用以致学,学以致用
- 每一种方法都有一个核心,用法形式并不重要
- 设计模式的技术基础是面向对象,设计模式从类开始;
- 设计模式的应用基础是业务性质,设计模式不是美学的选择,是业务性质的选择(因此正确操作方法是先描述业务及性质,然后用面向对象原则去设计)
- 设计模式从需求开始;需求驱动着设计模式演化成系统。
- 类/接口的结构是设计模式的起始点和落脚处,结构决定性质。
- 每种设计模式的侧重点都不一样,所以性质也就不一样,因此应用场景也不一样
- 多个设计模式往往交叉混合使用,以模拟、应对复杂多变的现实
应用设计模式必须对语言的机制深入理解,如接口与抽象类的区别
创建型模式
模式名称 |
使用描述 |
类图 |
应用场景 |
单例模式 |
判断是否为空,有则返回无则新建 |
... |
一个运行时内全局资源唯一并可以全局调用 |
工厂方法 |
暴露方法,过程下放(方法与实现分离),有依赖 |
... |
一维分类讨论 |
抽象工厂 |
接口内定义实体类别,具体工厂实现生产,有依赖 |
... |
多维分类讨论 |
建造者 |
导演类赖建造接口并定义建造接口的流程规范,具体建造类实现各个部分、环节;建造者与工厂的区别是建造者用于构造多部分组成的复杂对象 |
... |
流程固定,类型及环节局部多变 |
原型模式 |
克隆接口,克隆对象 |
... |
资源较多,需要复制上下文 |
Pool模式 |
管理对象的重用。获取对象时有则从栈弹出没有实例则新建 |
|
在创建对象比较昂贵,或者对于特定类型能够创建的对象数目有限制时 |
结构型模式
模式名称 |
使用描述 |
类图 |
应用场景 |
适配器 |
适配器者统一、协调者也,适配类依赖被协调者 |
。。。 |
功能一致但是api繁多,需要统一 |
桥接 |
将依赖元素双方都抽象化,运行时绑定具体对象 |
|
对象动态绑定,要求不同维度元素松耦合(组合>继承) |
组合 |
组合者吞云吐雾。为了多层嵌套,组合者要实现与其成员的根类同样的的抽象结构,根据抽象类可以有抽象成员的特性,吞进(包括自己)抽象数组中,吐出各自实现。组合不同维度实体 |
|
对象嵌套依赖 |
装饰者 |
装饰者即强化、装饰之用,所以不能更改方法名,故应实现对象接口,并将对象接口组合到内部成员,装饰者从而对兄弟类进行包装wrap装饰 |
|
对象行为、职责可修改、可增加 |
外观 |
统一子系统api到一个api里面 |
|
客户端要求提供统一接口 |
享元工厂 |
享元即共享单元,将基础构成元素设置为享元,根据key从享元工厂的享元池中获取运行时的享元,没有则新建;可以减少内存占用 |
|
需要命中缓存,利用元素、状态有限性解决性能问题 |
代理 |
代理与实体实现同一接口,并将实体组合到内部成员,对外只提供代理;或者让代理继承实体,既将生成的实现解耦,且对外完全隐藏了实体; |
|
安全访问、隐藏实体、简单装饰 |
依赖注入 |
将核心类的注入参数进行抽象/接口化,将属性的创建生成与核心类解耦,解决注入参数的多样性 |
|
配置多样,实现多样,类别多样等 |
注册容器 |
容器内添加数组类结构当做中心存储器 |
|
多个相同概念的对象需要存储时,可以通过操作键值对类型结构来存取键值,而不用列成多个属性 |
Service Locator服务定位器 |
|
|
松耦合,将类与实例 绑定 |
行为型模式
模式名称 |
使用描述 |
类图 |
应用场景 |
职责链/责任链 |
干系人实现接口,在责任链处理类中遍历/递归干系人去处理,直到责任到人 |
|
多个对象均有处理请求的机会,请求不清楚干系人具体是谁,责任运行时才能明确或者责任人为决定,需要解决责任的不确定性 |
命令 |
请求抽象成类,请求者、接收者分别依赖请求类 |
|
请求者与接收者要求解耦,请求 |
解释器 |
重新解释文法 |
|
性能要求不高,文法与表示表达解耦 |
迭代器 |
由聚合体创建迭代器,迭代器通过聚合体count等来顺序访问 |
|
无权访问内部却要访问全部子元素 |
中介者 |
中介即平台,实体对象自主出入中介平台,当有实体与中介通信,中介则更新内部的实体列表 |
|
多个实体对象需要复杂通信,中介者不生产信息 |
备忘录 |
实体对象可对外生成状态备忘,并可由备忘恢复状态,管理者管理备忘列表 |
|
不破坏封装性又需要获取、保存、恢复对象的内部状态 |
观察者 |
发布/订阅模式,订阅者自有更新实现,目标添加订阅者队列后,目标变化则通知订阅者队列更新 |
|
目标生产信息,处理对象可变 |
状态 |
根据状态创建实体,有效限制行为权限。实体实现状态处理的接口,调用者主动调用;这是种比状态的条件判断更优雅、干净的处理方式 |
|
实体多种状态且其行为差异大,实体状态变化会引起外在变化,条件复杂实体只能根据状态产生变化 |
策略 |
调用者应变后生成策略,再调用相应策略的被使用的方法,实现策略的快速切换 |
|
条件状况复杂多变,需要多种策略;对象行为在运行时决定 |
模板方法 |
父类提取公共方法,子类实现可变方法,并由钩子方法反向控制父类 |
|
复杂算法可以拆分为模板方法和父类具体方法 |
访问者模式 |
一个对象将操作外包到另一个对象,以简化专注点。一个使用Visitor模式的客户必须创建一个ConcreteVisitor对象,然后遍历该对象结构,并用该访问者访问每一个元素。当一个元素被访问时它调用对应它的类的Visitor操作,如有必要该元素将自身作为操作的一个参数以便该访问者访问它的状态。一般被访问者通过参数注入方式或者组合依赖方式被访问 |
|
需要将元素的操作从元素组中分离解耦出来——元素的分离;需要将操作分离出来当做更细粒度的对象——操作的分离; |
附录:
