《大话设计模式》第29章-OOTV杯超级模式大赛—模式总结(二)
接上篇《大话设计模式》第29章-OOTV杯超级模式大赛—模式总结(一)
“下面宣布一下比赛规则。”GOF的声音再次响起,“本次大赛根据模式的特点,设置了三个类别,分别是创建型模式、结构型模式和行为型模式,但由于有11位选择了行为型模式,人数过多,所以行为型模式又分为了两组。也就是说,我们将选手共分为了四组,所有的选手都将首先参加分组比赛,每组第一名将参加我们最终设计模式冠军的争夺。选手的分组情况,请看大屏幕。”
“下面我们就有请,单一职责先生代表评委宣誓。”
此时,几位评委站了起来,单一职责先生拿起事先写好的稿子,缓慢地说道:“我代表本届大赛全体评委和工作人员宣誓:恪守职业道德,遵守竞赛规则。严格执法,公正裁判,努力为参赛选手提供良好的比赛氛围和高效优质服务,维护公正的评委信誉。为保证大会的圆满成功,做出我们应有的贡献!宣誓人:单一职责。”
“宣誓人:开放封闭”
“宣誓人:依赖倒转”
……
“下面有请策略模式小姐代表参赛选手宣誓。”
“为了展示面向对象的优点和思想,为了编程的光荣和团队的荣誉,我代表我们全体参赛选手,将弘扬‘可维护、可扩展、可复用、灵活性好’的OO精神,严格遵守赛事活动的各项安排,遵守比赛规则和赛场纪律,尊重对手,团结协作,顽强拼搏,赛出风格,赛出水平,胜不骄,败不馁,尊重裁判,尊重对方,尊重观众。并预祝大赛圆满成功。”《大话设计模式》
29.4 创建型模式比赛
“现在比赛正式开始,有请第一组参赛选手入场,并进行综合形象展示。”
“第一组创建型选手,他们身穿的是Java正装进行展示。”
“1号选手,抽象工厂小姐,她的口号是提供一个创建一系列或相关依赖对象的接口,而无需指定它们具体的类。[DP]”
1号选手 抽象工厂(Abstract Factory)
“2号选手,建造者小姐,她的口号是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。[DP]”
2号选手 建造者(Bulider)
“3号选手工厂方法小姐向我们走来,她声称定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。[DP]”
3号选手 工厂方法(Factory Method)
“4号选手是原型小姐,她的意图是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。[DP]”
4号选手 原型(Prototype)
“5号选手出场,单例小姐,她提倡简捷就是美,保证一个类仅有一个实例,并提供一个访问它的全局访问点。[DP]”
5号选手 单例(Singleton)
此时只见场下一帮Fans开始热闹起来。
简单工厂带领着抽象工厂和工厂方法的粉丝们开始齐唱,“咱们工厂有力量,嗨!咱们工厂有力量!每天每日工作忙,嗨!每天每日工作忙,……哎!嗨!哎!嗨!为了咱程序员彻底解放!”
“单例单例,你最美丽,一人创建,全家获益。”单例的Fans同样不甘示弱地喊着口号。
观众席中还有两位先生安静地坐在那里,小声地聊着。
“你猜谁会胜出?”ADO.NET对旁边的Hibernate说。
“我觉得,抽象工厂可以解决多个类型产品的创建问题,就我而言,同一对象与多个数据库ORM就是通过她来实现的。我觉得她会赢。”Hibernate坚定地说。
“你也不看看,抽象工厂那形象,多臃肿呀,身上类这么多。做起事来一定不够利索。”ADO.NET不喜欢抽象工厂。
“那你喜欢单例?”Hibernate问道。
“单例又太瘦了。过于骨感也不是美。我其实蛮喜欢原型那小姑娘的,我的DataSet只要调用原型模式的Clone就可以解决数据结构的复制问题,而Copy则不但复制了结构,连数据也都复制完成,很是方便。”
“那你不觉得建造者把建造过程隐藏,一个请求,完整产品就创建,在高内聚的前提下使得与外界的耦合大大降低,这不也是很棒的吗?”
“问题是又有多少产品是相同的建造过程呢?再说回来,你造什么对象,不还是需要new吗?”
“哈,从new的角度讲,工厂方法才是最棒的设计,它可是把工厂职责都分了类了,其他几位不过是她的变体罢了。”
“有点道理,看来创建型这一组,工厂方法有点优势哦。”《大话设计模式》
“下面有请评委提问。”主持人GOF待五位选手出场亮相之后接着说。
“请问抽象工厂小姐,为什么我们需要创建型模式?”开放-封闭先生问道。
只见抽象工厂思考了一下,说道:“我觉得创建型模式隐藏了这些类的实例是如何被创建和放在一起,整个系统关于这些对象所知道的是由抽象类所定义的接口。这样,创建型模式在创建了什么、谁创建它、它是怎么被创建的,以及何时创建这些方面提供了很大的灵活性[DP]。”
“请问原型小姐,你有什么补充?”依赖倒转对着原型问道。
原型显然没想到突然会问到她,而且对于这个问题,多少有点手足无措,她说:“当一个系统应该独立于它的产品创建、构成和表示时,应该考虑用创建性模式。建立相应数目的原型并克隆它们通常比每次用合适的状态手工实例化该类更方便一些[DP]。”
“哈,这可能是我们需要原型的理由。”依赖倒转说道,然后转头问建造者,“请谈谈你对松耦合的理解。”
建造者对这个问题一定是有了准备,不慌不忙,说道:“这个问题首先要谈谈内聚性与耦合性,内聚性描述的是一个例程内部组成部分之间相互联系的紧密程度。而耦合性描述的是一个例程与其他例程之间联系的紧密程度。软件开发的目标应该是创建这样的例程:内部完整,也就是高内聚,而与其他例程之间的联系则是小巧、直接、可见、灵活的,这就是松耦合[DPE]。”
“那么你自己是如何去实践松耦合的呢?”依赖倒转接着问。
“我是将一个复杂对象的构建与它的表示分离,这就可以很容易地改变一个产品的内部表示,并且使得构造代码和表示代码分开。这样对于客户来说,它无需关心产品的创建过程,而只要告诉我需要什么,我就能用同样的构建过程创建不同的产品给客户[DP]。”
“回答得非常好,现在请问单例,你来说说看你参赛的理由,你与别人有何不同?”单一职责问道。
单例小姐有些羞涩,停了一会,才开口说:“我觉得对一些类来说,一个实例是很重要的。一个全局变量可以使得一个对象被访问,但它不能防止客户实例化多个对象。我的优势就是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且我还提供了一个访问该实例的方法。这样就使得对唯一的实例可以严格地控制客户怎样以及何时访问它[DP]。”
“工厂方法,请问你如何理解创建型模式存在的意义?”合成聚合复用问道。
此时只听场下一声音叫道,“二姐加油”,原来简单工厂在观众席上喊叫呢。工厂方法对着观众席微笑了一下,然后非常有信心地答道,“创建型模式抽象了实例化的过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。创建型模式都会将关于该系统使用哪些具体的类的信息封装起来。允许客户用结构和功能差别很大的‘产品’对象配置一个系统。配置可以是静态的,即在编译时指定,也可以是动态的,就是运行时再指定。[DP]”
“那么请问你与其他几位创建型模式相比有什么优势?”
“我觉得她们几位都可能设计出比我更加灵活的代码,但她们的实现也相对就更加复杂。通常设计应该是从我,也就是工厂方法开始,当设计者发现需要更大的灵活性时,设计便会向其他创建型模式演化。当设计者在设计标准之间进行权衡的时候,了解多个创建型模式可以给设计者更多的选择余地。[DP]”
几位评委都在不住地点头,显然,他们非常肯定工厂方法的回答。《大话设计模式》
“下面有请几位评委写上您们认为表现最好的模式小姐。”GOF说道。
“单一职责先生,您的答案是?”
只见单一职责翻转纸牌,上面写着“单例”。
“非常好,单例小姐已有一票。”
“开放封闭先生,您的选择是?”
“工厂方法。我觉得工厂方法能使得我们增加新的产品时,不需要去更改原有的产品体系和工厂类,只需扩展新的类就可以了。这对于一个模式是否优秀是非常重要的判断标准,我选择她。”开放封闭说道。
“OK,工厂方法小姐也有一票了。”
……
“工厂方法小姐再加一票。”
……
“工厂方法小姐一共有五票。成功晋级,恭喜你。”GOF宣布完,只见工厂方法抱住了旁边的抽象工厂泪流满面,喜极而泣。下面的简单工厂和一帮工厂方法的小Fans们欢呼雀跃。而其他模式的Fans们低头不语,个别竟然已潸然泪下。
“好的,各位来宾,观众朋友们,第一场的比赛现在结束,工厂方法成功晋级,但其他四位选手并不等于没有机会,希望您能通过浏览器给她们投票,IE用户,请发送OO加选手编号到www.ootv.com,Firefox用户请发送OO加选手编号到www.ootv.net,其他浏览器用户请发送OO加选手编号到www.ootv.org,您的支持将是对落选选手的最大鼓励,最终获得票数最多者同样可以进级决赛。下面休息一会,插播一段广告。”
ADO.NET开始发牢骚:“什么最大鼓励,根本就是电视台在骗钱。”
“你不发拉倒,我可要给抽象工厂投上一票了。”Hibernate说道。
“嗨,算了,反正也就一元钱,我给原型投上一票。”
“哥们,原型没戏了,投抽象工厂吧,这样她进级了,你的钱也不白花。”
“呸,你怎么知道抽象工厂会比原型的票数多,大家都不投她,她能成功吗?我不但投原型,而且要投她十五张票(最高限额)。”ADO.NET坚持道。
“我碰到神经病了。你去打水漂去吧,我不陪你。”《大话设计模式》
(未完待续)