基于策略模式实现事件双通知系统的合理性与优化咨询
问题1:是否为策略模式的正确用法?谁来决定策略选择?
你当前的用法不属于标准的策略模式实现。策略模式的核心目标是将策略选择逻辑和策略执行逻辑完全解耦,你现在把if/else判断硬写在Notification类的Send方法里,本质还是内部硬编码选策略,没有发挥策略模式的优势。
策略选择逻辑应该单独抽离到「策略工厂」模块实现,你可以额外定义一个INotificationStrategyFactory接口,专门负责根据订阅者属性返回对应的通知策略实例,改造后Notification类里就不需要再写if/else判断,直接调用工厂获取对应策略执行发送即可。
另外你当前的抽象设计有冗余:不需要定义EmailNotificationStartegy、SmsNotificationStartegy两个子接口,直接写具体的实现类实现公共的INotificationStrategy接口即可,同时注意拼写错误:Startegy应为Strategy。
问题2:是否需要INotification抽象?能不能直接在事件处理器写遍历逻辑?
非常需要保留INotification抽象,不要把遍历逻辑写在事件处理器里。
事件处理器的核心职责是处理事件触发后的业务逻辑,通知发送是独立的通用能力,如果把遍历、判断、发送的逻辑耦合到事件处理器里,后续其他业务场景需要发通知时,就会出现大量重复代码,也违反单一职责原则。
问题3:INotification的优势是什么?现有实现有什么问题?
INotification的核心优势有三点:
- 单一职责:把通知发送的全流程逻辑封装在独立层,上层业务不需要感知发送细节,只需要调用
Send方法即可; - 可测试性:单元测试时可以直接Mock
INotification的实现,不需要真实触发邮件、短信发送就能验证上层逻辑正确性; - 可复用性:所有需要发送通知的业务场景都可以复用这一套实现,不需要重复开发。
你现有实现的问题:
- 策略选择逻辑硬编码在
Send方法中,不符合开闭原则,新增通知策略必须修改Notification类; - 构造函数硬注入两个固定的策略实现,新增策略时必须修改构造函数传入新的策略实例,扩展性差;
- 定义了多余的子接口抽象,反而增加了不必要的维护成本。
问题4:新增策略是否必须修改Notification类?怎么避免修改?
你当前的实现新增策略确实必须修改Notification类,要避免修改可以通过「策略工厂+依赖注入」的方式改造:
- 定义策略工厂接口,封装策略选择逻辑:
public interface INotificationStrategyFactory { INotificationStrategy GetStrategy(Subscriber subscriber); }
- 工厂的实现类里维护策略匹配规则,比如邮箱非空返回邮件策略,否则返回短信策略,后续新增微信、钉钉等通知策略时,只需要加对应的策略实现类,然后在工厂里新增匹配规则即可;
Notification类只需要注入INotificationStrategyFactory,不需要再注入多个具体策略实例,Send方法里直接调用工厂获取对应策略执行发送即可,后续新增策略完全不需要修改Notification类本身,符合开闭原则。
内容的提问来源于stack exchange,提问作者Peter Pedigree
相关产品推荐
相关产品推荐

