c# - C#正确使用策略模式的方法
问题描述
我正在尝试重构我的代码。目前,对于类似的功能,我有不同的方法名称,如下所示。
public interface IReminderService
{
Task GenerateInviteReminders(string executedBy);
Task GenerateBookingReminders(string executedBy);
}
但想使用类似下面的东西。但不确定如何在 switch case 中传递参数来设置策略。接口是使用 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;
}
}
解决方案
首先,我经常使用策略或模板方法模式,因为您利用了动态调度或多态性,并且您大多摆脱了 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");
}
}
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.;
}
}
推荐阅读
- node.js - 从图像文本nodejs中去除噪音
- spring - 无法从卡夫卡读取
- r - R:导入大量 CSV 并对其进行操作(CSV 不一致)
- c++ - 一个类可以在 C++ 中在运行时添加朋友类吗?
- prestashop - Prestashop 1.6., TM HTML Content at TopRight
- c# - 如何从已覆盖的子类对象中调用超类方法?
- varnish - 从 Varnish 缓存中排除 Safari 浏览器
- blockchain - 在 Stellar Network 上用 100 美元兑换欧元需要多少钱
- sass - 如何在 Sass 中连接变量?
- php - 链接到从多维数组显示的完整图像