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接口方法。你应该看看这篇文章