《妙趣横生设计模式.docx》由会员分享,可在线阅读,更多相关《妙趣横生设计模式.docx(159页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、妙趣横生设计模式目录针对接口编程-问世间情为何物直教人生死相许3单一职责原则乔峰VS慕容复10开放封闭原则孙悟空任弼马温一职17里氏代换原则法海捉拿白蛇新解24迪米特法则慈禧太后为何不和陌生人说话29合成聚合复用原则刘邦VS韩信35简单工厂模式 一见钟情的代价44工厂方法模式 让麦当劳的汉堡适合不同MM的不同口味52抽象工厂模式 MM的生日59单例模式 你是我的唯一69原型模式 肉麻情话76建造者模式让我们同居吧!82装饰模式见MM的家长87外观模式MM也迷恋炒股?94享元模式短信可以这样发99适配器模式笔记本电脑的适配器105代理模式QQ聊天机器人110桥接模式最重要的是有一颗让MM快乐的心
2、115组合模式MM的生日礼物121模板方法模式人的一生应该这样度过128观察者模式GG在MM身边有两个妹妹134状态模式140策略模式141职责链模式154 建造者模式 让我们同居吧! 装饰模式 见MM的家长 外观模式 MM也迷恋炒股? 享元模式 短信可以这样发 适配器模式 笔记本电脑的适配器 代理模式 QQ聊天机器人 桥接模式 最重要的是要有一颗让MM快乐的心 组合模式 MM的生日礼物 模板方法模式 人的一生应该这样度过 观察者模式 GG在MM身边有两个妹妹 状态模式 在一天的不同时间要给MM发不通的短信 策略模式 帮助MM选择商场打折策略 职责链模式 帮助MM选择商场打折策略 统一建模语言
3、UML简介和StarUML使用针对接口编程-问世间情为何物直教人生死相许 应用场景举例: “十六年后 在此重会;夫妻情深 勿失信约”,悲痛欲绝的杨过跑到断肠崖,看到小龙女亲手留在石壁上的文字,即惊喜又痛苦不欲生:“十六年!为什么要等到十六年?!”。 但是信约已定,痴情的杨过也只能等十六年了。 离开断肠崖后,杨过一边开始了自己的苦苦的等待与思恋,一边寄情练功,当然开始时候也忘不了吃那疗伤的草药。后来杨过巧遇了千年神雕,和神雕一见如故,从此便开始修炼独孤求败的武功。无事可做,寄情练剑倒也不失为人生的一大快事。“相思无用,唯别而已。别期若有定,千般煎熬又何如?莫道黯然销魂,何处柳暗花明?!”,惊天地
4、泣鬼神的黯然销魂掌就这样诞生了。时光飞逝,恍惚间快过了十六年。此时,杨过的神功已成,想象着十六年约期就将来临,心中想象着自己一生的挚爱,不免感慨和激动万分!在祭拜过求败他老人家之后,杨过和神雕一起开始去赴那场长达十六年之久的约会。令众生激动和艳羡。 再出江湖的杨过惩奸除恶、帮扶弱小,很快就侠名远播,被人尊称为“神雕侠”。自己心中想象着小龙女过往的一笑一颦,想象着她是怎么度过这十六年的,不禁催生了更加浓烈的相思和相见之情。 千呼万唤,终于,这一天来到! 断肠崖边,佳人芳踪迹未现,过儿万念俱灰,纵身跳下悬崖 幸好悬崖下面是深渊,杨过并没有死,被水冲到了岸边的杨过苏醒过来后,看到了很多小蜜蜂,他一眼
5、就认出了这是小龙女样的蜜蜂,莫非龙儿就在附近?最后在深潭水下,杨过找到了自己苦苦等待了十六年的挚爱。原来小龙女得知自己无药可救,也纵身跳下断肠崖,十六年之期只不过是为了让杨过不要轻生。但是跳崖后的小龙女并没有死掉,接着就在谷底一个世外桃源的地方慢慢的疗伤,竟然完全康复了。真是有情人终成眷属,有情人终成名人。 定义: 接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 接口是对抽象的抽象。 接口就是标准,就是承诺。 针对接口编程,不要针对具体编程是依赖倒转原则的另外一种表述。 针对
6、接口编程又称为面向接口编程,针对接口编程就是要先设计一系列的接口,把设计和实现分离开,使用时只需引用接口即可,也由于系统各部分的解耦合。如下图所示: 故事分析: “十六年后 在此重会;夫妻情深 勿失信约”就是针对接口编程的一个绝妙的例子。而且最后还加了“信约”一次。言外之意就是说我们说好了要十六年在此地重逢,我们俩都要遵照此约定。根据上面的故事,小龙女和杨过制定好接口后,就纵身跳下了悬崖,不管自己的过儿了,因为她此时已经不用关心过儿怎么去再十六年后河自己相见,只要十六年后在此地相见即可,也就是说小龙女针对和使用都是接口,至于杨过怎么实现,她此时已经身患绝症而无法顾及了。而杨过看过此约定后,虽然
7、无奈,但也只好照办。具体实现如下:回去吃断肠草调理自己,然后以神雕为伴练习武功,知道练成了黯然销魂掌而神功大成,然后就是在江湖上做侠义之事,然后就是按照信约与十六年后来到断肠崖边;而小龙女就在谷底慢慢的调养,十六年后身体早已康复,而且越发迷人了。当杨过没有见到小龙女时纵身跳崖,遵照了“问世间情为何物,直教人生死相许”标准。 总结一下:小龙女和杨过定下接口,然后各自针对接口各自独立的做事,最终得以相见。 针对接口编程是未来提高程序的可维护性、可伸缩性和可复用性。如果你在一个类中直接使用另外的一个,这样就把两个类紧密的联系在了一起,以后如果想做出改变就很难了。如果针对接口编程,当业务变化时我们只需
8、要用一个新的类实现接口即可,而客户端依旧可以使用接口引用新的类的,同时也保证了客户端的不变性。这样客户端和实现端互不影响,保持了各自的相对独立性。正如小龙女和杨过的,他们树立了十六年制约后,就不用关心彼此的如何去赴这场约定,只需要按照约定做事就OK了。互不影响,自由在在。如下图所示: Java代码实现: 新建一个“信约”的接口,这个接口是杨过和小龙女都必须通过自己的方式实现的。代码如下:packagecom.diermeng.designPattern.dating;/* 杨过和小龙女定下的约定接口*/publicinterfaceDating /* * 约定的接口 */publicvoidd
9、ating(); 然后分别建立杨过和小龙女的实现类,分别实现上面的接口。代码依次如下:packagecom.diermeng.designPattern.dating.impl;importcom.diermeng.designPattern.dating.Dating;/* 杨过对接口的实现*/publicclassYangguoimplementsDating /* * 姓名 */ String name; /* * 默认空构造方法 */publicYangguo() /* * 传入name参数的构造方法 */publicYangguo(String name) this.name = n
10、ame; publicString getName() returnname; publicvoidsetName(String name) this.name = name; /* * (non-Javadoc) * see com.diermeng.dating.inter.Dating#dating() * 杨过对约定的实现 */publicvoiddating() if(this.getName()!=null) System.out.println(this.getName()+ : +十六年后 在此重会;夫妻情深 勿失信约); else System.out.println(十六年
11、后 在此重会;夫妻情深 勿失信约); packagecom.diermeng.designPattern.dating.impl;importcom.diermeng.designPattern.dating.Dating;/* 小龙女对接口的实现*/publicclassXiaoLongnvimplementsDating /* * 姓名 */ String name; /* * 默认空构造方法 */publicXiaoLongnv() /* * 传入name参数的构造方法 */publicXiaoLongnv(String name) this.name = name; publicStr
12、ing getName() returnname; publicvoidsetName(String name) this.name = name; /* * (non-Javadoc) * see com.diermeng.dating.inter.Dating#dating() * 小龙女对约定的实现 */publicvoiddating() if(this.getName()!=null) System.out.println(this.getName()+ : +十六年后 在此重会;夫妻情深 勿失信约); else System.out.println(十六年后 在此重会;夫妻情深 勿
13、失信约); 建立一个测试类,代码如下:packagecom.diermeng.designPattern.dating.client;importcom.diermeng.designPattern.dating.Dating;importcom.diermeng.designPattern.dating.impl.XiaoLongnv;importcom.diermeng.designPattern.dating.impl.Yangguo;/* 对杨过和小龙女约定进行测试的客户端*/publicclassDatingTest publicstaticvoidmain(String args)
14、 /分别实例化实例化 Dating yangguo =newYangguo(过儿); Dating xiaoLongnv =newXiaoLongnv(龙儿); /调用各自的方法 yangguo.dating(); xiaoLongnv.dating(); 程序运行结果如下:过儿 : 十六年后 在此重会;夫妻情深 勿失信约龙儿 : 十六年后 在此重会;夫妻情深 勿失信约 已有应用简介: Java是相面对象编程的语言,而面向对象编程的核心之一就是要针对针对接口编程、不要针对实现编程,在Java API中的标志接口java.io.Serializable和java.rmi.Remote等就是我们经
15、常遇到的,下面以java.io.Serializable为例说明一下,源代码如下:package java.io;public interface Serializable UML图形如下图所示: 当然在J2EE框架的使用中到处都是针对接口编程的身影。例如在中几乎每一处都是针对接口编程的,令人印象非常深刻的一点就是巴巴运动网把对数据库的CRUD等基本操作封装在了一个统一接口中,这给以后的代码的编写和数据库的操作带来了极大的方便,当然这里也使用了Java 5的泛形技术。有兴趣的读者可以去学习巴巴运动网的源代码。 温馨提示: 许下的承诺就是欠下的债。所以不要轻易做出承诺。 杨过和小龙女为了承诺而付
16、出了十六年的努力。 在软件设计和编码中,如果确立了接口,也就对客户做出了承诺,这种承诺几乎没有改变的机会,时间越长越是如此,因为那是别人对你接口的使用已经遍布世界各地,当然前提是你的借口很出色,这样才能取得很多人的信赖和消费。 不要轻易说:“我爱你“,因为这是一生的承诺。单一职责原则乔峰VS慕容复 应用场景举例: 江湖盛传:北乔峰,南慕容。 少室山下,天下群雄云集。 “你们一起来吧,我萧峰何惧!”,一声豪情和怒吼,乔峰卷入了和慕容复、游坦之、丁春秋一决生死之战。乔峰果然不愧是天下第一豪侠,以一敌三,你来我往,打得不可开交。乔峰使出了降龙十八掌中的“亢龙有悔”,此时慕容复忙往后退,情急之下,使出
17、了自己的绝技“游龙引凤”来化解乔峰如此强烈的进攻,此时慕容复双腿选在了亭子的柱子上,王语嫣心想:“表哥使用游龙引凤自然是不会败的了,可是面对天下众英雄的面,竟然和游坦之、丁春秋等这样的人联手对付大英雄乔峰,这也有些太不公平了,表哥,你在想些什么啊?”。此时被乔峰手下保护的段誉心急如焚,心想,这个不行,唯恐大哥有什么意外,毕竟总是乔峰神功盖世,眼前面对也是江湖上一流的高手,这样下去如何是好?突然,段誉挣脱众人的包括冲了上来,对慕容复使用激将法说:“你们两个打一个算什么英雄好汉,慕容复,有本事来和我单打啊!”。慕容复本来就对段誉一直以来对王语嫣的爱慕之意深表不满,又被他这么一激怒,怒声到:“找死!
18、”,就像段誉扑来。此时段誉以从神仙姐姐那里学来的“凌波微步”的奇功和慕容复纠缠。此时,虚竹正在和收拾丁春秋。而乔峰正在迎战游坦之,游坦之虽然练成了很毒辣的武功,但也绝非是乔峰的对手,数招之内便被乔峰从塔顶扔了下来,结果弄到一个腿部骨折而惨败的下场!段誉白在慕容复的剑下,宁死不屈。慕容复正欲一剑了解了段誉,段正淳喝道:“休伤我儿!”挡住了慕容复的剑。慕容复非常恼怒,数招之内就把慕容复打伤在地。眼看慕容复就要杀死自己父亲,躺在地上的段誉“啊”的一声使出了大理国的绝学“六脉神剑”,几招之内,慕容复惨败,正要进一步进攻时,此时他的梦中情人王语嫣柔声叫到:“段公子手下留情啊”,这段誉,一听到王语嫣的声音
19、,就神魂颠倒、不知所以了,慕容复乘此机会偷袭段誉,乔峰见状,一边喝道:“三弟小心”,一边瞬间出手,粉碎了慕容复的武器,慕容复还没反应过来,就已经被乔峰高高举起在了半空中,乔峰喝道:“我萧峰大好男儿,岂能与你这等小人齐名”,随即把慕容复恨恨的抛了出去!慕容复在天下英雄面前惨败,自觉颜面无常,欲拔剑自刎,被灰衣人阻拦 定义: 单一职责原则(Single Responsibility Principle ):就一个类而言,应该仅有一个引起它变化的原因。换句话说,一个类的功能要单一,只做与它相关的事情。 如果一个完成额外的不太相关的功能或者完成其它类的功能,这就会使得一个引起一个类变化的因素太多,如果
20、类的一处需要修改,其它和它相关连的代码都会受到影响,这就直接导致一旦系统出现了问题就难以调试困境,同时这样也非常不利于维护。 遵循单一职责原则也会给测试带来极大的方便。 违背单一职责原则会降低类的内聚性、增强类的耦合性。 违背单一职责原则会导致错误呈现几何级数的增长,因为类之间的关联性太强,每一个类都会对其他类有影响,一个类出现错误极可能会导致其他相关联的类出现错误,而且关联类联合起来还有可能产生新的错误。 在软件开发中,人们越来越意识到单一职责原则的重要性,美工只需要负责美工界面,业务层的人员只需写好业务代码,而数据层的人员只需关注数据层的工作即可。这样每个人都以自己专程协同工作,工作效率就
21、得到了大大的提高了。 现在软件开发的经典模式MVC模式,也非常好的体现了单一职责原则。MVC(Model-View-Control)就是模型、视图、控制器三层架构模式,其中M是指数据模型、V是指用户界面、C则是控制器。采用MVC模式使得数据和表现相分离,同一个数据层可以有不同的显示层。数据层和显示层的改变互不影响。这就非常有利于提高软件的可维护性和可复用性,同时也方便了软件的管理工作和提高软件开发效率。 如下图所示: 故事分析: 有王语嫣这个武学博士相助,同时集天下几乎所有武学与一身“以彼之道,还施彼身”的慕容复却输了,输给了懂得六脉神剑的段誉,也输给了用降龙十八掌打遍天下的乔峰。抛开其它的原
22、因不谈,慕容复之所以会输,是因为他虽然懂得很多武功,甚至懂得天下几乎百分之八十以上的武功,但是因为复国心切,确很少做到能够精通;从另外一个角度讲,也是修炼这么多武功害了慕容复。你想啊,一个年纪轻轻的人修炼这么多武功,怎么可能有时间去把每种武功都精通呢,而且还会累的要死。其实,慕容复就像一匹狼一样,面对着一大群样,想把每一个都吃掉!结果是可能基本咬死了每一只羊,却无暇去好好品尝和消化。而段誉和乔峰就不一样了。段誉会六脉神剑。这里我们主要分析一下乔峰。乔峰自幼被少林寺收养,刻苦勤奋,潜心修炼降龙十八掌,直至到达无招胜有招的地步。当然乔峰这样的真英雄、大豪杰自然是实战经验丰富的。就这样,当“以彼之道
23、,还施彼身”的慕容复遇到了用降龙十八掌打遍天下无敌手的乔峰是,慕容复输了。 从设计原则的角度考虑,慕容复输是因为他违背了单一职责原则,他把太多的精力分散于各种武学之中,他迷失在了武学之中。当然,不可否认,慕容复确实是年轻有为的武学天才。但是临阵实战的时候讲究的是你真正的实力,而不是以懂得的武功的多少决定胜负的。修炼太多的武功种类必然让人太累,而且非常容易走火入魔。这就像吃饭一样,吃了太多未必是什么好事,而且几乎肯定不是好事。这是因为,一方面吃了太多,对自己的消化系统和身体都不好,容易发胖等;另外一方面讲,吃的多不一定消化的多,而且很多时候反而削弱消化能力,因为吃的太多带来了太多的负担,影响了消
24、化系统的功能。而乔峰就不一样了,他在打好基础的情况,专注于降龙十八掌,直到能够随心所欲、运用自如。当然乔峰这样的盖世豪侠对武功本质的和武功精髓的理解也是高于慕容复的。而且,乔峰还有一个特定,就是遇强则强、越战越勇。 单一职责原则告诉我们,一个类应该只有一个引起该类变化的原因。这样有利提高类的可维护性和可复用性。如果把乔峰和慕容复比作两个类的话,引起乔峰变化的就是降龙十八掌,而且乔峰把降龙十八掌做到了极致,无论是敌是友,乔峰都可以用降龙十八掌化解。而慕容复呢,引起他变化的原因就太多了,虽然“以彼之道,还施彼身”几乎令所有江湖人士都敬畏三分,但是因为多而不精,遇到像乔峰这样的高手后,恐怕就无法“以
25、彼之道,还施彼身”了。 这里,我们把乔峰的降龙十八掌看做是乔峰的方法,而慕容复懂的武功也看作慕容复拥有的方法,建模的图形如下: Java代码实现: 乔峰的类:packagecom.diermeng.designPattern.SRP;/* 乔峰*/publicclassQiaofeng /* * 姓名 */ String name; /* * 无参构造方法 */publicQiaofeng() /* * 带参数的构造方法 */publicQiaofeng(String name) this.name = name; publicString getName() returnname; publ
26、icvoidsetName(String name) this.name = name; /* * 乔峰的功夫绝技展现 */publicvoidgongfu() if(this.getName()!=null) System.out.println(我是+this.getName()+ 使用降龙十八掌,无论是敌是友我都可以应对自如,这都要感谢我遵循了单一职责原则!); else System.out.println(使用降龙十八掌,无论是敌是友我都可以应对自如,这都要感谢我遵循了单一职责原则!); 慕容复的类图:packagecom.diermeng.designPattern.SRP;/*
27、慕容复*/publicclassMuRongfu /* * 姓名 */ String name; /* * 无参构造方法 */publicMuRongfu() /* * 带参数的构造方法 */publicMuRongfu(String name) this.name = name; publicString getName() returnname; publicvoidsetName(String name) this.name = name; /* * 慕容复的功夫展现 */publicvoidgongfu() if(this.getName()!=null) System.out.pri
28、ntln(我是+this.getName()+ 我会很多武功,对绝大多数人来说我都可以做到以彼之道还施彼身,但是如果遇到乔峰这样的高手,我就Over了,这都是没有遵循单一职责原则惹的祸!); else System.out.println( 我会很多武功,对绝大多数人来说我都可以做到以彼之道还施彼身,但是如果遇到乔峰这样的高手,我就Over了,这都是没有遵循单一职责原则惹的祸!); 建立一个测试类,代码如下:packagecom.diermeng.designPattern.SRP.client;importcom.diermeng.designPattern.SRP.MuRongfu;imp
29、ortcom.diermeng.designPattern.SRP.Qiaofeng;publicclassGongfuTest /* *paramargs */publicstaticvoidmain(String args) Qiaofeng qiaofeng =newQiaofeng(乔峰); MuRongfu muRongfu =newMuRongfu(慕容复); qiaofeng.gongfu(); muRongfu.gongfu(); 程序运行结果如下:我是乔峰 使用降龙十八掌,无论是敌是友我都可以应对自如,这都要感谢我遵循了单一职责原则!我是慕容复 我会很多武功,对绝大多数人来说
30、我都可以做到以彼之道还施彼身,但是如果遇到乔峰这样的高手,我就Over了,这都是没有遵循单一职责原则惹的祸! 已有应用简介: 我们这里已经以MVC模式为例来分析单一职责原则的应用。 模型车、视图层、控制层各司其责、相互独立,一个模型可以有多个视图,一个视图可以有多个控制器,同样的一个控制器也可以由多个模型。MVC基本的处理流程如下: 用户与视图交互,视图接受并反馈用户的动作;视图把用户的请求传给相应的控制器,有控制器决定调用哪个模型,然后由模型调用相应的业务逻辑对用户的请求进行加工处理,如果需要返回数据,模型会把相应的数据返回给控制,由控制器调用相应的视图,最终由视图格式化和渲染返回的数据,以
31、一种对用户尽可能友好的方式展现给用户。 温馨提示: 专注于一件事情,专注于一切事情。 如果这个世界每个人都专注于做一件事情,并把这件事情做到极致,世界会是怎样的一种和谐美好呢? 遵循单一职责原则的乔峰使少林寺的扫地僧也不禁发出感叹:“降龙十八掌果然天下第一!” 树立一个高远的目标,然后拼尽一切力量的去实现这个目标。 愿单一职责原则保佑您! 注意:该文档参考和使用了网络上的免费开放的图片和内容,并以免费开放的方式发布,希望为移动互联网和智能手机时代贡献绵薄之力!可以随意转载,但不得使用该文档谋利。开放封闭原则孙悟空任弼马温一职 应用场景举例: 孙悟空从东海龙宫拿到定海神针如意金箍棒后回到花果山,
32、和自己的部下过着自由自在的生活。那只好景不长,因为他在地狱删除了自己和花果山所有猴子的名单,同时又拿走了定海神针,不久便被阎王和龙王告上了天庭。玉帝正要下旨去捉拿妖猴问罪。忙被龙王劝止,龙王说孙悟空神通广大,阎王也深表赞同。玉帝有些迟疑,问众仙该如何是好,太白金星说不如封他一个天宫中的官职去做,这样明为封官,实际上在暗地里确进行压制。玉帝深表赞同。但是要封孙悟空一个什么官好呢?玉帝也一时想不出什么号的职位,于是就宣仙卿百官入朝,共同商讨此事。玉帝问道:“众爱卿,现在天庭什么地方可以空缺的职位啊?给那妖猴一个官去做。”众人都说现在天庭的各个职位人说爆满,无任何空缺职位。大家一时之间不知道该如何是
33、好,此事太白金星灵机一动,向玉帝禀报道:“禀报玉帝,鉴于天庭个职位人员爆满,不如封他一个弼马温的职位。”玉帝问道:“弼马温?是何等职位啊?”太白金星说,弼马温就是用来管理天马的,反正现在天马无人管理,在天庭新设立一个弼马温的职位一方面有利于管理天马,另一方面可以不影响天庭现有的职位,最后还可以安抚妖猴。 之所以会出现上面职位难以安排的情况,这还要从天庭的官吏机制说起,是整个天庭的官吏制度导致了这种情况。在天庭中,法力越大的位置越高,相应的法力越低的位置就越低。而且法力高的由于可以得到各种相应的更多的仙桃啊、太上老君的金丹啊等就变的法力越来越大,也就导致了位置越来越高;另一方面,因为法力越来越大
34、,所以寿命也就越来越长。这导致了什么结果你?导致了终身制!一个职位几乎由相应的仙人一直掌管,永远没有空缺的时候。在天庭是一个萝卜一个坑,官职一旦确定就很难更改!我们说托塔李天王,他就永远是李天王,没人能够取代他的位置!那现在如何安排孙悟空呢?要做到既不影响天庭既有秩序和众仙的利益,又能够安抚孙悟空,那就只有新设立一个职位啦! 玉帝一听太白金星的想法,大悦。立刻派人把孙悟空请了上来。孙悟空早就听说天庭好玩,而且在天庭还有官职,喜出望外,欢欢喜喜的赴任去了。 定义: 开放封闭原则(Open-Closed Principle):一个软件实体应当对扩展开放,则修改关闭。对扩展开放,意味着有新的需求或变
35、化时,可以对现有代码进行扩展,以适应新的情况;对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。 开放封闭原则是所有面向对象原则的核心。 “需求总是在变化”。 “世界没有一个软件是不变的”。 如何做到开放封闭原则呢?答案是:封装变化,依赖接口和抽象类,而不要依赖具体实现类。要针对接口和抽象类编程,不要针对具体实现编程。因为接口和抽象类是稳定的,他们是一种对客户端的一种承诺,是相对不变的。如果以后需要扩展或者开发新的功能,只需要实现或者继承接口或者抽象类即可覆盖或者扩展新的功能,这样做同时也不回影响新的功能。这就很好的做到了对扩展开放、对修改关闭。 实际上讲,绝对封
36、闭的系统式不存在的。无论我们怎么保持封闭,一个系统总会有要变化的地方,“世界上没有一个不边的软件”、“需求总是在改变”。我们要做的不是消灭变化,而是把变化隔离开来,并对其进行封装。我们无法控制变化,但是我们可以预则哪里会发生变法。把要变化的地方抽象起来,这样以后再面临变化的时候我们就可以尽量的扩展,而无须改变以后的代码。 如下图所示: 故事分析: 太白金星献计任孙悟空为弼马温一职就很好的体现了开放封闭原则。 为什么这么说呢? 这还要从天庭的官吏机制说起,在天庭中,法力越大的位置越高,相应的法力越低的位置就越低。而且法力高的由于可以得到各种相应的更多的仙桃啊、太上老君的金丹啊等就变的法力越来越大
37、,也就导致了位置越来越高;另一方面,因为法力越来越大,所以寿命也就越来越长。这导致了什么结果你?导致了终身制!一个职位几乎由相应的仙人一直掌管,永远没有空缺的时候。在天庭是一个萝卜一个坑,官职一旦确定就很难更改!我们说托塔李天王,他就永远是李天王,没人能够取代他的位置!那现在如何安排孙悟空呢?要做到既不影响天庭既有秩序和众仙的利益,又能够安抚孙悟空,那就只有新设立一个职位啦! 总结一下:天庭既有秩序不变,扩展一个弼马温的位置给孙悟空。而且这种扩张不会影响到天庭的其它秩序。这不就是对修改关闭,对扩展开放吗?! 同时,可能不久又出现一个新的“孙悟空第二”,龙王可能又要告到天庭,“需求总是变法的”!
38、这时候只需要按照针对孙悟空同样的思路就可以很好解决此类变化。 再次重温一下面的话: “需求总是在变化。” “世界上没有一个软件是不变的。” “针对抽象编程,不要针对实现编程。” 如下图所示: Java代码实现: 新建一个职位的接口:packagecom.dieremng.designPattern.OCP;/* 职位的接口*/publicinterfacePosition /* * 定义职位的职责 */publicvoidduty(); 太白金星、托塔李天王、弼马温分别实现上面的接口。代码依次如下:packagecom.dieremng.designPattern.OCP.impl;impor
39、tcom.dieremng.designPattern.OCP.Position;/* 太白金星对职位的实现*/publicclassTaibaijinxinimplementsPosition publicvoidduty() System.out.println(这里是太白金星); packagecom.dieremng.designPattern.OCP.impl;importcom.dieremng.designPattern.OCP.Position;/* 托塔李天王对职位的实现*/publicclassTuotalitianwangimplementsPositionpublicv
40、oidduty() System.out.println(这里是托塔李天王); packagecom.dieremng.designPattern.OCP.impl;importcom.dieremng.designPattern.OCP.Position;/* 弼马温对职位的实现*/publicclassBimawenimplementsPosition publicvoidduty() System.out.println(这里是弼马温); 建立一个测试类,代码如下:packagecom.dieremng.designPattern.OCP.client;importcom.dieremn
41、g.designPattern.OCP.Position;importcom.dieremng.designPattern.OCP.impl.Bimawen;importcom.dieremng.designPattern.OCP.impl.Taibaijinxin;importcom.dieremng.designPattern.OCP.impl.Tuotalitianwang;publicclassPositionTest /* *paramargs */publicstaticvoidmain(String args) Position taibaijinxin =newTaibaijinxin(); Position tuotalitianwang =newTuotalitianwang(); Position bimawen =newB