适配模式,桥接模式,组合模式,装饰模式和代理模式
继续疏理下结构型设计模式:
首先是适配模式。当用到的对象有对应的功能,而接口并不精确匹配,就用适配模式。适配模式有两种形式。一种是类适配器。把适配器和被适配的类同过多重继承做在一起,公开适配器的接口,屏蔽被适配的类的接口,使得被适配的类能够被调用者使用。另一种是对象适配器。适配器和被适配的对象互相独立,通过向适配器传递适配对象的指针来构造适配器,从而使适配对象能够被调用。差别在于适配器的生命周期。类适配器和被适配的对象同时建立和丢弃,适配是终身制;而对象适配器可以在刚好用到的时候构造,用完之后就扔掉,无妨对象仍然是原来的对象。
如果把适配器就地植入到一个类系的基础类中。就演变成桥接模式。桥接模式在基础类构造并封装一个后端类对象的多态指针,并且向派生类公开这个后端对象指针。派生类通过引用这个多态指针来引用后端类。
如果继续把桥接模式封装的指针推广为容器,用容器就可以装入更多的指针,就变化成组合模式。组合模式的组合类内部含有一个容器,用来添加被组合对象的指针。组合类模拟被组合对象相同的接口,因此使它的容器能够添加它自己。组合类模拟的接口其他方法,都通过迭代容器,最后转归成为被组合的对象的相应方法。如果遇到被组合的对象仍然是组合,则递归迭代。
作为一种极端情况,如果适配模式中,被适配的对象已经有了相应的接口。这时候,对象已经可以被调用者直接调用。再用适配器看起来是荒谬的。自己适配自己,结果基本类型没有变化。然而真的可以这样用。因为适配的结果没有变化,就可以连续应用这种适配而在运行时为对象追加功能。这就是装饰模式了。装饰模式就好像把继承关系从编译期延后到了运行期,用嵌了套的动态组合实现继承。虽然,仍然可以用编译期继承,而避免使用装饰模式。但是,并非所以对象都是以简单的方式new出来。一些对象通过工厂模式构造出来,它们的构造函数,复制构造函数都被做了屏蔽,这时使用编译时继承变得不可行,但是仍然可用装饰模式在运行时附加新的功能。
如果适配者完全克隆了被适配对象的接口,适配器可以参加到任何一个被适配对象的调用中去。这种方式就是代理。最简单的情况就是相应被调试的对象插入一个代理,通过代理输出额外调试的信息。调试完成删掉代理就恢复了代码原有的结构。但代理模式并不限于调试,可以在代理过程应用各种策略。比如对频繁发生的load/save读写文件可以采用某种缓冲策略。通过检索缓存而避免逻辑上互相对消的load/save操作频繁发生,从而提高了性能。
最后,在这里笑话一下:结构型设计模式是如此密集,只要你敢于把一个多态指针添加到一个类或者类系的基础类中,很难不撞上几个设计模式!