我有以下情况:必须根据每个对象的特定属性将对象集合发送给不同的第三方(该属性定义为枚举)。我打算使用如下的Factory模式实现它。
这可以重构为使用依赖注入吗?
public class ServiceA: IThirdParty
{
public void Send(Ticket objectToBeSent)
{
// a call to the third party is made to send the ticket
}
}
public class ServiceB: IThirdParty
{
public void Send(Ticket objectToBeSent)
{
// a call to the third party is made to send the ticket
}
}
public interface IThirdParty
{
void Send(Ticket objectToBeSent);
}
public static class ThirdPartyFactory
{
public static void SendIncident(Ticket objectToBeSent)
{
IThirdParty thirdPartyService = GetThirdPartyService(objectToBeSent.ThirdPartyId);
thirdPartyService.Send(objectToBeSent);
}
private static IThirdParty GetThirdPartyService(ThirdParty thirdParty)
{
switch (thirdParty)
{
case ThirdParty.AAA:
return new ServiceA();
default:
return new ServiceB();
}
}
}
答案 0 :(得分:2)
是的,可以重构 - 将服务注入SendIncident
或其类。
答案 1 :(得分:1)
我认为你应该首先意识到SendIncident不应该是IThirdPartyFactory的一部分。工厂创造对象。 SendingIncidents不是那样的。
所以介绍一个负责发送票证的类:
public TicketSender
{
IThirdPartyFactory _factory
public void TicketSender(IThirdPartyFactory factory)
{
_factory = factory;
}
public void SendIncident(Ticket ObjectToBeSent)
{
var service = _factory.GetThirdPartyService(ObjectToBeSent.ThirdPartyId);
service.SendIncident(ObjectToBeSent);
}
}
使用以下工厂:
public class ThirdPartyFactory : IThirdPartyFactory
{
IThirdParty serviceA;
IThirdParty serviceB;
public ThirdPartyFactory(IThirdParty serviceA, IThirdParty serviceB)
{
_serviceA = serviceA;
_serviceB = serviceB;
}
public IThirdParty GetThirdPartyService(ThirdParty thirdParty)
{
switch (thirdParty)
{
case ThirdParty.AAA:
return serviceA;
default:
return serviceB;
}
}
}
如果您正在使用像Windsor这样的IOC容器,那么将为您生成大部分工厂,并且您只需定义接口和选择逻辑。
答案 2 :(得分:1)
首先,Marwijn是正确的,你应该有一个单独的TicketSender类,它接受IThirdPartyFactory依赖。
您可以创建一个新界面:
public interface IThirdPartyId
{
int Id { get; }
}
按照惯例,让所有IThirdParty实现都实现IThirdPartyId。然后你可以像Marwijn建议的那样将一系列IThirdParty注入你的ThirdPartyFactory。工厂可以将它们重新设置为IThirdPartyId以获取每个的Id,并使用它来匹配工厂方法上的Id参数。
这样可以将所有查找逻辑保留在工厂中,而不是在工厂和IoC配置之间进行拆分。
答案 3 :(得分:0)
为什么不呢?只需稍微调整ThirdPartyFactory
即可成为抽象工厂,不要使用静态。
public class ThirdPartyFactory : IThirdPartyFactory
{
public ThirdPartyFactory(IThirdParty serviceA, IThirdParty serviceB)
{
this.serviceA = serviceA;
this.serviceB = serviceB;
}
IThirdParty serviceA;
IThirdParty serviceB;
public void SendIncident(Ticket objectToBeSent)
{
IThirdParty thirdPartyService = GetThirdPartyService(objectToBeSent.ThirdPartyId);
thirdPartyService.SendIncident(objectToBeSent);
}
private IThirdParty GetThirdPartyService(ThirdParty thirdParty)
{
switch (thirdParty)
{
case ThirdParty.AAA:
return serviceA;
default:
return serviceB;
}
}
}
答案 4 :(得分:0)
据我所知,这个问题是关于运行时选择或几个候选策略之一的映射 - 在这种情况下,根据IThirdParty
枚举值选择正确的ThirdParty
实现。
至少有三种方法可以做到这一点,而且它们都不需要工厂:
我个人偏好是部分类型名称角色提示。