《大话设计模式》将于11月底由清华大学出版社出版
《大话设计模式》第29章-OOTV杯超级模式大赛—模式总结(一)
《大话设计模式》第29章-OOTV杯超级模式大赛—模式总结(二)
(接上篇)
29.5 结构型模式比赛
此时的后台,第二组选手正在做着准备,电视台的记者抓紧时间,对适配器小姐做了一个小小的专访。
“适配器小姐,您入选的结构型模式组被称为死亡之组,这一点您怎么看?”
“我觉得,所谓死亡之组,意思是有多个可能得冠军的选手不幸被分在了一组,造成有实力的选手会在小组赛中提前被淘汰,但那是针对体育比赛,我们这种选秀活动,选手只要充分表现了自己,就是成功,最终结果往往是多赢的局面。所以我不担心。”
“您觉得您有可能成为冠军吗?”
“不想当冠军的模式不是好模式。我来了,当然就是要努力争取第一。”
“您是否有与众不同的杀手锏来获得胜利?”
“我有杀手锏?”适配器小姐笑着摇摇头,“努力争取胜利就可以了。不好意思,我得准备去了,再见。”
当适配器离开后,记者小声地对摄像师说,“你把最后一句擦掉。然后我们再录。”接着这记者拿着话筒对着摄像机,正式地说道:“观众朋友,适配器小姐说,她有成功致胜的杀手锏,但她却并没有提及内容,最终是什么让我们拭目以待。OOTV记者赵谣前方为您报道。”
“欢迎回到第一届OOTV杯超级设计模式大赛现场,下面是第二组,也就是结构型模式组的比赛,她们将穿C#休闲装出场。”
“6号选手,适配器小姐,她的口号是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。[DP]”《大话设计模式》
6号选手 适配器(Adapter)
“7号选手叫桥接。桥接小姐提倡的是将抽象部分与它的实现部分分离,使它们都可以独立地变化。[DP]”
7号选手 桥接(Bridge)
“8号选手向我们走来,组合小姐,一个非常美丽的姑娘,她的口号是将对象组合成树形结构以表示‘部分-整体’的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。[DP]”
8号选手 组合(Composite)
“9号选手,装饰小姐,她的意图非常简单,就是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活[DP]。的确,她把自己装饰得非常漂亮。”
9号选手 装饰(Decorator)
“10号选手出现了,外观小姐,她的形象如她的名字一样的棒,她说为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。[DP]”
10号选手 外观(Facade)
“11号选手是享
11号选手 享元(Flyweight)
“本组了最后一位,12号选手,代理小姐向我们走来,她声称为其他对象提供一种代理以控制对这个对象的访问。[DP]”
12号选手 代理(Ptoxy)
观众席中的ADO.NET和Hibernate又开始了讨论。
Hibernate:“C#休闲装我不喜欢,还是Java正装漂亮。”
ADO.NET:“哈,你这么正儿八经的人,当然是不喜欢休闲装,你兄弟NHibernate一定喜欢得不得了,我也是喜欢休闲装的。”
Hibernate :“这一组够强,没有太弱的,你感觉谁最有机会?”
ADO.NET:“不好说,都很漂亮的,各自有各自的特点,你认为呢?”
Hibernate :“我喜欢桥接,太漂亮了,那种解耦的方式,用聚合来代替继承,实在是非常巧妙。”
ADO.NET:“是的,桥接很漂亮,不过装饰也非常美丽。由于善于打扮,所以她可以很好地展示其魅力。”
Hibernate :“说得也是,装饰好歹也是靠化妆自己展示好看,而代理那个小妮子,听说她甚至有可能就不是自己来参加比赛,而是找了一替身。”
ADO.NET:“啊,不会吧,这种谣传你也会信呀,找人替身,那出了名算谁的?”
Hibernate :“当然还是她自己,大牌明星都这样的,找了替身做了很多,最后可能连替身名字都不让人家知道。”
ADO.NET:“代理要是大牌就不用来参加比赛了,出名前一切还是只有靠自己的。说心里话,我最喜欢的是适配器小姐。”
Hibernate:“哦,为什么喜欢她?她好像并不算漂亮。”
ADO.NET:“因为她对我的帮助最大,我在访问不同的数据库,如SQL Server、Oracle或者DB2等时,需要将数据结构和数据都转化成XML格式给DataSet,DataAdapter就是适配器,没有她的帮助,我的DataSet就发挥不了作用,真的很感激她。”
Hibernate:“哈,原来是恩人呀,打小认识的?青梅竹马?哈,好像就你认识她一样,我也和她是老相好哦。”
ADO.NET:“你就吹吧你,之前也听你说你和抽象工厂是相好,现在又和适配器相好,你的相好真够多的。”
Hibernate:“不信拉倒。我们不如来打赌吧,我赌10块钱,桥接会赢。”
ADO.NET:“瞧你那小气样,我赌100元,适配器会赢。”
Hibernate:“100就100,Who怕Who呀。”《大话设计模式》
“下面有请评委提问。”主持人GOF说。
“请问适配器小姐,刚才记者提到你有成功的杀手锏,那是什么呢?”开放
“杀手锏?”适配器心里一咯噔,心想,“那记者太不道义了,我明明没有回答她的问题,怎么就断章取义地说我有杀手锏呢?造谣呀。”犹豫了一下,她说道,“我所谓的杀手锏是说,面向对象的精神就是更好地应对需求的变化,而现实中往往会有下面这些情况,想使用一个已经存在的类,而它的接口不符合要求,或者希望创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作。正如开放
开放封闭不住地点头。
“桥接小姐,面对变化,你是如何做的?”合成聚合复用问道。
桥接答道:“继承是好的东西,但往往会过度地使用,继承会导致类的结构过于复杂,关系太多,难以维护,而更糟糕的是扩展性非常差。而仔细研究如果能发现继承体系中,有两个甚至多个方向的变化,那么就解耦这些不同方向的变化,通过对象组合的方式,把两个角色之间的继承关系改为了组合的关系,从而使这两者可以应对各自独立的变化,事实上也就是合成聚合复用女士所提倡的原则,总之,面对变化,我主张‘找出变化并封装之’。[DPE]”
“这个问题也同样提问给装饰小姐,面对变化,你如何做?”合成聚合复用接着问装饰。
装饰显然对此问题很有信心,答道:“面对变化,如果采用生成子类的方法进行扩充,为支持每一种扩展的组合,会产生大量的子类,使得子类数目呈爆炸性增长。这也是刚才桥接小姐所提到的继承所带来的灾难,而事实上,这些子类多半只是为某个对象增加一些职责,此时通过装饰的方式,可以更加灵活、以动态、透明的方式给单个对象添加职责,并在不需要时,撤销相应的职责。[DP]”
“组合小姐,我们通过你的材料,了解到你最擅长于表示对象的部分与整体的层次结构。那么请问,你是如何做到这一点的?”里氏代换问道。
组合答道:“我是希望用户忽略组合对象与单个对象的不同,用户将可以统一地使用组合结构中的所有对象。”组合回答道,“用户使用组合类接口与组合结构中的对象进行交互,如果接收者是一个叶节点,则直接处理请求,如果接收者是组合对象,通常将请求发送给它的子部件,并在转发请求之前或之后可能执行一些辅助操作。组合模式的效果是客户可以一致地使用组合结构和单个对象。任何用到基本对象的地方都可以使用组合对象。[DP]”
一直没有提过问题的迪
外观小姐有些紧张,停顿了一会,然后缓缓答道,“类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。如果两个类不必彼此直接通信,那么就不要让这两个类发生直接的相互作用。如果实在需要调用,可以通过第三者来转发调用。[J&DP]”
“那你又是如何去贯彻这一原则呢?”迪米特继续问道。
“我觉得应该让一个软件中的子系统间的通信和相互依赖关系达到最小,而具体办法就是引入一个外观对象,它为子系统间提供了一个单一而简单的屏障[DP]。通常企业软件的三层或N层架构,层与层之间地分离其实就是外观模式的体现。”外观小姐说话很慢,但显然准备过,并没说错什么。迪米特满意地点了点头。
“享
“对象使得内存占用过多,而且如果都是大量重复的对象,那就是资源的极大浪费[DP],会使得机器性能减慢,这个显然是不行的。”享元说,“面向对象技术有时会因简单化的设计而代价极大。比如文档处理软件,当中的字符都可以是对象,而如果让文档中的每一个字符都是一个字符对象的话,这就会产生难以接受的运行开销,显然这是不合理也是没必要的。由于文档字符就是那么些字母、数字或符号,完全可以让所有相同的字符都共享同一个对象,比如所有用到‘a’的字符的地方都使用一个共享的‘a’对象,这就可以节约大量的内存。”
“OK,最后一位,代理小姐,请对比一下你
代理没有想到会问这样一个问题,而旁边就站着外观和适配器,如果说得不好,显然就是很得罪人的事,她思考了片刻,说道:“代理与外观的主要区别在于,代理对象代表一个单一对象而外观对象代表一个子系统;代理的客户对象无法直接访问目标对象,由代理提供对单独的目标对象的访问控制,而外观的客户对象可以直接访问子系统中的各个对象,但通常由外观对象提供对子系统各元件功能的简化的共同层次的调用接口。[R2P]”代理停了一下,然后接着说,“至于我与适配器,其实都是属于一种衔接性质的功能。代理是一种原来对象的代表,其他需要与这个对象打交道的操作都是和这个代表交涉。而适配器则不需要虚构出一个代表者,只需要为应付特定使用目的,将原来的类进行一些组合。[DP]”《大话设计模式》
“下面有请六位评委写上您们认为表现最好的模式小姐。”GOF说道。
桥接
适配器
外观
适配器
桥接
外观
“哦,各位来宾,观众朋友们,第二场结构型模式的比赛真是相当精彩,各位选手也都实力相当,难分伯仲,现在出现了‘桥接’、‘适配器’、‘外观’的比分均为两分的相同情况。根据比赛规则,她们三位需要站上PK台,进行PK。三位有请。”
“下面请三位各自说一说你比其他两位优秀的地方。适配器小姐先来。”