C#正确使用战略模式

C#正确使用战略模式,c#,design-patterns,C#,Design Patterns,我正在尝试重构我的代码。目前,对于类似的函数性,我有不同的方法名,如下所示 public interface IReminderService { Task GenerateInviteReminders(string executedBy); Task GenerateBookingReminders(string executedBy); } 但是我想用下面的方法。但不知道如何在切换情况下传递参数来设置策略。使用IOC注入接口。或者请告诉我重构代码的正确方法 public

我正在尝试重构我的代码。目前,对于类似的函数性,我有不同的方法名,如下所示

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;          
    }
}
您的上下文类(
ExampleService
)不应该知道特定行为(策略)有不同的实现。您应该将策略作为其依赖项传递,而不是由上下文类负责实例化策略。这样可以实现松散耦合,因为实例化可能依赖于上下文类范围之外的许多因素,而且可能相当复杂。它还允许您将来添加更多策略,而无需修改
ExampleService

公共类示例服务
{
私有只读iMinderStrategy策略;
公共示例服务(IReminderStrategy策略)
{
这个。策略=策略;
}
}
关于提供哪种策略类型的决定应委托给IoC容器。差不多

if(useA)
{
//将IReminderStrategy与StrategyA绑定
}
其他的
{
//将IReminderStrategy绑定到策略B
} 

在这里,您需要另外一个类(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);
    }
}

首先,我经常使用策略或模板方法模式,因为您利用了动态分派或多态性,并且基本上摆脱了if-else块。我的意思是,你把逻辑放在一个地方,这样就可以防止if-Else分散到多个地方。为了进一步研究,您可以将它们与函数编程中的高阶函数进行比较

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");
   }
}
最后,在客户端:

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.;
   }
}

您需要首先从策略A和B中的接口实现该方法。我认为您需要将“A”和“B”作为参数传递给IReminderStrategy接口方法。你应该看看这篇文章