设计模式总体介绍
1 创建型模式
其本质是为了解决new XXX硬编码的问题。
1.1简单工厂模式
简单工厂中,有一个工厂类,所有的产品,用工厂类的一个函数来进行构造,通过传递不同的参数来进行构造。
简单工厂中,所有职责在同一个函数中,职责过重,而且不利于通过继承来进行修改。
简单工厂,工厂类只有一个,工厂类中也只有一个静态方法。
1.2 抽象工厂模式
Client客户想要使用ProductA与ProductB,不能直接进行new,而是通过一个抽象工厂来进行创建,不同的工厂产生不同的产品的组合。
当然,也可以通过参数来确定如何产生不同的产品。
工厂封装了创建产品的责任与过程,将客户与类的实现分离。
1.3 生成器模式
一个类,需要有多个部分组成,每个部分都可能有多种选择,然后,我们有多种预制,这些预制可以放在Builder中,通过不同的Builder子类来表示这种预制。
Director则通过请求Builder中的各个部件的接口,来获取多个部件的组合。
对Director而言,不和具体的部件类打交道,而通过Builder来得到部件。Director负责部件的组合。
与抽象工厂相比,构造器更注重构建,它有一个Director专门来负责对各个部件的构建。
实例:主界面风格,主界面中有菜单,工具条,状态栏,其他组成等。
1.4 工厂方法模式
工厂方法:有很多从同一个类中继承来的产品类,同时,对每个产品类,都有一个对应的工厂类。不同产品的选择,通过实例化不同的工厂类来实现的。
工厂方法模式: 只有一个抽象产品类,具体工厂类只能创建一个具体产品类的实例
抽象工厂模式: 有多个抽象产品类 ,具体工厂类能创建多个具体产品类的实例
1.5 原型模式
1.6 单例模式
2 结构性模式
结构性模式涉及如何组合类和对象,以获得更大的结构。
结构性对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现一些新功能的一些方法。
2.1适配器
将一个类的接口转换成另外一个接口。
客户需要使用一个名为Target的接口,而我们只有一个Adaptee的对象,该对象符合Target的基本要求,但由于接口不匹配,因此不能直接用于Client中。
适配器接口则是用Adapter继承target接口,然后集成了一个Adaptee的对象,具体功能通过Adaptee对象的转发来完成。
适配器分为类适配器和对象适配器,前者是通过多继承来实现的,后者是通过聚合的方式来实现。对象适配器更为灵活,一个适配器类可以与多个Adaptee进行适配。而类适配当碰到多个Adaptee的平行子类时就无法实现了。
实例:比如我们有一个使用double类型数组来表示六根数的参数,然后我们又有六根数类,就可以用适配器方法,将double数组转换为六根数。
2.2 桥接
桥接是为了解决组合爆炸问题而出现的。Abstraction类会有多个对象,每个对象都可能拥有多组方案,因此形成组合爆炸。则此时,可以将方案抽象为Implementor类,几套不同的方案则对应不同的子类,然后在Abstraction类中保存Implementor类的一个引用。
实例:如覆盖计算问题,覆盖计算类可以作为这个Abstraction,然后,网格点法,经度条带法等作为Abstraction的子类。然后,覆盖计算问题(瞬时覆盖,累积覆盖等)可以被抽象为Implementor,不同的覆盖问题对应不同的子类。
2.3组合
Component是一类组合的公共父类,有多个不同类型的子类,然后有个Composite类,也是Component的子类,但该类却是不同类型子类的一个组合。
在composite类中,保存着一个列表,包含了所有的Component组件的列表。
2.4 装饰
装饰者也是Component的子类,其目的在于,将ConcreteComponent类的基本功能的基础上,添加上额外的一点功能。
装饰与组合的异同:装饰和组合都是组件类的子类,但装饰注重的是在原有功能的基础上添加新的功能,而组合模式则是将若干部分组合为整体。
2.5 外观
当一个系统,要实现某个功能,需要有步骤一到步骤六六个基本步骤,而很多时候,我们并不关系这六个步骤是什么,而只想要完整的功能,则此时,就需要外观模式。
Façade中,将多个子系统聚合在一起,然后提供一个方法,能够将多个子系统按照一定的逻辑顺序先后调用,执行完整个流程。以后,我们想要实现功能,就不需要和子系统打交道了,而只需要和Façade打交道。
2.6 享元
很多对象,在系统中出现多次,但没法直接重用,因为这些对象虽然绝大部分属性相同,但也有几个属性是不同的。此时,可将对象的属性分为内部属性和外部属性,然后将只含有内部属性的对象封装,外部属性的话,采用额外的机制进行控制,从而实现对象的共享。
2.7 代理
当实际对象不方便实例化时,我们可以设置一个代理,保存了对象必要的信息。
3 行为模式
3.1模板模式
没有客户类,而是有一组继承关系,在父类中写流程逻辑,在不同的子类中负责不同的操作对象。
模板是一种典型的基于继承的多态。
3.2策略模式
在客户类中,保存一个策略的父类,通过传递不同的子类参数,以达到实现不同策略的目的。
策略模式只是一个最简单的多态,只不过,策略模式是将算法封装为一个策略类而已。
策略是一种典型的基于组合的多态。
3.3命令模式
将命令封装为一个类,然后不同的命令用不同的子类实现。实现一个Invoke函数,用于接受命令参数,并执行命令。
命令模式是为了解除命令的发出者和命令的接受者之间的紧耦合关系。
命令模式的核心思想,是将命令封装为一个对象,将其作为命令发起者和接受者的中介。
Invoke是命令的发出者,Command是命令的传递者,Receiver是命令的接收者。
Invoke会通过命令输入函数保存一个命令或者一组命令,然后调用Execute函数执行命令,而每个命令,也需要有个机制能够设置命令的接收者,从而实现命令从发出者向接收者之间的传递。
3.4状态模式
有一个状态类,状态类有很多子类,在每个状态子类中,都封装着从当前状态跳转到下一状态的基本逻辑。在客户类中,保存着一个当前的状态,然后不断调用状态改变,就会进行一系列状态的改变。
3.5观察者模式
建立一个一对多的关系,当“一”发生变化时,依赖这个“一”的多,也能同步改变。
观察着模式,被观察者需要有个“注册”和“注销”的基本功能,并且有一个列表,保存着所有的观察者,而且被观察者需要有个“状态”的概念,当状态改变时,通过通知函数通知所有的观察者,观察者中有个Update方法,可以更新自身状态。
实例:图表,二维三维仿真。
3.6备忘录模式
备忘录模式就是在不破坏封装性的前提下,捕获并保存一个类的内部状态,这样就可以利用该状态实施恢复操作。
3.7中介者模式
中介者模式将对象间的交互和通信封装在一个类中,这个类就是中介者。各对象之间不需要知道彼此就能进行通信。
在中介者中,需要知道这些通信类的一个公共接口,通过公共接口来进行对象间通信即可。
中介者模式,将对象与对象间的通信解耦。
中介者模式的另一个特点是控制集中。
3.8访问者模式
3.9职责链模式
用一个链表结构,将所有消息的接受者串联成串,然后消息在接受者队列中不断传递,直到传递完成。这些消息的接受者有同一个父类,因此能够直接保存到一个链表中。
职责链和观察者区别:
一个是链表,一个是数组。
观察者之间,所有观察者之间是平行的,而职责链,是有先后关系的,前面的对象可以对消息进行一定的封装后再转发。
3.10解释器模式
如对XML的解释器等。