原文:
结构型模式涉及到如何组合类和对象以获得更大的结构。结构型类模式采用继承机制来组合接口或实现。结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。因为可在运行时改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。
Adapter
意图:将一个类的接口转换成客户希望的另外一个接口(转换接口)。Adapter模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。
动机: 重用已有的类。
适用性: 重用已有的类去完成正在编写的类中所需的功能。一般原有的类的功能应该和所需类的功能相近,或者更多。
结构: 使用对象组合。不一定就用于子类的编写,也可以是普通类的编写,因此继承关系并不是必须的。典型例子:ACE对系统调用函数的封装。
优点: 重用代码,简化类的编写和测试。
Facade
意图:为子系统中的一组接口提供一个一致的界面(一致的接口), Facade模式定义了一个高层接口,这个接口使得子系统更加容易使用(简化接口)。
动机: 封装复杂的子系统,使客户更容易使用。同时也封装了原系统变化所引起的客户代码变化。
适用性: 存在功能复杂或易变的子系统,使用Facade增加一个封装层,方便用户使用。
结构: 使用一个类为子系统提供一组易用的对外接口。
优点: 简化编程,隔离变化。
Bridge
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
动机: 分离对外接口和内部实现。本质上就是分离两个变化点,并单独封装其变化。
适用性: 用于具有两个变化点的抽象概念的分离。
结构: 使用两个抽象封装不同的变化点。
优点: 简化类之间的继承关系(理论上,一个抽象一个变化点)。隐藏实现的变化对客户的影响。适用于跨越多个平台的图形和窗口系统。
Composite
意图:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。
动机: 隐藏“一对多”的关系,让客户一致的对待不同的对象。
适用性: 常用于结构上具有显式树型结构的对象关系。当使用一致的方式对待列表中的每个对象的情况时,可以使用Composite来封装对对象列表的管理和遍历,简化客户代码对对象的管理,使客户能够使用一致的代码来对待所有对象。
结构: 常常在Composite的一个派生类中,使用列表来管理其他的派生对象;或者基于递归组合来组织可变数目的对象
优点: 封装了“一对多”的对象关系,使客户能够统一的对待所有的派生对象。省去客户自行管理对象的行为和代码(省略大量if语句)。
组合模式: 可以和Command对象一起使用,封装“一对多”的关系,当然如果Command对象需要考虑顺序或者其他情况的时候,应该使用Builder来构建。常常使用Builder来构建Composite,用Iterator来遍历对象。
Decorator
意图:动态地给一个对象添加一些额外的职责。就扩展功能而言,Decorator模式比生成子类方式(继承)更为灵活。
动机: 复用现有的类,在不破坏原来的条件下, 添加一些额外的职责/功能。
适用性: 存在一个具备核心功能的类(组件),但是同时需要一些附加的功能。使用Decorator可在不破坏原类的条件下,动态添加所需的附加功能。
结构: 如果需要动态的替换,继承关系是必须的,在继承关系下,只需在复用原类接口下改写部分接口即可。但是如果没有替换要求,没必要一定使用继承关系,只需简单的适配所需的接口即可。一般,每个装饰者都“有一个”(包装一个)组件,即保存某个组件的实例。如果需要多次修饰,那么可用多个装饰者包装核心组件(多层次继承)。
优点: 代码复用;容易在核心功能代码的基础上增加额外的功能。
缺点:装饰者会导致设计中出现许多小对象,如果过度使用,会使程序变得更加复杂。
Flyweight
意图:运用共享技术有效地支持大量细粒度的对象。让某个类的一个实例提供许多“虚拟实例”
动机: 对象共享,优化性能
适用性:当一个类有许多细小实例,且实例能被同一个方法控制,可使用绳量来存储细小对象,即将所有原来的实例状态存储在一个类中,统一管理。
优点:减少运行时对象实例个数,节约内存;将许多“虚拟”对象的状态集中管理。
Proxy
意图:为其他对象提供一个代理以控制对这个对象的访问。
动机: 对某个对象的访问有特殊的要求。比如需要跨越网络障碍等。
适用性:远程代理控制访问远程对象;虚拟代理控制访问创建开销大的资源;保护代理基于权限控制对资源的访问;缓存代理控制对缓存对象的访问。
结构:常用代理包装实际对象,在必要时可通过工厂来实例化对象。
优点: Proxy是一个重型模式(需要实现原对象的大部分接口),可使用Facade代替。
区别:1)装饰者为对象增加行为,代理是控制对象的访问。2)适配器会改变对象适配的接口,而代理则实现相同的接口。
-------------------下面两个可能谈不上模式,更像代码重构惯用法----------------------------
Compose Method
意图: 将一个比较复杂(逻辑或步骤多)的方法(接口实现)转化成为一系列意图自明的更小方法(接口)。
动机: 提供代码的可读性。
适用性: 所有的复杂的接口实现。该模式经常用于重构现有的代码。
结构: 用更小的接口封装代码行。
优点: 能够大大改善代码的可读性,如果接口名字取的好的话。
组合模式: 可与任何模式相结合,改善代码的质量。
Collecting Parameter
意图: 使用对象(结构体)在不同的地方进行参数收集。
动机: 所需的参数分散在系统的不同地方,使用该模式简化参数的收集和传递。
适用性: 用于类之间的数据收集和传递,也适用于类内部的参数收集和传递。
结构: 一般使用结构体来存放所需参数。
优点: 有利于接口之间和对象之间的参数传递。
组合模式: 常和ComposeMethod方法一起使用。