文章目录
自己理解的部分设计模式解析,如有错误感谢指出
简单工厂
工厂中通过不同的枚举,创建不同的产品类实例,所有产品类继承同一个的抽象产品基类
用户通过向同一个【工厂】传入不同的枚举参数获取相应的【产品实例】
工厂方法
工厂A创建产品A,工厂B创建产品B,工厂C创建产品C…
所有工厂类继承同一个抽象工厂基类,所有产品类继承同一个抽象产品基类
用户通过不同的【工厂】获取相应的【产品实例】
抽象工厂
工厂1创建产品A1、产品B1、产品C1,工厂2创建产品A2、产品B2、产品C2
所有工厂继承同一个基类,产品A系列继承同一个基类A,产品B系列继承同一个基类B,产品C系列继承同一个基类C
用户通过【工厂1】获取【产品1系列下的几个产品】,通过【工厂2】获取【产品2系列下的几个产品】,如【华为手机工厂】产出【华为手机屏幕、华为手机电池】,【小米手机工厂】产出【小米手机屏幕、小米手机电池】
单例模式
构造函数私有,创建静态类指针实例,外部通过公共静态成员函数获取该类指针实例
全局唯一实例,节省资源不用频繁创建释放,也可用来共享某些资源
在QT中也可让该类负责编写信号,让没有继承QObject的类也可发送信号
建造者模式
Director(导演)->Builder(建造者)->Protuct(要造出的产品)
ProtuctA有多个部分组成
BuilderA有n个函数分别创建ProtuctA的n个部分
ProtuctA有n个函数分别设置n个部分
【导演】通过【手机建造者】创建【框架】,【手机建造者】完成后给【手机产品】安装【框架】
【导演】通过【手机建造者】创建【主板】,【手机建造者】完成后给【手机产品】安装【主板】
【导演】通过【手机建造者】创建【电池】,【手机建造者】完成后给【手机产品】安装【电池】
【导演】通过【手机建造者】创建【屏幕】,【手机建造者】完成后给【手机产品】安装【屏幕】
【导演】通过【手机建造者】创建【系统】,【手机建造者】完成后给【手机产品】安装【系统】
【手机创建完成】
原型模式
类重写拷贝构造函数,添加成员函数Clone,在该函数中调用拷贝构造函数,新new了个实例返回
用户通过【Clone】接口获取一个与当前实例数据相同的新实例
适配器模式
需要同时用到类A和类B的功能,但是两个类不好作出修改
写一个第三方类C,该类将两个不相关的类A和B联系起来,此时类A和类B不需要作改动
如类C同时继承类A和类B,或者类C继承类A并创建变量B
用户新建一个第三方类,通过继承、组合、委托等方式,将已有的几个类联系起来,这样可以将它们的一些接口功能组合起来,而不用修改已有的类
桥接模式
继承重写虚函数的两种方式
方式一:继承抽象类重写虚函数,然后在其中编写需要的功能
方式二:同样是派生类A继承并重写虚函数,但是该类中有一个新类实例B,在B中实现需要的功能,然后在A重写的虚函数中调用B相应的功能,这种方法看似结果相同甚至多此一举,但是这样耦合性比方式一小,因为要是修改功能,只需要修改类B文件,不需要修改继承抽象类的类A文件
用户在派生类中继承重写虚函数时,具体实现不写在重写的函数体中,而是把功能委托出去,在函数体中调用委托对象,这样当实现需要修改时,基类和派生类文件都不需要改动
组合模式
组合模式的类都继承同一个抽象基类,所有派生类都有相同的虚函数
可以有单独一个派生类实例,该实例可重写使用基类的虚函数
派生类中保存派生类实例的容器,相当于父节点保存了几个子节点,所有节点可重写使用同一个基类的虚函数
类似树结构节点类
就像树节点,每个节点的属性名方法相同,具体的属性值不同
每个节点类都包含0-1个父节点,0-n个子节点,这些节点的类相同
装饰模式
类A的某个成员函数FA需要添加一些内容使用,可以继承类A派生出类B,然后类B在FB中编写需要添加的内容
在FB添加的内容下面调用类A的FA,如A::FA()
用户通过在类外装饰一层补充某个普通成员函数的功能
如继承类然后编写要补充的功能代码后,再调用基类的已有功能函数
修饰补充类已有功能
外观模式
某些操作需要几个类进行有序构造调用功能函数,如程序编译的步骤:预处理、编译、汇编、链接
新建一个类,在该类中构造四个步骤的实例并调用相应功能,这样在用户使用时,直接调用该类就可以了,比如现在的IDE开发工具
多个类实例有序执行才可得到需要的结果
新建一个类,在其中实现上述的实例并执行
这样用户只需要调用该类就可使用需要的功能
就像在有序执行的步骤外面套一层外观,更简洁易用
享元模式
节省空间资源,如编写一个黑白五子棋,每颗棋子有坐标和颜色两个属性,棋盘类Chessboard需要保存每颗棋子实例
方式一:struct Piece{POINT pos; COLOR co;},Chessboard类中容器vector<Piece*> ps 保存创建的棋子,每颗棋子都有个Piece实例
方式二:PieceFactory棋子工厂中创建黑白两色的棋子,每次需要棋子时向工厂中取出相应颜色并更新坐标属性,然后传递棋子指针给棋盘类,Chessboard类中容器map<POINT,Piece*> ps保存创建的棋子,每颗棋子只占用坐标属性的空间,对应的颜色可以从PieceFactory类中获取,也就多了两个Piece实例占用空间,该方式所有棋子共享了黑白两色的两个实例
方式二比方式一明显节省空间资源
用户需要创建保存大量的项目A实例,这些实例的某些属性只有几个确定值
那么这些属性可以筛选出来组成新项目B,工厂F中保存着每个值对应的B实例
筛选剔除某些属性的项目A+筛选出某些属性组成的项目B=原项目中的所有属性
保存所有项目实例的容器vector改为map,每个A实例对应着工厂F中的某个B实例指针
相当于全局A实例共享着工厂F中几个B实例,而不是有多少个A实例就有多少个B实例
代理模式
简单点就是类A需要一个辅助功能,然后该辅助函数写在类B中,在类A中保存着类B new出的实例指针
如模仿出C++智能指针类,该类中需要个计数器,然后智能指针类保存计数器类实例,让计数类代理该功能
用户通过代理类执行主类需要的功能
职责链接模式
抽象类中有个虚函数HandleMsg,该函数需要处理Msg消息请求,每个继承该抽象类的派生类,都需要处理消息请求
如:有许多消息类型(靠消息枚举区分),每个派生类都有自己需要处理的N个枚举类型,或者某个枚举类型所有派生类都需要处理,也可以设计成派生类注册某个枚举消息,就处理哪些消息
一些简单的程序架构经常用到,如C++程序网络消息处理、QT程序事件或者信号发送处理
命令模式
调用操作的对象和具体操作执行的地方进行解耦
抽象命令类Command,继承Command生成不同的命令类实例,命令执行类Exectue,每个命令类都保存着执行类实例
当相应命令的操作需要修改时,不需要修改Command类文件,只需要修改Exectue类文件,调用命令者和命令接收处理者不用直接交互
用户通过调用具体的Exectue操作类调用具体的Command命令类
中介者模式
QT中两个类通信只需要绑定信号槽就可以了,C++两个类也需要通信的话,简单点只需要借用中介者就可以了
类A,类B,中介类Mediator,A和B中保存着Mediator实例,Mediator中保存着A和B的实列,A发送消息给中介,中介再发送消息给B
同理,B发消息给中介,中介再发送消息给A
用户通过中介类建立两个不想关类之间的通信
备忘录模式
State状态类A、StateSave保存状态类B、Exectue操作类C
操作类功能:改变状态、利用B恢复状态
用户通过操作类改变状态值,通过保存类保存状态初始值
状态值改变后,操作类通过保存类恢复状态初始值
观察者模式
多个观察者,一个目标
目标类:保存多个观察者(可删除)的容器,自身的状态State
观察者:UpdateState,更新显示目标新的状态
当目标状态发生改变时,遍历执行容器中的观察者实例,执行UpdateState操作
即目标发生改变,所有观察该目标的观察者都能知道
用户通过目标中保存的所有观察者,当目标发生变化时,目标遍历观察者容器通知自身的变化
状态模式
将对象的状态和对应状态下的行为分离开来
状态处理类StateHandle中保存状态类State(可切换状态),在类StateHandle中的成员函数中调用保存的状态类的状态处理函数
用户通过状态处理类来处理相应的状态行为
策略模式
策略类Strategy、执行策略类Context
用户通过调用相应的策略类Strategy调用具体的策略类Context
可结合简单工厂使用,用户通过不同的枚举传入工厂,工厂创建相应的策略或者执行已有策略
用户通过Context操作类来调用具体的Strategy策略类
访问者模式
访问者类Visitor、元素类Element、元素操作类Exectue
元素操作类Exectue:保存元素的容器、变量访问者实例
用户通过Exectue遍历所有元素实例,并将访问者实例传入元素,相应元素接收到访问者后,元素将自身this传入访问者对应的元素操作接口,访问者再处理相应的元素
模板方法模式
模板方法基类Base、模板方法类Concrete
类中有几个方法的执行顺序,但是相应的方法没有具体的实现,不同的模板方法都有自己的具体方法实现,而基类保证了方法的执行顺序
用户通过基类指针Base指向具体的模板方法类实例Concrete,调用基类的执行函数,方法函数按顺序执行
多个任务的执行步骤顺序相同,但是步骤的具体内容不同
可以将执行顺序写在基类的成员函数,每个步骤都是一个虚函数
每个任务都继承基类生成派生类,在其中实现每个步骤虚函数的具体实现