前言
本博客仅做学习笔记,如有侵权,联系后即刻更改
科普:
策略模式(Strategy Pattern)
定义
定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户变化
- 又称为政策(Policy)模式
- 每一个封装算法的类称之为策略(Strategy)类
- 策略模式提供了一种可插入式(Pluggable)算法的实现方案
包含角色- Context(环境类)
- Strategy(抽象策略类)
- ConcreteStrategy(具体策略类)
模式分析
优点
- 提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为
- 提供了管理相关的算法族的办法
- 提供了一种可以替换继承关系的办法可以避免多重条件选择语句
- 提供了一种算法的复用机制,不同的环境类可以方便地复用策略类
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
- 将造成系统产生很多具体策略类
- 无法同时在客户端使用多个策略类
适用环境
- 一个系统需要动态地在几种算法中选择一种
- 避免使用难以维护的多重条件选择语句
- 不希望客户端知道复杂的、与算法相关的数据结构,提高算法的保密性与安全性
观察者模式(Observer Pattern)
定义
观察者模式:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新
- 别名
发布-订阅(Publish/Subscribe)模式
模型-视图(Model/View)模式
源-监听器(Source/Listener)模式
从属者(Dependents)模式
包含的角色
- Subject (目标)
- ConcreteSubject(具体目标)
- Observer(观察者)
- ConcreteObserver(具体观察者)
特殊场景
- 有时候在具体观察者类ConcreteObserver中需要使用到具体目标类ConcreteSubject中的状态(属性),会存在关联或依赖关系
- 如果在具体层之间具有关联关系,系统的扩展性将受到一定的影响
增加新的具体目标类有时候需要修改原有观察者的代码,在一定程度上违背了开闭原则,但是如果原有观察者类无须关联新增的具体目标,则系统扩展性不受影响
模式分析
优点
- 可以实现表示层和数据逻辑层的分离
- 在观察目标和观察者之间建立一个抽象的耦合
- 支持广播通信,简化了一对多系统设计的难度
- 符合开闭原则,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便
缺点
- 将所有的观察者都通知到会花费很多时间
- 如果存在循环依赖时可能导致系统崩溃
- 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化
适用环境
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用
- 一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少对象将发生改变,也不知道这些对象是谁
- 需要在系统中创建一个触发链
模板方法模式(Template Method Pattern)
定义
定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类不改变一个算法的结构即可重定义该算法的某些特定步骤
- 类行为型模式
- 是一种基于继承的代码复用技术
- 将一些复杂流程的实现步骤封装在一系列基本方法中
- 在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序
而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果
包含角色
- AbstractClass(抽象类)
- ConcreteClass(具体子类)
模式实现
- 模板方法(Template Method)
- 基本方法(Primitive Method)
- 抽象方法(Abstract Method)
- 具体方法(Concrete Method)
- 钩子方法(Hook Method)
模式分析
优点
- 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序
- 提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为
- 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行
- 更换和增加新的子类很方便,符合单一职责原则和开闭原则
缺点
- 需要为每一个基本方法的不同实现提供一个子类
如果父类中可变的基本方法太多,将会导致类的个数增加,系统会更加庞大,设计也更加抽象(可结合桥接模式)适用环境
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现
- 各子类中公共的行为应被提取出来,并集中到一个公共父类中,以避免代码重复
- 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制
总结
小小励志
有些事你现在不做,一辈子都不会做了。
如果你想做一件事,全世界都会为你让路。
《搭车去柏林》