您好,欢迎访问三七文档
面向对象分析设计Object-OrientedAnalysis&Design谭火彬-2-第06章面向对象的设计原则Object-OrientedDesignPrinciples-3-学习路线图OOUMLOOPDP…Case-Study…学习路线图::……………………12345678910-4--4-从问题开始!长方形与正方形假如我们有一个类:长方形(Rectangle)我们需要一个新的类,正方形(Square)问:可否直接继承长方形?没问题,因为数学上正方形就是长方形的子类!-5--5-开始设计:正方形publicclassRectangle{privateintwidth;privateintheight;publicvoidsetWidth(intw){width=w;}publicintgetWidth(){returnwidth;}publicvoidsetHeight(inth){height=h;}publicintgetHeight(){returnheight;}}publicclassSquareextendsRectangle{publicvoidsetWidth(intw){super.setWidth(w);super.setHeight(w);}publicvoidsetHeight(inth){super.setWidth(h);super.setHeight(h);}}-6--6-设计方案正确吗?publicstaticvoidresize(Rectangler){while(r.getHeight()=r.getWidth()){r.setHeight(r.getHeight()+1);}System.out.println(“It’sOK.);}Rectangler1=newRectangle();r1.setHeight(5);r1.setWidth(15);resize(r1);Rectangler2=newSquare();r2.setHeight(5);r2.setWidth(15);resize(r2);使用父类(长方形)时,程序正常运行使用子类(正方形)时,程序陷入死循环设计出问题了?继承出问题了?-7--7-为什么会出现问题?违背了面向对象的设计原则!-8--8-面向对象的设计原则面向对象的设计原则是面向对象设计的基本指导思想是评价面向对象设计的价值观体系是设计模式的出发点和归宿面向对象的设计原则是构造高质量软件的出发点-9--9-设计目标构造出高质量软件,以保持系统稳定设计目标可扩展性(Extensibility)灵活性(Flexibility)可插入性(Pluggability)……-10--10-设计质量:培养灵敏的嗅觉糟糕的设计总是散发出臭味,让人不悦判断一个设计的好坏,主观上能否让你的合作方感到心情愉悦,是最直观的标准设计开发人员要培养嗅觉,当你看到UML图或者代码,感到杂乱、繁琐、郁闷的时候,你可能正面对一个糟糕的设计这种嗅觉是在实践开发中培养起来的,而面向对象设计原则对此加以归纳和总结-11--11-设计质量:坏的设计什么是坏的设计?僵硬性(Rigidity):刚性,难以扩展脆弱性(Fragility):易碎,难以修改牢固性(Immobility):无法分解成可移植的组件不必要的复杂性(NeedlessRepetition):CtrlC+CtrlV晦涩性(Opacity):不透明,很难看清设计者的真实意图-12--12-设计质量:好的设计什么是好的设计?容易理解容易修改和扩展容易复用容易实现与应用简单、紧凑、经济适用让人工作起来心情愉快的设计设计原则是提高设计质量的基本原则-13--13-面向对象的基本设计原则LSP:Liskov替换原则TheLiskovSubstitutionPrincipleOCP:开放-封闭原则TheOpen-ClosePrincipleSRP:单一职责原则TheSingleResponsibilityPrincipleISP:接口隔离原则TheInterfaceSegregationPrincipleDIP:依赖倒置原则TheDependencyInversionPrinciple……-14--14-LSPLSP(TheLiskovSubstitutionPrinciple,Liskov替换原则)“若对于类型S的任一对象o1,均有类型T的对象o2存在,使得在T定义的所有程序P中,用o1替换o2之后,程序的行为不变,则S是T的子类型”如果在任何情况下,子类(或子类型)或实现类与基类都是可以互换的,那么继承的使用就是合适的。为了达到这一目标,子类不能添加任何父类没有的附加约束“子类对象必须可以替换基类对象”-15--15-违背LSP原则Square类针对height、width添加了Rectangle所没有的附加的约束(即要求height=width),这样Square类(子类)不能完全替换Rectangle(父类)违背了LSP原则带来潜在的设计问题(使用resize方法时,子类出错!)-16--16-怎么办?ABABCabstract在可能的情况下,由抽象类(接口)继承-17--17-抽象类与具体类具体类3抽象类1abstract抽象类2abstract具体类1抽象类3abstract具体类2只要有可能,不要从具体类继承行为集中的方向是向上的(抽象类)数据集中的方向是向下的(具体类)-18--18-解决方案-19--19-IS-A关系的思考?鸵鸟是鸟吗?是鸵鸟有翅膀,鸟也有翅膀鸵鸟有喙,鸟也有喙…但是…鸟.getFlySpeed()鸵鸟.getRunSpeed()有着不同-20--20-IS-A关系的思考(续)对于动物学家只关心鸟的生理特征,对他们来说,鸵鸟就是鸟对于养鸟人关心鸟的行为特征,鸵鸟不是鸟他们都正确考虑一个特定设计是否恰当时,不能完全孤立地看这个解决方案,应该根据设计使用者提出的合理假设来审视-21--21-OCPOCP(TheOpen-ClosePrinciple,开放-封闭原则)软件实体(类、模块、函数等)应该是可扩展的,但是不可修改的特征:对于扩展是开放的(Openforextension):模块的行为可以扩展,当应用的需求改变时,可以对模块进行扩展,以满足新的需求对于更改是封闭的(Closedformodification):对模块行为扩展时,不必改动模块的源代码或二进制代码-22--22-OCP的关键在于抽象OCP的关键在于抽象抽象技术:abstractclass,Interface抽象预见了可能的所有扩展(闭)由抽象可以随时导出新的类(开)ClientServerServerClientInterfaceInterfaceClient-23--23-范例:手与门如何在程序中模拟用手去开门和关门?行为:开门(open)关门(close)判断门的状态(isOpened)-24--24-设计实现publicclassDoor{privateboolean_isOpen=false;publicbooleanisOpen(){return_isOpen;}publicvoidopen(){_isOpen=true;}publicvoidclose(){_isOpen=false;}}publicclassHand{publicDoordoor;voiddo(){if(door.isOpen())door.close();elsedoor.open();}}publicclassSmartTest{publicstaticvoidmain(String[]args){HandmyHand=newHand();myHand.door=newDoor();myHand.do();}}-25--25-新的需求……需要手去开关抽屉,冰箱……?我们只好去修改程序!-26--26-解决新的需求:修改设计publicclassHand{publicDoordoor;publicDrawerdrawer;voiddo(intitem){switch(item){case1:if(door.isOpen())door.close();elsedoor.open();break;case2:if(drawer.isOpen())drawer.close();elsedrawer.open();break;}}}publicclassSmartTest{publicstaticvoidmain(String[]args){HandmyHand=newHand();myHand.door=newDoor();myHand.drawer=newDrawer();myHand.do(1);}}手被改了!主(使用手)程序也被改了!-27--27-符合OCP的设计方案publicinterfaceExcutable{publicbooleanisOpen();publicvoidopen();publicvoidclose();}-28--28-新的实现publicclassDoorimplementsExcutable{privateboolean_isOpen=false;publicbooleanisOpen(){return_isOpen;}publicvoidopen(){_isOpen=true;}publicvoidclose(){_isOpen=false;}}publicclassHand{publicExcutableitem;voiddo(){if(item.isOpen())item.close();elseitem.open();}}publicclassDrawerimplementsExcutable{privateboolean_isOpen=false;publicbooleanisOpen(){return_isOpen;}publicvoidopen(){_isOpen=true;}publicvoidclose(){_isOpen=false;}}publicclassSmartTest{publicstaticvoidmain(String[]args){HandmyHand=newHand();myHand.item=newDoor();myHand.do();}}-29--29-新的需求……需要手去开关冰箱……?为冰箱实现Excutable接口不需要修改任何原有的设计和代码publicclassRefrigeratorimplementsExcutable{privateboolean_isOpen=false;publicbooleanisOpen(){return_isOpen;}publicvoidopen(){_isOpen=true;}publicvoidclose(){_isOpen=false;}}-30--30-关于OCPOCP是OOD中很多说法的核心如果这个原则应用得有效,应用程序就会具有更多的可维护性、可重用性以及可健壮性很多设计模式都是遵从这个原则而提出来的LSP是OCP成为可能的主要原则之一正是子类型的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展-31--31-SRPSRP(TheSingleResponsibilityPrinciple,单一职责原则)就一个类而言,应该仅有一个引起它变化的原因有关类的职责分配问题,是面向对象设计中最重要的基本原则“Acritical,fundamentalabilityinOOA/Distoskillfullyassignresponsibilitytosoftwarecomponents.”Cr
本文标题:tanhuobin_uml06Object-OrientedDesignPrinciples
链接地址:https://www.777doc.com/doc-352 .html