首页 > 代码库 > 谁是面向对象设计中的霸主?(中)

谁是面向对象设计中的霸主?(中)

         在上篇博文中,我们一起了解了创建型模式组的战况,下面我们来看看号称“死亡之组”的结构型模式的战况。所谓结构型模式,就是针对系统的结构进行设计,重点考虑产品的层次结构等问题。

         下面我们一起来了解一下本组各个门派的资料:

         适配器模式:讲一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

         桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

         组合模式:将对象组合成树形结构以表示“部分—整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

         装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更加灵活。

         外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一个系统更加容易使用。

         享元模式:为运行共享技术有效地支持大量细粒度的对象。

         代理模式:为其他对象提供一种代理以控制对这个对象的访问。

         好了,各个门派已经登台,大战一触即发,我们拭目以待:

         首先出招的是适配器模式:在现实世界里,变化无处不在,面向对象的出现就是为了更好的应对需求的变化,然而如果你想使用一个已经存在的类,而它的接口不符合要求,或者希望创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作,怎么办?哈哈哈……我们可以做到让这些接口不同的类通过适配后,协同工作。

         主动出击效果不凡,桥接模式接招:面对变化,面向对象的继承的确是不错,但是过度使用,势必会造成类的结构过于复杂,关系太密,难以维护,更加致命的是扩展性极差。而我们可以研究集成体系中,如果有两个甚至多个方向的变化,那么就解耦这些不同方向的变化,通过对象组合的方式,把两个角色之间的继承关系改为了组合的关系,从而使这两者可以应对各自独立的变化,怎么样,厉害吧?

         装饰模式乃女子门派,虽为女流之辈,但面无惧色:面对变化,如果采用生成子类的方法进行扩充,为支持每一种扩展的组合,会产生大量的子类,如此子类数目太多了,然而事实上这些子类无非就是为某个对象增加一些职责,此时通过装饰的方式,可以更加灵活、以动态、透明的方式给单个对象添加职责,并在不需要时,撤销相应的职责。

         组合模式一看这架势,不得不使出自己的独门绝技:我们擅长于表示对象的部分与整体的层次结构,希望用户忽略组合对象和单个对象的不同,用户能够统一地使用组合结构中的所有对象。用户使用组合类接口与组合结构中的对象进行交互,如果接收者是一个叶节点,则直接处理,如果是组合对象,通常将请求发送给它的子部件,并在转发之前或之后可能执行一些辅助操作,其效果是客户可以同样的方式使用组合结构和单个对象,任何用到基本对象的地方都可以使用组合对象。

         外观模式按耐不住,大喝一声,凌空而起:类之间的耦合性越弱,越有利于复用,如果两个类不必直接打交道,那么就不要让这两个类发生直接的相互作用,必要时,可以借助第三者来转发调用。我们的独门绝学是引入一个外观对象,它为子系统间提供一个单一而简单的屏障。通常企业软件的三层或者N层架构,层与层之间地分离其实就是外观模式的体现。

         享元模式,拍案而起,口中大喊,我来试试:对象使得内存占用过多,而且如果都是大量重复的对象,那就是资源的极大浪费,会使得机器性能减慢,面向对象技术有时会因简单设计而代价极大,比如文档处理软件,当中的字符都可以是对象,如果让文档中的每一个字符都是一个字符对象的话,系统开销令人汗颜。而文档之中的字符无非就是写符号,我们让所有相同的符号都共享一个对象,例如所有的“a”都共享一个“a”对象,节约内存。

         代理模式脚尖点地,腾空而起,直接向外观模式和适配器模式的方向奔去:代理与外观区别在于:代理对象代表一个单一对象儿外观对象代表一个子系统;代理的客户对象无法直接访问目标对象,由代理提供对单独的目标对象的访问控制,而外观的客户对象可以直接访问子系统中的各个对象,但通常由外观对象提供对子系统各元件功能的简化的共同层次的调用接口。至于我和适配器,其实都属于一种衔接性质的功能。代理是一种原来对象的代表,其他需要与这个对象打交道的操作都是和这个代表交涉,而适配器则不需要虚构出一个代表者,只需要为应付特定使用目的,将原来的类进行一些组合罢了。

         最后外观模式使出了威力巨大的三分归元气,顿时天昏地暗,飞沙走石:桥接和适配器被用于软件生命周期的不同阶段,针对不同问题,孰优孰劣,无从谈起。而我和适配器有些近似,都是对现存系统的封装,有人说我是另外一组对象的适配器,我觉得不妥,因为我定义的是一个新的接口,而适配器则是复用一个原有的接口,适配器是使两个已有的接口协同工作,而我则是为现存系统提供一个更为方便的访问接口。如果硬要说我是适配,那么我只能说适配是用来适配对象的,而我则是用来适配整个系统的,谁更厉害,明眼人都看得出来。

         激战之后,断壁残垣,一片狼藉,但胜者只有一个: