结构型模式

 结构型模式

 Adapter 适配器

 适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。

 Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况” ,在遗留代码复用、类库迁移等方面非常有用。

 GoF 23 定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。

Bridge 桥接

 Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有 的绑定关系,使得抽象(Tank的型号)和实现(不同的平台)可以沿着各自的维度来变化。

 所谓抽象和实现沿着各自纬度的变化,即“子类化”它们,比如不同的Tank型号子类,和不同的平台子类)。得到各个子类之后,便可以任意组合它们,从而获得不同平台上的不同型号。

 Bridge模式有时候类似于多继承方案,但是多继承方案往往违 背单一职责原则(即一个类只有一个变化的原因),复用性比 较差。Bridge模式是比多继承方案更好的解决方法。

 Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使 有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式.

 Composite 组合

 Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一 对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对 象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

 将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思 想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复 内部实现结构——发生依赖关系,从而更能“应对变化”。

 Composite模式中,是将“Add和Remove等和对象容器相关的方法”定 义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容 器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题, 需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对 于这种特殊结构,这又是必须付出的代价。ASP.NET控件的实现在这 方面为我们提供了一个很好的示范。

 Composite模式在具体实现中,可以让父对象中的子对象反向追溯; 如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

Decorator 装饰

通过采用组合、而非继承的手法, Decorator模式实现了在运行时动 态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了 单独使用继承带来的“灵活性差”和“多子类衍生问题”。

 Component类在Decorator模式中充当抽象接口的角色,不应该去实 现具体的行为。而且Decorator类对于Component类应该透明——换 言之Component类无需知道Decorator类,Decorator类是从外部来扩 展Component类的功能。

 Decorator类在接口上表现为is-a Component的继承关系,即 Decorator类继承了Component类所具有的接口。但在实现上又表现 为has-a Component的组合关系,即Decorator类又使用了另外一个 Component类。我们可以使用一个或者多个Decorator对象来“装饰”一 个Component对象,且装饰后的对象仍然是一个Component对象。  Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式 应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰” 的含义。

Façade外观

从客户程序的角度来看, Facade模式不仅简化了整个组 件系统的接口,同时对于组件内部与外部客户程序来说, 从某种程度上也达到了一种“解耦”的效果——内部子系统 的任何变化不会影响到Façade接口的变化。

Façade设计模式更注重从架构的层次去看整个系统,而 不是单个类的层次。Façade很多时候更是一种架构设计 模式。

 注意区分Façade模式、Adapter模式、Bridge模式与 Decorator模式。Façade模式注重简化接口,Adapter模式 注重转换接口,Bridge模式注重分离接口(抽象)与其实 现,Decorator模式注重稳定接口的前提下为对象扩展功 能。

Flyweight享元

 面向对象很好地解决了抽象性的问题,但是作为一个运行 在机器中的程序实体,我们需要考虑对象的代价问题。 Flyweight设计模式主要解决面向对象的代价问题,一般不 触及面向对象的抽象性问题。

 Flyweight采用对象共享的做法来降低系统中对象的个数, 从而降低细粒度对象给系统带来的内存压力。在具体实现 方面,要注意对象状态的处理。

对象的数量太大从而导致对象内存开销加大——什么样的 数量才算大?这需要我们仔细的根据具体应用情况进行评 估,而不能凭空臆断。

Proxy代理

 “增加一层间接层”是软件系统中对许多复杂问题 的一种常见解决方法。在面向对象系统中,直接 使用某些对象会带来很多问题,作为间接层的 proxy对象便是解决这一问题的常用手段。

 具体proxy设计模式的实现方法、实现粒度都相差 很大,有些可能对单个对象做细粒度的控制,如 copy-on-write技术,有些可能对组件模块提供抽 象代理层,在架构层次对对象做proxy。

 Proxy并不一定要求保持接口的一致性,只要能够 实现间接控制,有时候损及一些透明性是可以接 受的。

 

posted on 2021-02-19 19:51  西洲SDQ  阅读(99)  评论(1编辑  收藏  举报