我正在尝试重构代码。目前,对于类似的功能,我有不同的方法名称,如下所示。
public interface IReminderService
{
Task GenerateInviteReminders(string executedBy);
Task GenerateBookingReminders(string executedBy);
}
但是要使用类似下面的内容。但不确定如何在切换情况下传递参数来设置策略。使用IOC注入接口。或者,请让我知道重构代码的正确方法。
public interface IReminderStrategy
{
Task GenerateReminders(string executedBy);
}
public class StrategyA : IReminderStrategy
{
public StrategyA(IInterfaceA a, IInterface b)
{}
}
public class StrategyB : IReminderStrategy
{
public StrategyB(IInterfaceA a, IInterface b)
{}
}
public class ExampleService {
private readonly IInterfaceA _a;
private readonly IInterfaceB _b;
public ExampleService(
IInterfaceA a,
IInterfaceB b
) {}
switch case(string messageType)
{
IReminderStrategy strategy;
case "A":
strategy = new StrategyA(?????)
break;
case "B":
strategy = new StrategyB(?????)
break;
}
}
答案 0 :(得分:0)
您的上下文类(ExampleService
)不应意识到特定行为(策略)有不同的实现。而不是由上下文类负责实例化策略,而是应将策略作为其依赖项传递。这样,您就可以实现松散耦合,因为实例化可能取决于上下文类范围之外的许多因素,并且可能也相当复杂。它还允许您将来添加更多策略,而无需修改ExampleService
。
public class ExampleService
{
private readonly IReminderStrategy strategy;
public ExampleService(IReminderStrategy strategy)
{
this.strategy = strategy;
}
}
应将提供哪种策略类型的决定委托给IoC容器。像
if (useA)
{
// bind IReminderStrategy to StrategyA
}
else
{
// bind IReminderStrategy to StrategyB
}
答案 1 :(得分:0)
您将需要一个以上的类(ConcreteClass)来实现接口方法,并将您的对象(StrategyA或StrategyB)作为参数传递给新的此类对象(ConcreteClass),然后在需要时调用该方法。
switch (message)
{
case "A":
concreteObject.SampleMethod(new StrategyA());
break;
case "B":
concreteObject.SampleMethod(new StrategyB());
break;
default:
break;
}
....
concreteObject.Execute(inputMessage)
class Concrete
{
IReminderStrategy _reminderStrategy;
public void SampleMethod(IReminderStrategy reminderStrategy)
{
_reminderStrategy = reminderStrategy
}
public void Execute(string message)
{
_reminderStrategy.GenerateReminders(message);
}
}
答案 2 :(得分:0)
首先,我经常使用策略或模板方法模式,因为您利用了动态调度或多态性的优势,并且您大多摆脱了if-else块。我的意思是您将逻辑放在一个地方,所以要防止if-els分散到多个地方。为了进一步研究,您可以将它们与函数式编程中的高阶函数进行比较。
public interface IReminderStrategy
{
Task GenerateReminders(string executedBy);
}
public class InviteReminder : IReminderStrategy
{
private IInterfaceA _a;
private IInterfaceB _b;
public InviteReminder(IInterfaceA a, IInterface b){
_a = a; _b = b;
}
public Task GenerateReminders(String executedBy) {
_a.doSomething;
_b.doSomething;
//do invite reminder specific actions here.
}
}
public class BookingReminder : IReminderStrategy
{
private IInterfaceA _a;
private IInterfaceB _b;
public BookingReminder(IInterfaceA a, IInterface b){
_a = a; _b = b;
}
public Task GenerateReminders(String executedBy) {
_a.doSomething;
_b.doSomething;
//do booking reminder specific actions here.
}
}
public static class ReminderFactory {
//If there will be no DI then remove injects and static and instantiate the object with dependencies.
@Inject
private readonly IInterfaceA _a;
@Inject
private readonly IInterfaceB _b;
/* made the class as static so as you said we will be using a DI container.
public ReminderFactory(IInterfaceA a, IInterfaceB b) {
_a = a;
_b = b;
}
*/
public IReminderStrategy getReminder(String messageType) {
switch case(messageType)
{
IReminderStrategy strategy;
case "invite":
strategy = new InviteReminder(_a, _b)
break;
case "book":
strategy = new BookingReminder(_a, _b)
break;
}
}
}
1)实例化并通过策略(出于教学目的,即为了清楚说明)。
然后在客户端中某个位置之前的一个步骤中
IReminderStrategy reminderStrategy = ReminderFactory.getReminder("invite");
shopService.shop(reminderStrategy);
最终在客户端中:
public class ShopService {
public void shop(IReminderStrategy reminderStrategy) {
reminderStrategy.GenerateReminders("taha");
}
}
2)或直接:
public class ShopService {
public void shop() {
//...
IReminderStrategy reminderStrategy = ReminderFactory.getReminder("invite");
reminderStrategy.GenerateReminders("taha");
//...
}
}
并且可能在其他服务中:
public class TravelService myService() {
public void travel() {
//travel preparation
IReminderStrategy reminderStrategy = ReminderFactory.getReminder("book");
reminderStrategy.GenerateReminders("admin");
//other travel things or maybe do something with the result.;
}
}