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

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

注:和状态模式对比

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

特性 策略模式 状态模式
主要目的 封装算法,让客户端选择 封装状态,管理状态转换
切换控制 由客户端主动控制 由上下文或状态对象自动控制
状态感知 策略之间通常不知道彼此 状态之间知道并触发转换
典型应用 可互换的算法实现 状态驱动的行为变化
设计重点 算法的可替换性 状态转换的逻辑封装
相关推荐
故事还在继续吗11 分钟前
设计模式完全指南
设计模式
薛定谔的悦1 小时前
共享数据总线(DPR)设计模式——嵌入式系统的“内存数据库”
jvm·数据库·设计模式
A-Jie-Y3 小时前
JAVA设计模式-建造者模式
java·设计模式
无敌秋4 小时前
# C++ 工厂方法模式实战指南
开发语言·c++·设计模式
a里啊里啊4 小时前
软考-软件评测师:知识点整理(七)——软件工程
设计模式·软件工程·软考·uml·结构化开发·软件评测师·软件模型
ximu_polaris5 小时前
设计模式(C++)-行为型模式-策略模式
c++·设计模式·策略模式
geovindu6 小时前
go: Observer Pattern
开发语言·观察者模式·设计模式·golang
z小天才b1 天前
Java 设计模式完全指南:从入门到精通
java·开发语言·设计模式
kyriewen111 天前
Next.js:让你的React应用从“裸奔”到“穿衣服”
开发语言·前端·javascript·react.js·设计模式·ecmascript
A-Jie-Y1 天前
JAVA设计模式-工厂方法模式
java·设计模式