策略模式——java设计模式(二十三)

简介

策略模式(Strategy Pattern):定义一系列算法并将每一个算法封装起来,让他们可以互相替换,独立于客户而变化。

  • 用于算法的自由切换和扩展,需要使用策略模式实现算法的定义和使用分离,从而替换传统的硬编码方式。又称政策模式
  • 硬编码,增加算法需要修改源码,并且代码复杂,维护困难。
    1. 算法集中在一个类中,该类提供多个方法,每个方法对应一个接口。
    2. 算法集中在一个方法中,使用条件语句选择。

结构和实现

  • 角色包括:
    • 环境类:使用算法的角色,维护抽象策略类的引用。
    • 抽象策略类:声明抽象算法,方便替换算法。
    • 具体策略类:实现抽象策略类。
  • 策略模式结构。
    180515.strategy.png

实例

  • 开发售票系统,为不同类型的用户提供不同的打折方式。
    180515.ticket.png

优缺点和适用范围

  • 优点:
    • 完美符合开闭原则。修改或者增加新的算法无需修改源码。
    • 管理算法族。通过继承结构管理,公用算法可放入抽象策略类。
    • 关联替换继承。无需使用继承方法替换算法实现,符合单一职责原则。
    • 避免硬编码。多重的逻辑判断导致代码难以维护。
    • 复用算法。算法被提取在一个类中,可以被其他环境复用。
  • 缺点:
    • 客户端需要了解所有算法。包括算法之间的区别。
    • 具体策略类多。任何变化都需要导致增加具体策略类。
    • 单独使用策略。客户端每次只能使用一个策略,不能使用一部分之后使用另一个策略的一部分。
  • 适用范围:
    • 需要动态的在几个算法中选择一个使用。
    • 对象行为多,使用多重条件语句复杂。
    • 需要封装算法,提高保密性和安全性。

jdk中的应用

  • ThreadPoolExecutor可以设置不同的拒绝策略。ThreadPoolExecutor是环境类,RejectedExecutionHandler是抽象策略类,各种拒绝策略是具体策略类。
    180518.ThreadPoolExecutor2.png
public class ThreadPoolExecutor extends AbstractExecutorService {
    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
        if (handler == null)
            throw new NullPointerException();
        this.handler = handler;
    }
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40369829/article/details/80370626