OOT设计模式赛事接口隔离原则文档格式.docx
《OOT设计模式赛事接口隔离原则文档格式.docx》由会员分享,可在线阅读,更多相关《OOT设计模式赛事接口隔离原则文档格式.docx(40页珍藏版)》请在冰豆网上搜索。
接口隔离原则与广义的迪米特法则都是对一个软件实体与其他的软件实体的通信的限制。
遵循接口隔离原则,会使一个软件系统在功能扩展的过程当中,不会将修改的压力传递到其他的对象。
一个重构方法的讨论
“将条件转移语句改写成为多态性”是一条广为流传的代码重构做法。
这一做法本身并不能保证“开-闭”原则,应当以“开-闭”原则判断是否需要改写成多态。
条件转移并不是错误,如果需要,完全可以选择使用条件转移。
如果一个条件转移语句确实封装了某种商务逻辑的可变性,那么将此种可变性封装起来就符合“开-闭”原则设计思想了。
如果一个条件转移语句没有涉及重要的商务逻辑,或者不会随着时间的变化而变化,也不意味着任何的可扩展性,那么它就没有涉及任何有意义的可变性。
这时候将这个条件转移语句改写成多态性就是一种没有意义的浪费。
抽象类应当拥有尽可能多的共同代码
在一个继承的等级结构中,共同的代码应当尽量向等级结构的上方移动。
把重复的代码从子类里面移动到超类里面,可以提高代码的复用率。
在代码发生改变时,设计师之需要修改一个地方。
抽象类应当拥有尽可能少的数据
与代码的移动方向相反,数据的移动方向是从抽象类到具体类,向等级结构的下方移动。
一个对象的数据不论是否使用都会占用资源,所以应当放到等级结构的低端。
什么时候才应当使用继承复用
1.子类是超类的一个特殊种类,而不是超类的一个角色,Is-A才符合继承关系。
2.永远不会出现需要将子类换成另一个类的子类的情况。
3.子类具有扩展超类的责任,而不是具有置换掉(Override)和注销掉(Nullify)超类的责任。
只有在分类学角度上有意义时,才可以使用继承,不要从工具类继承。
迪米特法则(LoD)
迪米特法则(LoD):
又称最少知识原则(LKP),就是说一个对象应当对其他对象尽可能少的了解。
狭义的迪米特法则:
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用.如果其中一个类需要调用另一个类的方法的话,可以通过第三者转发这个调用.
缺点:
会在系统内造出大量的小方法,散落在系统的各个角落.这些方法仅仅是传递间接的调用,因此系统与系统中的商业逻辑无关.当设计师试图从一张类图看出总体的构架时,这些小方法会造成迷惑和困扰.
为了克服狭义迪米特法则的缺点,可以使用依赖倒转原则,引入一个抽象的类型引用"
抽象陌生人"
对象,使"
某人"
依赖于"
换言之,就是将"
变成朋友.
广义的迪米特法则:
一个模块设计得好坏的一个重要的标志就是该模块在多大的程度上将自己的内部数据与实现有关的细节隐藏起来.
信息的隐藏非常重要的原因在于,它可以使各个子系统之间脱耦,从而允许它们独立地被开发,优化,使用阅读以及修改.
迪米特法则的主要用意是控制信息的过载.在运用迪米特法则到系统的设计中时,要注意以下几点:
*在类的划分上,应当创建有弱耦合的类.类之间的耦合越弱,就越有利于复用.
*在类的结构设计上,每一个类都应当尽量降低成员的访问权限.
*在类的设计上,只要可能,一个类应当设计成不变类.
*在对其他类的引用上,一个对象对其他对象的引用应降到最低.
*尽量限制局部变量的有效范围.
OO设计原则----接口隔离原则(ISP)
接口隔离原则(ISP)
净化抽象接口的一个原则,中心思想就是使接口和接口之间尽量的解除耦合,降低接口改变维护的工作量。
如果一个子类需要另一个接口的对象,通常我们会在这个子类的接口中声明一个有使用接口为参数的方法,(为什么?
因为这个具体类的使用的时候都是以接口为表示的)。
这个时候其他的派生类就会遇到改变的情况,而且有很多派生类会进行方法的一个退化性的实现。
而且当一个接口的改变会影响不相关的一些接口。
解决办法使用一个适配器模式进行适配
坏味道
一当一个接口中的方法很多,但是派生类具有选择性的实现的时候,这个接口的设计就有问题了,应该根据用户的分组把接口进行分组
二当一个接口引用另外一个接口的时候,就会产生接口间的依赖,但是这个时候一定要分清是否应该使用适配方案因为有些情况这样的使用是正确的
三当一个接口中含有大量的方法的时候,就说明这个接口的副作用就越大,应为任何一个派生类都需要实现所有的方法,而且接口方法的改变几率也就越大,对于派生类的影响几率也就越大,使接口的维护开销也就越大。
java与模式的思考——里氏代换原则、依赖倒转原则
2007年12月27日22:
44
里氏代换原则
面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化,具体化也就是给出不同的实现。
继承关系就是一种从抽象化到具体化的导出。
里氏代换原则:
如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。
其实就是一个软件程序的代码块如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
依赖倒转原则
面向对象设计的原则估计都是和抽象分不开的,依赖倒转原则:
要依赖于抽象,不要依赖于具体。
传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块,抽象层次依赖于具体层次。
倒转原则就是把这个错误的依赖关系倒转过来。
抽象层次包含的应该是应用系统的商务逻辑和宏观的、对整个系统来说重要的战略性决定,是必然性的体现。
具体层次含有的是一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有相当大的偶然性选择。
具体层次的代码是经常变动的,不能避免出现错误。
这一设计原则也是COM、CORBA、JavaBean、EJB等构建设计模型背后的基本原则。
从复用的角度来说,高层次的模块是应当复用的,而且是复用的重点,因为它含有一个应用系统最重要的宏观商务逻辑,是较为稳定的。
在传统的过程性设计中,复用则侧重于具体层次模块的复用。
同样,最重要的宏观商务逻辑也是维护的重点。
遵守依赖倒转原则会带来复用和可维护性的“倒转”。
依赖(或者耦合)关系的种类:
零耦合(NilCoupling)关系:
两个类没有耦合关系
具体耦合(ConcreteCoupling)关系:
发生在两个具体的(可实例化的)类之间,经由一个类对另一个具体类的直接引用造成
抽象耦合(AbstractCoupling)关系:
发生在一个具体类和一个抽象类(或Java接口)之间,使两个必须发生关系的类之间存有最大的灵活性
依赖倒转原则的表述是:
抽象不应当依赖于细节,细节应当依赖于抽象。
Abstractionsshouldnotdependupondetails.Detailsshoulddependuponabstractions.
要针对接口编程,不要针对实现编程。
Programtoaninterface,notanimplementation.
也就是说应当使用Java接口和抽象Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。
而不要用具体Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。
要保证做到这一点,一个具体Java类应当只实现Java接口和抽象Java类中声明过的方法,而不要给出多余的方法。
要遵守“开—闭”原则,倒转依赖原则便是达到要求的途经。
变量的静态类型和真实类型
变量被声明时的类型是静态类型(statictype),或明显类型(apparenttype),变量所引用的对象的真实类型叫实际类型(actualtype)。
对象的创建
变量的声明是静态类型,可实例创建过程中调用的构造方法仍然必须是具体类型的构造方法。
一般,在创建一个对象时,Java语言要求使用new关键词以及这个类本身,一旦对象被创建,就可以灵活地使用这个对象的抽象类型来引用它。
所以,创建一个对象的过程是违背“开—闭”原则以及依赖倒转原则的,从而就产生了工厂模式,用于解决对象创建过程中的依赖倒转问题。
怎样做到依赖倒转?
以抽象方式耦合是依赖倒转原则的关键。
抽象耦合关系总要涉及具体类从抽象类继承,并且需要保证在任何引用到基类的地方都可以改换成其子类,因此,里氏代换原则是依赖倒转原则的基础。
在抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性,如果一个具体类发生变化的可能性非常小,那么抽象耦合能发挥的好处便十分有限,这时可以用具体耦合反而会更好。
依赖倒转原则的优缺点
虽然很强大,但却最不容易实现。
因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用可能还会导致产生大量的类,对不熟悉面向对象技术的工程师来说,维护这样的系统需要较好地理解面向对象设计。
依赖倒转原则假定所有的具体类都是会变化的,这也不总是正确,有一些具体类可能是相当稳定,不会变化的,使用这个具体类实例的应用完全可以依赖于这个具体类型,而不必为此发明一个抽象类型。
子类型必须能够替换掉它们的父类型。
只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
正是由于子类型的可替换性才使得父类型的模块在无需修改的情况下就可以扩展。
依赖性倒转其实可以说是面向对象设计的标志,用那种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。
29.1
演讲任务
时间:
7月23日下午17点
地点:
小菜办公室
人物:
小菜、公司开发部经理
“小菜,”开发部经理来到小菜的办公桌前,“最近我听说你在工作中,用到了很多设计模式,而且在你们同一项目组中引发了关于设计模式的学习和讨论,反响非常好。
明天全公司要开关于如何提高软件质量的研讨会,我希望到时你能做一个关于设计模式的演讲。
”
“我?
演讲?
给全公司?
”小菜很惊讶于经理的这个请求,“还是不要了吧,我从来都没上过台给那么多人讲东西。
我怕讲不好的。
“没事,你就像平时和同事交流设计模式那样说说你在开发中的体会和经验就行了。
“明天,时间太仓促了吧,来不及的。
”小菜想法推脱。
“哈,某位大导演在他的近期的电影里不是已经向众人证实,身材是可以靠挤来获得的。
同理可证,时间也是可以挤出来的,晚上抓紧一些,一定行的。
就这么定了,你好好准备一下。
”说完,经理就离开了小菜的办公桌。
“我……”小菜还来不及再拒绝,已经没了机会。
7月23日晚上22点
小菜自己的卧室
小菜
“讲什么好呢?
”小菜使劲地想呀想,却没有头绪,“该死的大鸟,还不回来,不然也可以请教请
教他。
“真困”,小菜睡眼朦胧,趴到了桌上,打起盹来,不一会,进入了梦乡。
29.2
报名参赛
未知
地点:
很多
“来来来,快来报名了,超级设计模式大赛,每个人都有机会,每个人都能成功,今天你参加比赛给自己一个机会,明天你就成功还社会一个辉煌。
来来来……”只见台子上方一很长的条幅,上写着“OOTV杯超级模式大赛海选”,下面一个帅小伙拿着话筒卖力地吆喝着。
“大姐、二姐,我们也去报名参加吧。
”工厂三姐妹中最小的简单工厂说道。
“这种选秀比赛,多得去了,很多是骗人的,没意思。
”大姐抽象工厂说。
“我觉得我们三姐妹有机会的,毕竟我们从小就是学这个出身。
”二姐工厂方法也很有兴趣参赛。
“大姐,去吧,去吧。
”简单工厂拉住抽象工厂的手左右摇摆着。
“行了行了,我们去试试,成就成,不成可别乱哭鼻子。
”抽象工厂用手指点了一下简单工厂的鼻子,先打上了预防针。
“放心吧,我们都会成功的。
”简单工厂很高兴,肯定地说。
三个人果然顺利通过了海选。
但在决赛前的选拔中,工厂方法和抽象工厂都晋级,而简单工厂却不幸落选了。
“唔唔唔……唔唔唔……”简单工厂哭着回到了后台。
“小妹,别哭了,到底发生了什么?
”工厂方法搂住她,轻声地问道。
“他们说我不符合开放-封闭原则的精神,”简单工厂哽咽地答道,“所以就把我淘汰了。
“你在对每一次扩展时都要更改工厂类,这就是对修改开放了,当然不符合开闭原则。
”抽象工厂说道,“行了,别哭了,讲好了不许哭鼻子的。
“哇……哇……哇……”被大姐这么一说,简单工厂放声大哭。
“好了,没关系的,这次不行,还会有下次的。
”工厂方法拍了拍她的后背安慰地说。
“二姐,你要好好加油,为我们工厂家族争光。
”简单工厂握着工厂方法的手说,然后对着抽象工厂说,“大姐,哼,你老是说风凉话,祝你早日淘汰。
”边说着,简单工厂却破涕为笑了。
“你这小妮子,敢咒我。
看我不……”抽象工厂脸上带笑,嘴里骂着,举起手欲拍过去。
“二姐救我,大姐饶命。
”简单工厂躲到工厂方法后面叫道。
三姐妹追逐打闹着,落选的情绪一扫而空。
29.3
超模大赛开幕式
“各位领导、各位来宾、观众朋友们,第一届OOTV杯超级设计模式大赛正式开始。
”漂亮的主持人GOF出现在台前,话音刚落,现场顿时响起激昂的音乐热烈的掌声。
“首先我们来介绍一下到场的嘉宾。
第一位是我们OOTV创始人,面向对象先生。
”只见前排一位40多岁的中年人站了起来,向后排的观众挥手。
工厂方法在后台对着抽象工厂说:
“没想到面向对象这么年轻,40岁就功成名就了。
“是呀,他从小是靠做simula服装开始创业的,后来做Smalltalk的生意开始发扬光大,但最终让他成功的是Java,我觉得他也就是运气好。
”抽象工厂解释说。
“运气也是要给有准备头脑的人,前二十年,做C品牌服装生意的人多得是了,结构化编程就象神一样的被顶礼膜拜,只有面向对象能坚持OO理念,事实证明,OO被越来越多的人认同。
这可不是
运气。
“结构化编程那确实是有些老了,时代不同了,老的偶像要渐渐退出,新的偶像再站出来。
现在是面向对象的时代,当然如日中天,再过几年就不一定是他了。
”抽象工厂相对悲观。
“面向对象不是一直声称自己‘永远二十五岁’吗?
”工厂方法双手抱拳放在胸前,坚定地说,“我看好他,他是我永远的偶像。
“到场来宾还有,抽象先生、封装先生、继承女士、多态女士。
他们也是我们这次比赛的策划、导演和监制,掌声欢迎。
”主持人GOF说道。
工厂方法说:
“啊,这些明星,平时看都看不见的,真想为他们尖叫。
抽象工厂说:
“我最大的愿望就是能得到抽象先生的签名,看来极有可能梦想成真了。
两姐妹在那里入迷地望着前台,自说自话着。
“现在介绍本次大赛的评委,单一职责先生、开放封闭先生、依赖倒转先生、里氏代换女士、合成聚合复用女士、迪米特先生。
“那个叫开放封闭的家伙就是提出淘汰小妹的人。
”抽象工厂对工厂方法说。
“嘘,小点声,他们可就是我们的评委,我们的命运由他们决定的。
”工厂方法把食指放在嘴边小
声地说。
“下面有请面向对象先生发表演讲。
面向对象大步流星地走上了台前,没有任何稿子,语音洪亮地开始了发言。
“各位来宾,电视机前的朋友们,大家好!
(鼓掌)
感谢大家来为OOTV的超级设计模式大赛捧场。
OO从诞生到现在,经历了风风雨雨,我面向对象能有今天真的也非常的不容易。
就着这机会,我来谈谈面向对象的由来和举办此次设计模式大赛的目的。
软件开发思想经过了几十年的发展。
最早的机器语言编程,程序员一直在内存和外存容量的苛刻限制下‘艰苦’劳作。
尽管如此,当时程序员还是创造了许多令人惊奇的工程软件。
后来,高性能的计算机越来越普及,它们拥有较多的内外存空间,编程也发展到一个较高的层次,不再对任一细节都斤斤计较,于是出现了各种高级语言,软件编程开始进入了全面开花的时代。
刚开始的高级语言编写,大多是面条式的代码,随着代码的复杂化,这会造成代码极度混乱。
随着软件业的发展,面条式的代码是越来越不适应发展的需要,此时出现了结构化编程,即面向过程式的开发,这种方式把代码分割成了多个模块,增强了代码的复用性,方便了调试和修改,但是结构也相对复杂一些。
面向过程的开发,把需求理解成一条一条的业务流程,开发前总是喜欢问用户‘你的业务流程是什么样的?
’,然后他们分析这些流程,把这些流程交织组合在一起,然后再划分成一个又一个的功能模块,最终通过一个又一个的函数,实现了需求。
这对于一个小型的软件来说,或许是最直接最简捷的做法。
而问题也就出在了这里。
随着软件的不断复杂化,这样的做法有很大的弊端。
面向过程关注业务流程,但无论多么努力工作,分析做得如何好,也是永远无法从用户那里获得所有的需求的,而业务流程却是需求中最可能变化的地方,业务流程的制定需要受到很多条件的限制,甚至程序的效率、运行方式都会反过来影响业务流程。
有时候用户也会为了更好地实现商业目的,主动地改变业务流程,并且一个流程的变化经常会带来一系列的变化。
这就使得按照业务流程设计的程序经常面临变化。
今天请假可能就只需要打声招呼就行了,明天请假就需要多个级别管理者审批才可以。
流程的易变性,使得把流程看得很重,并不能适应变化。
面向过程通过划分功能模块,通过函数相互间的调用来实现,但需求变化时,就需要更改函数。
而你改动的函数有多少的地方在调用它,关联多少数据,这是很不容易弄得清楚的地方。
或许开发者本人弄得清楚,但下一位维护代码者是否也了解所有的函数间的彼此调用关系呢?
函数的修改极有可能引起不必要的Bug的出现,维护和调试中所耗费的大多数时间不是花在修改Bug上,而是花在寻找Bug上,弄清如何避免在修改代码时导致不良副作用上了。
种种迹象都表明,面向过程的开发也不能适应软件的发展。
与其抱怨需求总是变化,不如改变开发过程,从而更有效地应对变化。
面向对象的编程方式诞生,就是为解决变化带来的问题。
面向对象关注的是对象,对象的优点在于,可以定义自己负责的事物,做要求它自己做的事情。
对象应该自己负责自己,而且应该清楚地定义责任。
面向对象的开发者,把需求理解成一个一个的对象,他们喜欢问用户‘这个东西叫做什么,他从哪里来,他能做什么事情?
’,然后他们制造这些对象,让这些对象互相调用,符合了业务需要。
需求变化是必然的,那么尽管无法预测会发生什么变化,但是通常可以预测哪里会发生变化。
面向对象的优点之一,就是可以封装这些变化区域,从而更容易地将代码与变化产生的影响隔离开来。
代码可以设计得使需求的变化不至于产生太大的影响。
代码可以逐步演进,新代码可以影响较少地加入。
显然,对象比流程更加稳定,也更加封闭。
业务流程从表面上看只有一个入口、一个出口,但是实际上,流程的每一步都可能改变某个数据的内容、改变某个设备的状态,对外界产生影响。
而对象则是完全通过接口与外界联系,接口内部的事情与外界无关。
当然,有了面向对象的方式,问题的解决看上去不再这么直截了当,需要首先开发业务对象,然后才能实现业务流程。
随着面向对象编程方式的发展,又出现了设计模式、ORM、以及不计其数的工具、框架。
软件为什么会越来越复杂呢?
其实这不是软件本身的原因,而是因为软件需要解决的需求越来越复杂了。
面向过程设计开发相对容易,但不容易应对变化。
面向对象设计开发困难,但却能更好的应对千变万化的世界,所以现代的软件需要面向对象的设计和开发。
设计模式是面向对象技术的最新进展之一。
由于面向对象设计的复杂性,所以我们都希望能做出应对变化,提高复用的设计方案,而设计模式就能帮助我们做到这样的结果。
通过复用已经公认的设计,我们能够在解决问题时避免前人所犯的种种错误,可以从学习他人的经验中获益,用不着为那些总是会重复出现的问题再次设计解决方案。
显然,设计模式有助于提高我们的思考层次。
让我们能站在山顶而不是山脚,也就是更高的高度来俯视我们的设计。
如今,好的设计模式越来越多,但了解他们的人却依然很少,我们OOTV举办设计模式大赛的目的一方面是为了评选出最优秀的设计模式,另一方面也是希望让更多的人了解她们,认识她们,让她们成为明星,让她们可以为您的工作服务。
祝愿本届大赛圆满成功。
谢谢大家!
[DPE]”(鼓掌)
正在此时,突然一个人双手举着一块牌子冲上了讲台,纸牌上写着“Service-OrientedArchitecture(面向服务的体系架构SOA)”,口中大声且反复地说道:
“抵制Object-Oriented,推广Service-Oriented,OO已成往事,SOA代表未来。
这突如其来的变化,让全场哗然,很多人都交头接耳,说着关于SOA与OO的关系。
只有面向对象先生依然站在讲台上,微笑不语,显然久经风雨的他对于这种事早已见怪不怪。
保安迅速带着此人离开了会场。
会场渐渐又恢复了安静。
“下面宣布一下比赛规则。
”GOF的声音再次响起,“本次大赛根据模式的特点,设置了三个类别,分别是创建型模式、结构型模式和行为型模式,但由于有11位选择了行为型模式,人数过多,所以行为型模式又分为了两组。
也就是说,我们将选手共分为了四组,所有的选手都将首先参加分组比赛,每组第一名将参加我们最终设计模式冠军的争夺。
选手的分组情况,请看大屏幕。