行为型设计模式——策略模式

策略模式是一种行为设计模式,定义了很多可封装的算法,不同算法可以在运行时相互替换。特别适合在大量if-else分支判断的场景。

特点

1、封装变化:将经常变化的算法部分独立出来

2、面向接口编程:定义算法接口,不同实现类提供具体算法

3、组合优于继承:通过组合方式使用策略,而不是通过继承

结构

策略模式结构包括三个部分:

|----------------------------|--------------------------|
| Context(环境类) | 持有一个策略对象的引用,通过策略接口调用具体策略 |
| Strategy(策略接口) | 定义所有支持的算法的公共接口 |
| ConcreteStrategy(具体策略) | 实现策略接口的具体算法类 |

UML图如下:

代码示例

策略+工厂模式(使用工厂模式管理策略的创建) 实现消息发送渠道

java 复制代码
import java.util.HashMap;
import java.util.Map;

// 策略工厂
class NotificationStrategyFactory {
    private static final Map<String, NotificationStrategy> strategies = new HashMap<>();
    
    static {
        strategies.put("EMAIL", new EmailNotification());
        strategies.put("SMS", new SmsNotification());
        strategies.put("PUSH", new PushNotification());
    }
    
    public static NotificationStrategy getStrategy(String type) {
        NotificationStrategy strategy = strategies.get(type.toUpperCase());
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的通知类型: " + type);
        }
        return strategy;
    }
    
    public static void registerStrategy(String type, NotificationStrategy strategy) {
        strategies.put(type.toUpperCase(), strategy);
    }
}

// 策略接口
interface NotificationStrategy {
    void send(String message, String recipient);
}

// 具体策略类
class EmailNotification implements NotificationStrategy {
    @Override
    public void send(String message, String recipient) {
        System.out.printf("发送邮件到 %s: %s%n", recipient, message);
    }
}

class SmsNotification implements NotificationStrategy {
    @Override
    public void send(String message, String recipient) {
        System.out.printf("发送短信到 %s: %s%n", recipient, message);
    }
}

class PushNotification implements NotificationStrategy {
    @Override
    public void send(String message, String recipient) {
        System.out.printf("发送推送通知到设备 %s: %s%n", recipient, message);
    }
}

// 上下文类
class NotificationService {
    public void sendNotification(String type, String message, String recipient) {
        NotificationStrategy strategy = NotificationStrategyFactory.getStrategy(type);
        strategy.send(message, recipient);
    }
}

// 使用示例
public class StrategyWithFactoryDemo {
    public static void main(String[] args) {
        NotificationService service = new NotificationService();
        
        // 通过工厂获取策略
        service.sendNotification("EMAIL", "您的订单已发货", "user@example.com");
        service.sendNotification("SMS", "验证码: 123456", "13800138000");
        service.sendNotification("PUSH", "您有一条新消息", "device_token");
        
        // 动态注册新策略
        NotificationStrategyFactory.registerStrategy("WECHAT", 
            (message, recipient) -> System.out.println("微信通知: " + message));
        
        service.sendNotification("WECHAT", "公众号更新", "wechat_user");
    }
}

适用场景

  1. 多种算法变体:系统需要在多种算法中选择一种

  2. 避免多重条件语句:减少复杂的if-else或switch-case语句

  3. 算法需要独立变化:算法的使用和实现需要解耦

  4. 客户端不需要知道具体实现:客户端只关心接口,不关心具体算法

优点

1、开闭原则 :无需修改上下文即可引入新策略;2、消除条件语句 :避免使用多重条件转移语句;3、提高可复用性 :算法可以独立于上下文重复使用;4、提高灵活性 :运行时可以动态切换算法;5**、职责分离**:算法实现和使用分离

缺点

1、策略类数量增加 :每个策略都需要一个单独的类;2、客户端必须了解策略 :客户端需要知道有哪些策略可用;3、通信开销 :策略和上下文之间可能需要传递数据;4、增加复杂度:简单场景使用可能显得过度设计

注:和状态模式对比

策略模式改变对象行为,状态模式改变对象状态。策略模式处理可选的算法实现,状态模式管理核心状态转换。

特性 策略模式 状态模式
主要目的 封装算法,让客户端选择 封装状态,管理状态转换
切换控制 由客户端主动控制 由上下文或状态对象自动控制
状态感知 策略之间通常不知道彼此 状态之间知道并触发转换
典型应用 可互换的算法实现 状态驱动的行为变化
设计重点 算法的可替换性 状态转换的逻辑封装
相关推荐
咖啡八杯16 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
大数据新鸟18 小时前
设计模式四大基本原则
设计模式
南一Nanyi1 天前
依赖注入和控制反转
前端·设计模式·nestjs
tiankong12131 天前
如何拓展多态下的子类
设计模式·c#
jctech1 天前
让「小程序」跑起真正的原生代码:ComboNative 多进程原生小程序运行时 · Alpha 首发
android·设计模式·架构
Kel2 天前
Node.js 单线程高并发:从内核中断到 JS 回调的完整技术栈
设计模式·架构·node.js
解局易否结局3 天前
ArkUI MVI 架构实战:单向数据流设计模式在 HarmonyOS NEXT 中的深度实践
华为·设计模式·架构·harmonyos
解局易否结局3 天前
ArkTS 设计模式与架构进阶:构建可维护的 HarmonyOS 应用
华为·设计模式·架构·harmonyos
happyness443 天前
AI编程与设计模式
设计模式·ai编程
就是小王同学啊3 天前
Spring小技巧之设计模式
sql·spring·设计模式