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

策略模式是一种行为设计模式,定义了很多可封装的算法,不同算法可以在运行时相互替换。特别适合在大量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、增加复杂度:简单场景使用可能显得过度设计

注:和状态模式对比

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

特性 策略模式 状态模式
主要目的 封装算法,让客户端选择 封装状态,管理状态转换
切换控制 由客户端主动控制 由上下文或状态对象自动控制
状态感知 策略之间通常不知道彼此 状态之间知道并触发转换
典型应用 可互换的算法实现 状态驱动的行为变化
设计重点 算法的可替换性 状态转换的逻辑封装
相关推荐
wwdoffice01108 小时前
304和316不锈钢有什么区别?哪个更好?
设计模式
网小鱼的学习笔记9 小时前
创建型设计模式(工厂、builder、原型、单例)
java·后端·设计模式
逆境不可逃9 小时前
【从零入门23种设计模式21】行为型之空对象模式
java·开发语言·数据库·算法·设计模式·职场和发展
蜜獾云1 天前
设计模式之命令模式:给其他模块下达命令
设计模式·命令模式
小湘西1 天前
拓扑排序(Topological Sort)
python·设计模式
蜜獾云1 天前
设计模式之观察者模式:监听目标对象的状态改变
观察者模式·设计模式·rxjava
知无不研1 天前
中介者模式
c++·设计模式·中介者模式
badhope1 天前
OpenClaw卸载命令全解析
java·linux·人工智能·python·sql·数据挖掘·策略模式
bmseven1 天前
大白话讲解23种设计模式简介
设计模式
蜜獾云1 天前
设计模式之代理模式:本地接口代理远程接口的调用
设计模式·系统安全·代理模式