设计模式
23种设计模式:重点:单例模式、工厂模式、门面模式、代理模式、策略模式、备忘录模式、状态模式、访问者模式、模板方法模式、观察者模式、迭代器模式
创建型
单例、工厂(简单工厂、工厂方法、抽象工厂)、建造者、原型 (5)
结构型
门面、代理、适配器、组合、桥接、装饰者、享元(7)
行为型
策略、备忘录、状态、模板方法模式、观察者模式、访问者模式、迭代器、责任链模式、命令模式、解释器模式、中介者模式(11)
创建型:单例、工厂(简单工厂、工厂方法、抽象工厂)、建造者、原型
单例:
malloc一个内存,创建一个实例,比如创建一个链头句柄,
分饿汉模式和懒汉模式:
1、饿汉模式是进程起来的时候创建实例,后面添加元素的时候不用再创建,进程结束的时候销毁
2、懒汉模式当添加第一个元素的时候创建这个句柄,后面继续添加的时候不用再创建,删除最后一个元素的时候删除这个句柄,这个好处就是节省空配置启动内存
单例模式的优点是:节省内存,不用频繁的创建销毁实例,保证核心的内存在整个程序执行阶段都可以被有效访问
缺点:应用场景局限,而且访问的时候很有可能造成空指针访问,需要做判空处理
工厂方法:
创建实例时,将具体的实例生产方式交给子类实现,
比如有多个业务需要创建各自不同的实例,并且调用同一个接口去创建,那么怎么样去避免不同业务的差异呢,我们可以在init函数入口传入入参
,通过函数指针的方式去屏蔽业务的差异,将差异交给业务去实现,这样的话创建接口只负责抽象的处理,符合开闭原则
简单工厂将业务差异通过业务类型的不一样交给接口去感知差异,这样不符合开闭原则,增加一个业务需要在接口中增加业务回调。
抽象工厂就是对工厂的抽象,工厂方法往往是一个接口,而抽象工厂往往是一组接口
建造者:
将一个复杂的对象拆分成最小粒度的元素,并且将这些元素进行组合
优点是层次分离,调用者无需关心内部实现细节,缺点是使用范围局限,一个产品必须要有相同的元素组成
原型:
重新创建一个实例,并且这个实例的内容是对原实例的拷贝
结构型:门面、代理、适配器、组合、桥接、装饰者、享元
门面:
将子系统内部差异的行为屏蔽,抽象出一个统一的接口给外部调用,比如socket就是将庞大的TCP/IP协议族统一出来的抽象层
代理:
比较适用于C/S模型,中间可以抽象一个proxy来保护目标对象,对于Client来说proxy相当于server,对于server来说proxy相当于一个client。
它与门面模式的区别,门面代表多个子系统,而代理往往代表一个。
适配器:
垫层,比如接口表项管理,就是将平台下发的数据适配成微码所能识别的字段
组合:
部分-整体,比如AVL中有根节点、孩子节点、叶子结点,每个元素都拥有自己的特性,比如叶子的它的特性是左右孩子为NULL,整个树形系统由这些部分组合成一个整体
桥接:
将抽象和实现分离,降低两者的耦合度,并将它们组合起来,而不是放在一个接口中实现,将多个维度结合
装饰者:
给对象添加一些额外的职责
享元:
减少相同属性的对象的创建,共享相同属性
行为型:策略、备忘录、状态、模板方法模式、观察者模式、访问者模式、迭代器、责任链模式、命令模式、解释器模式、中介者模式
策略
对象的某个行为在不同的场景中有不同的表现,比如relay选择server的策略有主备、轮询、和全转发,通过不同的策略配置,那么选择server的行为不一
备忘录
标记对象的某一个状态,比如AVL的先序遍历,我们可以定义一个指针指向最小节点,这样我们做遍历时就不用每次首先遍历左子树找到最小节点了,增加性能
状态
当一个对象的内部状态发生变化,允许它的行为发生变化,比如用户上线时区分offering和bound状态,每一种状态对于选取server的策略又是不一样的
模板方法模式
将框架接口定义好,而将接口的实现留给子类,比如我们在做数据管理的时候通常有一些框架接口,init、uninit、增删改查等等
这里面会有一些抽象的处理,业务差异交给业务去实现各自的接口
提取公共模式,便于维护,符合开闭原则
观察者模式
定义了对象之间一对多的依赖关系,它适合C/S模型,server发布一个服务,由多个client去订阅这个服务,当server发生变化时需要通知被依赖的对象,
比如当接口中的某个属性发生变更时,需要通知使用这个接口的所有业务去刷新这个属性,可以用来解决时序问题
访问者模式
将数据结构和数据操作分离,防止数据的操作污染了数据结构,比如数据管理我们可以提供增删改查的接口,而具体是如何将这些数据做管理,到底是通过AVL还是链表还是红黑树、我们将管理链隐藏,只对对象操作
迭代器
将遍历抽象为一个first接口和一个next接口
责任链模式
就好比如路由器的软件部件组成,当测试找过来查看一个问题的时候,首先根据黑盒现象查找责任田模块,当责任田模块发现这是另外一个模块的问题,那么需要由责任田模块将问题的定位进展作交接。
类似的,我需要你向我提供一个方法,我不关心你内部的依赖,由你去向下解决依赖的部分,这样可以给调用者带来方便
命令模式
CLI命令,可以将请求和如何实现进行隔离,类似于二维表(type、回调)
解释器模式
RF的关键字封装就是一种解释器模式
中介者模式
用一个中介者对象来封装一系列对象的交互。中介者使得各对象不需要显式地相互引用,从而解耦合,独立改变他们之间的交互。
代理(一对一)、门面(一对多)、中介(多对多)