设计模式笔记

导语
每隔一段时间,就会学习一次设计模式,每次都会有不一样的领悟

一、目标

代码复用,应对变化

二、方法

隔离变化,各司其职
找出稳定部分和变化部分,进行分离,使它们功能独立

三、原则

  • 依赖倒置:变化(实现细节)依赖稳定(抽象)
  • 开闭原则:开放扩展,关闭更改
  • 单一职责:一个类仅有单一功能
  • 替换原则:子类必须能替换基类,实现复用的基石
  • 接口隔离:接口小而完备,不依赖不需要的方法
  • 组合优先:组合优先继承,继承破坏了封闭性,耦合度高
  • 封装变化:松耦合
  • 面向接口编程:减少依赖

四、分类

创建型模式(1)

不使用new,隐藏创建逻辑,使用另外的对象来灵活创建目标对象

对象创建

  • 工厂模式:创建一系列复杂对象
  • 抽象工厂模式:构建工厂的工厂
  • 原型模式:通过对象创建对象,本质是对对象的深拷贝
  • 构建者模式:多个简单对象一步一步构造一个复杂对象,与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。比如套餐构建器,不同的构建器可以构建不同的套餐,每个套餐中有主食、汤和饮料,但是主食、汤和饮料的种类都是不同的。

对象性能

  • 单例模式:一个类仅有一个实例,并提供一个访问它的全局访问点

结构型模式(2)

单一职责

  • 装饰器模式:动态(组合)地给一个对象增加额外的功能,避免过度继承,导致子类数量膨胀。如果一个类的一个字段的类型,和这个类的父类是同一个类型,可以高度怀疑是装饰器模式。
  • 桥接模式:把一个类不同方向的功能进行抽离成两个类,并用组合模式组合起来。类似于多继承,但是是比多继承更好的解决方法。也就是说多继承是不是可以考虑用桥接模式来实现。

接口隔离

  • 外观模式:使得客户端不与系统耦合,外观类与系统耦合。隐藏系统复杂性。
  • 适配器模式:将一个接口包装成另一个接口,适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
  • 代理模式:一个类代表另一个类的功能,解决在直接访问对象时带来的问题。

数据结构

  • 组合模式:一般用于树形结构的处理,使得树节点和叶子节点可以对外提供统一的处理方法。外部无需知道内部数据结构。

对象性能

  • 享元模式:一些重型对象可能会拥有很多的字段,但是有一些字段是固定的。如果系统中存在大量这类对象会增加系统负担。因此可以把固定字段抽取出来变成享元对象,存储在享元对象管理器的缓存中。然后这些重型对象通过享元ID获取这些字段。举例,

行为型模式(3)

这些设计模式特别关注对象之间的通信。

组件协作

  • 模板模式:定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。不要调用我,让我来调用子类中的函数。
  • 策略模式:封装算法,使得算法可以拓展,并且运行时可切换不同算法
  • 观察者模式:当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

行为变化

  • 命令模式:请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
  • 访问者模式:使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。

接口隔离

  • 中介者模式:提供了一个中介类,该类通常处理不同类之间的通信。直播间主播和粉丝沟通,主播只需要发送信息给房间类,房间类显示信息即可,房间类就是中介,主播和粉丝解耦。

状态变化

  • 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。由备忘录管理器保存和恢复该对象的状态。
  • 状态模式:创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象

数据结构

  • 迭代器模式:访问一个集合内部的元素,而不暴露其数据结构。对于不同集合可以提供统一的接口。从而隔离数据结构和算法。对于C++而言,这样面向对象的设计模式已经过时,因为基于模板的迭代器性能要优于基于对象的方式,原因是运行时多态需调用,需要查询虚函数表。但是对于其他没有编译时多态的语言依然有用。
  • 责任链模式:多个handle组成一个链表,客户端发起的请求沿着链表传递,直到完成处理。解耦请求和处理器,使得handle可以扩展,处理链也可以进行不同组合。

领域问题

  • 解释器模式:一些固定文法构建一个解释句子的解释器

注意事项

无特殊说明时依赖指的是编译时依赖,也就是该类编译时,依赖的类必须存在

基类中必须声明虚析构函数,否则子类的析构函数不会被调用

接口在C++中用抽象基类来表示

C++不推荐多继承,但是可以有一个主继承,其他都是接口

------------- 感谢您的阅读-------------
作者dreamingpoet
有问题请发邮箱 Dreamingoet@126.com
您的鼓励将成为创作者的动力