七、Adapter配置器模式
动机:
在编写程序时,对象的接口一定会和当前的环境很好的融合。一旦将其他环境中的对象“转移”到新环境中,那么这些对象的接口就无法与新环境相融合。
怎样解决对象的迁移?
意图:
将一个类的接口转换成客户希望的另一个接口。
Adapter模式使得原本由于接口不兼容而不能而不能一起工作的那些类可以一起工作。
结构:
配置器模式有两个结构,分别为对象适配器结构和类适配器结构。
图一对象适配器
图二类适配器
Adapter模式的要点:
Adapter模式可以通过“转化”的方式来实现代码的复用。
GoF23定义了两种Adapter模式的实现结构:对象适配器和类适配器。前者侧重于对象间的组合,后者则依靠“多继承”的实现方式。“多继承”所带来的高耦合与程序一贯遵循的松耦合相背,所以不推荐使用类适配器结构。
为了方便更好的适配,应当尽可能使用“面向接口的编程。
八、Bridge桥接
抽象不应该依赖于实现细节,实现细节应该依赖于抽象
动机:
程序的变化点往往不仅仅只是一个,在面对“多维度的变化”时,应该如何解决
意图:
将抽象部分与实现部分分离,使它们都可以独立地变化
结构:
Bridge模式的要点:
Bridge模式通过对象间的组合解构了抽象与实现的绑定关系,使得抽象与实现可以完成各自的变化
“子类化”后的类对象通过不断组合可以实现Bridge模式的多维度变化
Bridge模式要优于多继承方案,根据单一职责原则,松耦合显然比强耦合要更加适应变化
模式应该活学活用,不可奉为圭臬,模式要服务于需求,合适的模式才是最好的
九、Composite组合
动机:
对象容器内的代码过多的暴露给客户代码,导致两者的耦合关系十分紧密,一旦发生变化容易引起代码巨大的变更
意图:
将对象组合成树形结构以表示“部分—整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
结构:
Composite模式的要点:
Composite模式强调对象代码内部的高内聚,也就是提供给客户代码的接口要尽量的少,以此来实现客户代码对抽象接口的依赖,降低客户代码与对象代码的耦合关系,提高应对变化的能力。
在使用模式时难免遇到两难的境地,如果侧重代码间的“透明性”,则降低了代码的“安全性”,反之亦然。模式只是提供了一个处理代码的思路具体如何完善要考虑实际需求。
十、Decorator装饰
动机:
在面对由于继承带来的灵活性降低,应当怎样解决?
如何动态的实现对象功能的扩展?
意图:
动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加的灵活
结构:
Decorator模式的要点:
通过采用组合、而非继承的手法,实现了运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子衍生问题”
Decorator模式解决的主要问题是“主题类在多个方向上的扩展功能”
十一、Facade外观
动机:
如何简化客户程序和系统间的交互接口?
如何将外部客户程序的演化和内部系统的变化之间的依赖相互解耦?
意图:
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一系统更加容易使用。
Facade模式的要点:
从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Facade接口的变化
Facade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Facade很多时候更是一种架构设计模式
十二、Flyweight亨元
动机:
如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够地使用面向对象的方式来进行操作?
意图:
运用共享技术有效地支持大量细粒度的对象
结构:
Flyweight模式的要点:
面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题
Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面要注意对象状态的处理
对象的数量太大从而导致对象内存开销夹打——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空翻新
十三、Proxy代理
动机:
如何在不是去透明性操作对象的同时来管理/控制这些对象特有的复杂性?
意图:
为其他对象提供了一种代理以控制对这个对象的访问。
结构:
Proxy模式的要点:
“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的Proxy对象便是解决这一问题的常用手段
具体Proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些对象对组件模块提供抽象代理层,在架构层次对对象做Proxy
Proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的
UML 物理视图
UML使用两种视图来表示实现单元:实现视图和配置视图。这些视图提供了将类映射至构件和结点的机会。
实现视图将系统中可重用的块包装成具有可替代性的物理单元,这些单元称为构件。实现视图用构件以及构件之间的接口与依赖关系来表示设计元素的具体实现。构件是系统高层的可重用的组成部件。下面是一个实现视图的图例:
配置视图表示运行时计算资源的物理布置。这些运行的资源称为节点。在运行时,节点包含构件和对象。构件和对象的分配可以是静态的,它们可以在节点之间迁移。如果含有依赖关系的构件实例放在不同的节点上,部署视图可以展示执行过程中的瓶颈。
UML 模型管理视图
模型管理视图对模型本身的组织建模。模型是从某一观点以一定精确度对系统所进行的完整性描述。模型由一系列包含模型元素(如:类,状态机,用例)的包构成.。包是操纵包内容,以及访问控制和配置控制的单元。因此,整个模型实际上可看成一个根包,它间接包含了模型中的所有内容。包是操作模型内容、存取控制和配置控制的基本单元。每一个模型元素包含于包中或包含于其他模型元素中。下面是一个图例:
创建型模式:
创建型模式围绕类和对象的实例化、引用等功能的一些系列操作来构建程序结构,实现结构的灵活性,更好的应对各种各样的变化