设计模式总结

  • 特点
    • 对在不同的对象之间划分责任和算法的抽象化。不仅仅是关于类和对象的,并是关于他们之间的相互作用。类的行为模式使用继承关系在几个类之间分配行为。对象的行为模式则使用对象的聚合来分配行为。
    • 行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。这些模式刻画了在运行时难以跟踪的复杂的控制流。
  • 种类
    • 模板方法模式(Method Template)
      • 模板方法类图
      • 模板方法类图2
      • 针对某个算法分为多步且部分可变的情况。
      • 需要有一个抽象父类,其中有一个方法会调用各个子函数或抽象子函数,相当于确定了逻辑的顺序和骨架,只有部分逻辑可以在实现类中具体实现。
      • 对调用者来说,只关心抽象父类中的这个主函数,具体抽象子函数的实现是哪种,需要提前指定
      • 对调用者来说,怎么确定使用的是哪个子类?
        • 有时调用者中直接使用具体类也无所谓?至少被调用者的现有代码不需要修改,只需要增加
        • 也可以通过配置文件、环境变量等方式来指定特定字符串,用来判断使用哪个具体子类
      • 目的是在抽象父类中确定逻辑(各个子函数的调用顺序),然后子类中可以重写某些子函数实现定制
      • 不使用该设计模式时:比如在实现servlet处理逻辑时,实现者要把整个流程实现一遍,并且没有一个规范可以遵循,容易出错,比如搞错了逻辑顺序。
      • 使用该设计模式时:父类定了一个逻辑顺序,你只能在这个基础上改,否则使用者比如容器不认,并且提出了一部分通用逻辑。
      • 现实例子:写作文套模板
    • 命令模式(Command)
      • 命令模式类图
      • 每个命令是一个类,实现共同的命令接口,组合要操作的对象(如灯);然后调用者(如遥控器)类中组合包含各个命令,然后调用者提供对外接口,每个接口方法内再使用某个命令实现功能
      • 就是把命令封装成对象,使命令可以重复调用、撤销,降低了调用者和接受者的耦合,同时容易扩展出新的命令。
      • 它尝试以对象来代表实际行动。命令对象可以把行动(action) 及其参数封装起来,于是这些行动可以被重复使用、撤销、撤销后重做。
      • 不使用该设计模式时:直接使用类及其提供的各种命令,坏处是要改这个类,并且实现撤销、重做比较麻烦比较乱。
      • 使用该设计模式时:不用改这个类,只增加具体命令类,client就可以使用了,并且各个命令有各自的撤销、重做操作逻辑实现。
      • 现实例子:遥控(命令调用者,Invoker)、灯(接收者,Receiver)及等的各种命令
    • 中介者(调停)模式(Mediator)
      • 中介者模式类图
      • 和门面模式一样都是简化交互关系,但中介者模式通常处理的是众多内部类自身之间的交互、调用关系,内部类都会在构造函数中组合传入中介类
      • 不使用该设计模式时:众多内部类直接经常互相调用,都是多对多的关系,很混乱。
      • 使用该设计模式时:众多内部类之间的调用都通过中介者进行转发和协调,中介者去调用各个内部类。
      • 现实例子:装修公司的项目经理(协调多个项目多个工种)
    • 观察者模式(Observer)
      • 观察者模式类图
      • 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新。
      • 一个系统中必然由多个相互协作的类组成,很常见的问题就是维持状态的一致性或者说联动效果。观察者模式就是为了解决这种问题,处理“协作者”之间的一致性与联动问题。
      • 观察者模式的核心在于对于观察者的管理和维护,以及发送通知。
      • 观察者模式将发布者与订阅者进行解耦,不再是直接的方法调用,通过引入Observer角色,完成了发布者与具体订阅者之间的解耦,也是一种形式的“方法调用”的解耦
      • Subject中可以像C#的事件机制一样,有一个事件函数,执行/触发时会调用notify()函数
      • 设置模式在实现时,不一定要一模一样,有时不重要的部分可以自行决定,比如观察者模式中registerObserver()方法放在main函数中还是Observer的构造函数中(Subject作为参数传进来)都可以
      • 与中介者模式的对比
        • 用于一对多依赖场景中的解耦,通过引入Observer角色,将消息发布者与具体的订阅者进行解耦
        • 中介者模式是将系统内部多对多的复杂耦合关系,借助于中介者进行解耦,将网状结构,简化为星型结构,将多对多转换为一对多 。发起消息的Colleague同事类角色是被观察者,中介类Mediator是观察者,调用其他的同事类进行协作
        • 他们都能够实现消息发布者与接收者的解耦,消息发布者都不知道具体的消息接收者
        • 尽管观察者模式强调“一致性通信”,中介者模式强调“内部组件协作”,但是根本还是方法执行时,需要同步调用其他对象
        • 两个模式之间是一种类似的关系,在有些场景可替代转换。如果协作关系比较简单,可以实现为一对多的形式,使用观察者模式;如果协作关系更加复杂,那么就可以使用中介者模式
      • 实例:Java中已经定义的观察者模式Observer和Obeservable
    • 状态模式(state)
      • 状态模式类图
      • 状态模式类图2
      • 状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎改变了它的类。
        • 这里说的内部状态的改变,可能是其自身一步一步按特定顺序或事件自动进行下去的。在每一步的处理结束时都会去切换到下一状态
      • 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化(取代了if...else...)。
      • 避免了复杂的状态判断逻辑,避免了复杂的状态切换处理,尤其状态很多的时候
      • 类似状态机?
      • 每个state的处理函数中,完成本状态的任务后,需要让Context类切换到其他状态(所以状态类的构造函数中需要传入Context类),或者发送状态变化事件,或者对于后面说的死循环的做法也可以在外部改变Context中的状态
      • Context类或者说Engine类中,会设置一个初始状态,同时可以在其中定义所有的状态类型的各个状态,会有启动和停止方法
        • 一种做法是,启动后就会一步步、一个一个状态得跑下去,不需要人干涉,每个状态的动作最后会切换状态或结束任务
        • 还有一种可能的做法是,Context类在启动后,会开一个新的线程,里面有一个死循环,会不断的检查状态和执行状态其中的动作(利用多态,调用通用的抽象方法即可)。停止状态判断变量用于判断是否停止
        • 结束方法通常是修改停止状态判断变量,多用于会死循环一直运行时
      • 设计模式之状态模式
    • 策略模式(strategy)
      • 策略模式类图
      • 策略模式类图_飞行器
      • 和简单工厂模式有点像,都是根据type参数做不同的行为,只不过简单工厂是创建并返回不同的产品,而策略模式是在自身构造函数中创建不同的算法类并供自身使用(调用抽象算法类)。
      • 设计意图是,定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化。
    • 职责链模式(chain of responsibility)
    • 访问者模式(Visitor)
      • 最难理解的设计模式。。。。
      • 表示一个作用于某对象结构中的各元素的操作。它使在不改变各元素的 类的前提下可以定义作用于这些元素的新操作。
      • 分为访问者和元素两部分
        • 对于每一个元素,访问者接口类中都有(也就是每个访问者都有)对应个数的visit操作函数将其作为参数传入并使用其方法
        • 对于每一个访问者,元素接口类中都有(也就是每个元素都有)对应个数的accept操作函数将其作为参数传入并使用其方法
      • 访问者模式类图
    • 迭代器模式(iterator)
      • 迭代器模式类图
      • 能够将遍历序列的操作和序列底层相分离
      • 迭代器是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不需要知道该序列底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价小。因此,经常可以见到对迭代器有一些奇怪的限制;例如,java的Iterator只能单向移动
    • 解释器模式(interpreter)
      • 解释器模式类图
    • 备忘录模式(Memento)
      • 备忘录模式类图
      • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
      • 对象的某个瞬时状态,叫做快照(如同你去拍证件照,立等可取,快速的拍照,俗称快照)。每一个快照,通常叫做一个检查点。想要实现快照和撤销恢复机制,就必须将对象的状态保存起来。这就是备忘录模式的初衷。
      • 将对象的状态保存在外部,但是外部却仍旧不知道对象的属性细节
      • 备忘录模式与命令模式不是可替代关系,而是可以相互配合的好基友。命令模式记录操作历史,备忘录模式记录对象的状态,一起配合实现撤销的操作。
原文地址:https://www.cnblogs.com/wyp1988/p/10875093.html