设计模式总结03–行为型模式

1 模板方法

1.1 设计意图

定义算法骨架,将某些特定算法延迟到子类实现。父类控制行为、子类控制过程细节。

1.2 解决要点

将代码公共不变的部分抽离出来,将变化的部分让子类去扩展;实现框架一样的反向控制,开放可扩展的细节给用户。

1.3 优缺点

优点

封装不可变和开放可变、提取公共代码便于维护

缺点

  • 设计原则:
  • 子类膨胀:每一个不同实现都有一个不同子类,造成类膨胀。
  • 设计水平:
  • 性能方面:
  • 代码可读:
  • 场景局限:

2 策略模式

2.1 设计意图

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

2.2 解决要点

解决算法的动态选择问题。在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

2.3 优缺点

优点

可自由切换、避免if…else般的多重判断、扩展性好

缺点

  • 设计原则:用户需要感知策略类、至少是名词语义的感知。
  • 子类膨胀:策略算法类会增多。
  • 设计水平:
  • 性能方面:
  • 代码可读:
  • 场景局限:

3 责任链模式

3.1 设计意图

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

3.2 解决要点

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可。客户无需关系请求处理的细节,每个处理者也无需关系责任链的整个处理全过程,弱化问题复杂度。

3.3 优缺点

优点

解耦了请求发送者和接收者、接收者不知链而简化问题、可动态添加处理环节、灵活度高、

缺点

  • 设计原则:
  • 子类膨胀:如果处理过程很多,太细化也会造成处理类的过多
  • 设计水平:
  • 性能方面:链条太长、影响性能。
  • 代码可读:
  • 场景局限:请求不一定被处理、容易造成环形依赖

4 观察者模式

4.1 设计意图

定义对象间的一种一对多的依赖关系,当该对象的状态发生改变时,依赖于它的多个对象都得到通知并被自动更新。

4.2 解决要点

解耦对象自身状态和状态改变后多个对象的处理、且多个对象可能是未知的。

4.3 优缺点

优点

观察者和被观察者是松耦合、将一个对象与多个对象协作起来。

缺点

  • 设计原则:
  • 子类膨胀:如果处理过程很多,太细化也会造成处理类的过多
  • 设计水平:
  • 性能方面:观察者太多、会影响性能
  • 代码可读:
  • 场景局限:如果观察者调用被观察者可能触发循环调用、观察者不知道被观察者内部的状态变化过程

5 中介者模式

5.1 设计意图

中介者负责协调各个对象调用关系,隔离了各个对象的直接调用。

5.2 解决要点

解决对象直接引用导致类结构臃肿和复杂的网状关系。

5.3 优缺点

优点

隔离了各个对象的关系、符合最少知道原则、将多对多的网状关系简化为一对多的星型关系。

缺点

  • 设计原则:
  • 子类膨胀:中介者类可能变得臃肿
  • 设计水平:
  • 性能方面:
  • 代码可读:
  • 场景局限:容易造成环形调用

6 状态模式

6.1 设计意图

允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

6.2 解决要点

解决对象行为与其状态息息相关、状态改变则行为改变。

6.3 优缺点

优点

封装状态转换规则、每个状态类处理特定的状态符合单一职责、每个状态类可执行切换到下一状态动作,所以避免了if…else般的臃肿、可以让多个对象共享一套状态机而减少系统开销。

缺点

  • 设计原则:当新增一个状态环节,会涉及到对原有状态转换过程的修改,不符合开闭原则
  • 子类膨胀:将对象状态剥离出来必然会增加系统类和对象个数
  • 设计水平:将对象的状态抽象出来本身就比较复杂、极其考验抽象水平
  • 性能方面:
  • 代码可读:
  • 场景局限:

7 命令模式

7.1 设计意图

将不同请求封装成一个个命令对象,由用户可以选择不同的请求进行投递、让请求处理者不用关心命令的具体类型。

7.2 解决要点

解耦行为请求者、行为实现者、行为执行者三者之间的关系。使得程序更加的灵活可控。

7.3 优缺点

优点

降低系统耦合度和复杂度、容易扩展新的命令

缺点

  • 设计原则:
  • 子类膨胀:造成命令类的膨胀
  • 设计水平:
  • 性能方面:
  • 代码可读:
  • 场景局限:

8 迭代器模式

8.1 设计意图

在不暴露一个聚合对象内部细节情况下,提供一种机制去遍历该对象的内部数据。

8.2 解决要点

将数据遍历和对象本身独立,提供不同的方式去遍历对象内部数据。

8.3 优缺点

优点

支持多样式遍历对象、迭代过程不暴露对象内部细节、支持多个迭代而互不干扰、解耦了迭代器与聚合类,使之相互独立

缺点

  • 设计原则:
  • 子类膨胀:每个类都需要提供迭代类,容易造成类膨胀
  • 设计水平:
  • 性能方面:
  • 代码可读:
  • 场景局限:

9 访问者模式

9.1 设计意图

主要将数据结构与数据操作分离。

9.2 解决要点

解决稳定的数据结构和易变的操作耦合问题。

9.3 优缺点

优点

各个访问者独立、符合单一职责

缺点

  • 设计原则:每个具体被访问的元素需要对访问者知晓,违反最小知道和依赖倒置;新增元素、访问者接口需要新加方法;
  • 子类膨胀:
  • 设计水平:
  • 性能方面:如果对象元素众多,遍历影响性能
  • 代码可读:
  • 场景局限:每个被访问者需要实现accept接口,对现有类的扩展不方便。

10 备忘录模式

10.1 设计意图

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

10.2 解决要点

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

10.3 优缺点

优点

方便状态回滚、用户不需要关心状态保存细节

缺点

  • 设计原则:
  • 子类膨胀:
  • 设计水平:如果对象需要备份的状态较多,抽象内部状态是个技术活。
  • 性能方面:备份必然浪费资源。
  • 代码可读:
  • 场景局限:

11 解释器模式

11.1 设计意图

给定语言和文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

11.2 解决要点

对于一些固定文法构建一个解释句子的解释器。

10.3 优缺点

优点

表达式增加则新扩展一个解释器子类即可、扩展性好、灵活性高

缺点

  • 设计原则:
  • 子类膨胀:会形成解释器类的膨胀
  • 设计水平:对抽象设计水平要求高
  • 性能方面:
  • 代码可读:
  • 场景局限:可利用场景较少

猜你喜欢

转载自blog.csdn.net/fs3296/article/details/108663703
今日推荐