我正在重构一个项目,但发现了困难。
目标是从基于ServiceType
的代码中删除一些切换用例(请参阅代码中的(。
某些上下文
ServiceA
、ServiceB
等都是描述不同服务的非常相似的类。我想:
- 让它们实现一个接口(比如
IService
( - 制作一个返回正确混凝土的工厂(
ServiceXX : IService
(
这样最终我将能够减少切换案例的数量。
这里有一个开关,我想删除:
foreach (Service s in PartnerServices)
{
int min = 0;
int max = 0;
switch (s.Type)
{
case "ServiceA":
min = ServiceA.GetMinPrice();
max = ServiceA.GetMaxPrice();
break;
case "ServiceB":
min = ServiceB.GetMinPrice();
max = ServiceB.GetMaxPrice();
break;
case "ServiceC":
min = ServiceC.GetMinPrice();
max = ServiceC.GetMaxPrice();
break;
case "ServiceD":
min = ServiceD.GetMinPrice(StateID);
max = ServiceD.GetMaxPrice(StateID);
break;
case "ServiceE":
min = ServiceE.GetMinPrice(StateID, CustomerID);
max = ServiceE.GetMaxPrice(StateID, CustomerID);
break;
}
...
}
我面临的问题是,大多数GetMinPrice
和GetMaxPrice
实现需要0个参数,而少数实现需要参数。
这是因为一些服务需要外部信息来计算价格(例如ServiceE
,需要知道StateID
和CustomerID
,因为可以为这两个密钥定制价格(。
因此,尽管这些类属于相同的"类";根";方法签名不同。
这通常是如何管理的?你有什么建议吗?
请注意,我不能将这些参数作为相关服务类的属性插入,因为这些是外部信息,不属于那里。
事先非常感谢。
我可能有一个想法,让我更接近解决方案。。。如果我创建一个新的类,它将包含计算价格所需的所有潜在选项,然后将其传递给方法,该怎么办?
这里是解释我的意思的最终代码示例:
public class PriceCalculationOptions
{
public int StateID { get; set; }
public int CustomerID { get; set; }
}
public interface IService
{
int GetMinPrice(PriceCalculationOptions options);
int GetMaxPrice(PriceCalculationOptions options);
}
public class ServiceA/B/C/D/E : IService
{
public int GetMinPrice(PriceCalculationOptions options)
{
//custom implementation using options
}
public int GetMaxPrice(PriceCalculationOptions options)
{
//custom implementation using options
}
}
public class ServiceFactory
{
public static IService CreateService(string ServiceType)
{
switch (ServiceType)
{
case "ServiceA":
return new ServiceA();
break;
case "ServiceB":
return new ServiceB();
break;
...
}
}
}
因此,包含切换情况的初始foreach变为:
foreach (Service s in PartnerServices)
{
int min = 0;
int max = 0;
IService service = ServiceFactory.CreateService(s.Type);
PriceCalculationOptions priceCalculationOptions = new PriceCalculationOptions()
{
StateID=1,
CustomerID = 20
};
min = service.GetMinPrice(priceCalculationOptions);
max = service.GetMaxPrice(priceCalculationOptions);
...
}
你们觉得怎么样?你认为有什么不利之处吗?对我来说,这似乎可行!