收藏 分享(赏)

第1章面向对象概述.ppt

上传人:Facebook 文档编号:3489097 上传时间:2018-11-05 格式:PPT 页数:132 大小:2.44MB
下载 相关 举报
第1章面向对象概述.ppt_第1页
第1页 / 共132页
第1章面向对象概述.ppt_第2页
第2页 / 共132页
第1章面向对象概述.ppt_第3页
第3页 / 共132页
第1章面向对象概述.ppt_第4页
第4页 / 共132页
第1章面向对象概述.ppt_第5页
第5页 / 共132页
点击查看更多>>
资源描述

1、-1-,面向对象概述,-2-,为什么学习这门课 性质与目的 课程要求 成绩评定 学习本课程的建议,课程介绍,-3-,为什么学习这门课,程序员 (programmer),系统分析员 (system analyst),建筑工人 (worker),建筑师 (architect),-4-,(1)了解信息系统建模的基本理论 (2)熟练使用UML进行系统建模,性质与目的,(3)掌握运用建模技术、建模工具进行系统开发的方法,性质,专业课、54学时、必修、考试,目的,-5-,课程要求,1.清晰、准确、熟练地掌握面向对象方法的主要思想、基本概念与原则。2.针对具体问题会应用面向对象技术进行系统分析和设计,掌握在

2、ROSE环境下用UML进行分析和设计的技术。,-6-,成绩评定,出勤+作业 (30%) 期末笔试 (70%),-7-,学习本课程的建议,课前预习多学习面向对象分析和设计的例子尽快学会使用支持UML的工具(如Rose 2003),-8-,第1章 面向对象概述,-9-,知识图谱,-10-,1.1 面向对象的基本概念1.2 面向对象的基本特征1.3 面向对象方法论1.4 面向对象建模,本章内容,-11-,面向对象的基本特征和方法论软件建模的基本概念,本章重点,-12-,什么是对象 面向对象与面向过程的区别 对象与类的确定 消息和事件,1.1 面向对象的基本概念,-13-,什么是对象 面向对象与面向过

3、程的区别 对象与类的确定 消息和事件,1.1 面向对象的基本概念,-14-,对象是某种可被人感知的事物,也是思维,感觉或动作所能作用的物质或精神体。,图书馆管理系统,学生、老师、管理员、计算机、书籍、书架、图书馆,院系、学号、编号,什么是对象,-15-,什么是对象 面向对象与面向过程的区别 对象与类的确定 消息和事件,1.1 面向对象的基本概念,-16-,面向过程的程序设计,结构化程序设计,以函数为中心,以功能为中心,面向对象的程序设计,以对象为基础,以事件或消息来驱动对象执行处理,面向对象与面向过程的区别,-17-,例1-1:文件打印管理程序设计需求描述:在某个计算机信息管理系统中需要设计和

4、编写文件打印管理程序。该系统中有三种类型文件:纯文本文件(*.txt)、图文混合文件(*.mdx)和图像文件(*.jpg)。可利用的打印机是1台行打和2台激打。这三台打印机为许多计算机用户共享使用,用户可以任意选择某台打印机使用。但其中行打只能打印纯文本文件,而激打可以打印三种类型的文件。请为该管理系统设计一个打印管理程序(假设任何一个打印机都有足够的缓冲区,可以一次性处理所提交的任何文件数据)。,面向对象与面向过程的区别,-18-,解决方案一:传统的设计,打印控制程序,图文混合 打印处理,纯文本 打印处理,队列 控制处理,图像 打印处理,图1.1 打印控制程序的结构化设计,面向对象与面向过程

5、的区别,-19-,解决方案二:面向对象的设计,面向对象与面向过程的区别,-20-,什么是对象 面向对象与面向过程的区别 对象与类的确定 消息和事件,1.1 面向对象的基本概念,-21-,对象与类的确定,对象是组成系统的基本单元,类是创建对象的模板。 对象=数据+数据的操作,类=属性+操作 确定一个类的步骤,1)确定系统的范围 2)在系统范围内寻找对象 3)将对象抽象成为一个类,-22-,什么是对象 面向对象与面向过程的区别 对象与类的确定 消息和事件,1.1 面向对象的基本概念,-23-,消息(Message)向对象发出的服务请求,它包括了提供服务的对象标识、服务(方法)标识、输入信息和回答信

6、息等。,图书馆管理系统,1)某一个按钮发送鼠标单击事件的消息给相应对象; 2)对象接受消息后提供图书的相关信息给界面; 3)界面显示信息,完成任务。,事件(Event)一种由系统预先定义而由用户或系统发出的动作。,Click、Load,“单击按钮”,消息和事件,-24-,抽象(Abstract)封装(Encapsulation)继承(Inheritance)多态(Polymorphism),1.2 面向对象的基本特征,-25-,从许多事物中舍弃个别的、非本质的特征,抽取共同及本质的特征。,原则,舍弃与系统责任无关的事物 舍弃与系统责任无关的特征,概念,举例,九方皋相马 庖丁解牛,抽象(Abst

7、ract),-26-,抽象的作用1)将需要的事物进行简化;2)将事物特征进行概括;3)将抽象模型组织为层次结构;,4)将软件重用得以保证,抽象(Abstract),-27-,抽象(Abstract),-28-,把对象的属性和方法结合成一个独立的系统单位,并尽可能地隐藏对象的内部细节。也称“信息隐藏”。,(1)结合对象的全部状态和行为,形成整体;(2)隐蔽对象的内部细节,通过接口与外部联系。,概念,含义,封装(Encapsulation),-29-,早期的模块化方法不强调数据与过程的完整结合。,封装(Encapsulation),-30-,面向对象的方法强调信息隐蔽,更强调数据与处理的完整性。,

8、封装(Encapsulation),-31-,特殊类的对象拥有一般类的属性和行为。,概念,学生类继承结构示意图,继承(Inheritance),-32-,单继承,多继承,继承实现了软件模块的可重用性、独立性,缩短了开发周期,提高了软件的开发效率。,继承(Inheritance),-33-,继承(Inheritance),-34-,两个或多个属于不同类的对象,对于同一个消息或方法所做出不 同响应的能力。,Object Pascal和C+虚函数(Virtual Function),覆盖,多态(Polymorphism),-35-,多态(Polymorphism),例 1-3 function Ad

9、d(a,b:integer):integer return a+b; ; function Add(a,b:string):string return ToString(Add(ToNumber(a),ToNumber(b) ;,结构化程序设计语言中的“多态”概念。,重载是传统的语言特性,不是多态机制,也不是面向对象的概念。,多态的作用:接口重用,重载,-36-,面向对象分析面向对象设计,1.3 面向对象方法论,-37-,面向对象的分析OOA(Object-Oriented Analysis),就是运用面向对象的方法进行需求分析。 OOA的侧重点是业务领 域分析,与软件所要应用的行业领域相关,

10、而与软件技术关系不大, 需要由领域专家进行。,面向对象分析,-38-,面向对象的分析过程,面向对象分析,-39-,(1)获取问题域陈述,图书管理系统陈述,数据中心服务器,管理系统客户端,管理系统客户端,管理系统客户端,借阅者,图书管理员,系统管理员,图书管理信息系统网络结构示意图,面向对象的分析过程,-40-,(2)建立系统的对象模型,标识和确定类,准备数据字典,确定关联,图书:书刊名、ISBN/ISSN号、分类、作者、出版日期、出版社,关联是指两个类或多个类之间的相互依赖,用描述性动词 或动词词组表示。,面向对象的分析过程,-41-,(2)建立系统的对象模型,确定属性,修饰性的名词词组,借助

11、于应用域的知识及对客观世界的知识,只考虑与具体应用直接相关的属性,使用继承类来细化对象,自底向上,自顶向下,完善对象模型,面向对象的分析过程,-42-,(3)建立对象的动态模型,准备脚本确定事件准备事件跟踪表构造状态图,面向对象的分析过程,-43-,(4)建立系统的功能模型,列出输入、输出值建立数据流图,面向对象的分析过程,-44-,OOA的成果,业务领域用例图 活动图 协作图 大量的业务文档资料,面向对象分析,-45-,OOD(Object-Oriented Design)面向对象的设计,面向对象设计是把分析阶段得到的需求转变成符合成本和质量要求的、抽象的系统实现方案的过程。,系统设计对象设

12、计,面向对象设计,-46-,面向对象设计,面向对象设计的准则,模块化抽象信息隐藏低耦合高内聚,-47-,面向对象设计的实用规则,设计的结果清晰易懂一般到具体结构的深度应适当尽量设计小而简单的类使用简单的消息协议使用简单的函数或方法把设计变动减至最小,面向对象设计,-48-,1.4 面向对象建模,-49-,模型是什么,模型是对现实的简化。,-50-,为什么要建模,为了能够更好地理解正在开发的系统。,更好地理解问题 人员之间的沟通 发现错误或疏漏的地方 获取设计结果 生成代码,-51-,建模的基本原则,(1)要仔细的选择模型;(2)每一种模型可以在不同的精度级别上表示所要开发的系统;(3)模型要与

13、现实相联系;(4)对一个重要的系统用一组几乎独立的模型去处理。,-52-,选择什么工具进行建模,统一建模语言UML(Unified Modeling Language),I. Jacobson,J. Rumbaugh,G. Booch,-53-,UML是一种定义良好、易于表达、功能强大且普遍适用的建模语言,它融入了软件工程领域的新思想、新方法和新技术,不仅可以支持面向对象的分析与设计,更重要的是能够有力地支持从需求分析开始的软件开发的全过程。,统一建模语言UML,-54-,瀑布模型喷泉模型基于构件的开发模型XP(eXtreme Programming),以面向对象为基础的开发模式,-55-,瀑

14、布模型,项目计划,需求分析,软件设计,软件实现,软件测试,软件运行和维护,采用瀑布模型的软件过程,优点便于组织和管理,缺陷反馈不及时,增加了风险;缺乏灵活性;完全确定需求比较困难。,以面向对象为基础的开发模式,-56-,喷泉模型,分析,设计,实现,维护,演化,采用喷泉模型的软件过程,优点提高开发效率,节省时间,缺点不利于项目管理;审核难度加大。,以面向对象为基础的开发模式,-57-,基于构件的开发模型,基于构件的开发模型的软件过程,DCOM、EJB、CORBA,优点导致了软件的复用提高了软件开发的效率降低了成本,提高了可维护性,缺点缺乏通用的组装标准,风险大对人员要求高构件库的质量影响产品质量

15、,以面向对象为基础的开发模式,-58-,XP方法,发布计划,迭代,验证测试,小型发布,系统架构,用户场景,采用XP方法的软件过程,优点简单交流和反馈进取,以面向对象为基础的开发模式,-59-,本章小结,-60-,什么是对象?试着列举三个现实中的例子。 什么是抽象? 什么是封装?它有哪些好处? 什么是继承?它有哪些好处? 面向对象分析的过程有哪些? 面向对象的设计准则有哪些? 为什么要使用UML建模?,作业,-61-,面向对象设计原则,-62-,从问题开始!,假设要设计一个画图软件,其中涉及到长方形与正方形,那么它们之间的关系如何定义: 假如我们有一个类:长方形(Rectangle) 我们需要一

16、个新的类,正方形(Square) 问:可否直接继承长方形?,没问题,因为数学上正方形就是长方形的子类!,-63-,-64-,开始设计:正方形,public class Rectangle private int width;private int height;public void setWidth(int w) width = w;public int getWidth() return width;public void setHeight(int h) height = h;public int getHeight() return height; ,public class Squa

17、re extends Rectangle public void setWidth(int w) super.setWidth (w);super.setHeight (w);public void setHeight(int h) super.setWidth (h);super.setHeight (h) ; ,-65-,设计方案正确吗?,public static void resize(Rectangle r) while (r.getHeight() = r.getWidth() r.setHeight(r.getHeight() + 1);System.out.println(“I

18、ts OK.“);,第一种情况:使用长方形Rectangle r1 = new Rectangle(); r1.setHeight(5); r1.setWidth(15); resize(r1);,第二种情况:使用正方形Rectangle r2 = new Square(); r2.setHeight(5); r2.setWidth(15); resize(r2);,-66-,问题?,使用父类(长方形)时,程序正常运行 使用子类(正方形)时,程序陷入死循环 设计出问题了?继承出问题了?,-67-,为什么会出现问题?,违背了面向对象的设计原则!,-68-,面向对象的设计原则,什么是面向对象设计原

19、则? 面向对象设计原则有什么意义? 是指导面向对象设计的基本指导思想 是评价面向对象设计的价值观体系 是设计模式的出发点和归宿,-69-,设计目标,设计目标 重用性(Reusability) 可扩展性 (Extensibility) 灵活性 (Flexibility) 可插入性 (Pluggability) 保持系统稳定,-70-,设计质量:坏的设计,什么是坏的设计? 僵硬性(Rigidity):刚性,难以扩展 脆弱性(Fragility):易碎,难以修改 牢固性(Immobility):无法分解成可移植的组件 不必要的复杂性(Needless Repetition):Ctrl C + Ctr

20、l V 晦涩性(Opacity):不透明,很难看清设计者的真实意图,-71-,设计质量:好的设计,什么是好的设计? 容易理解 容易修改和扩展 容易复用 容易实现与应用 简单、紧凑、经济适用让人工作起来心情愉快的设计,-72-,面向对象的一些基本设计原则,LSP:Liskov替换原则 The Liskov Substitution Principle OCP:开放-封闭原则 The Open-Close Principle SRP:单一职责原则 The Single Responsibility Principle ISP:接口隔离原则 The Interface Segregation Pri

21、nciple DIP:依赖倒置原则 The Dependency Inversion Principle FCOI:优先使用组合,而非继承 Favor Composition Over Inheritance ,-73-,1.LSP,LSP(The Liskov Substitution Principle, Liskov替换原则) “若对于类型S的任一对象o1,均有类型T的对象o2存在,使得在T定义的所有程序P中,用o1替换o2之后,程序的行为不变,则S是T的子类型” 如果在任何情况下,子类(或子类型)或实现类与基类都是可以互换的,那么继承的使用就是合适的。为了达到这一目标,子类不能添加任何

22、父类没有的附加约束,-74-,Barbara Liskov,2008年度美国计算机学会(ACM)图灵奖(Turing Award)获得者。美国国家工程院院士、美国计算机学会会员、以及美国艺术与科学院院士。,-75-,换句话说,LSP替换原则就是指任何父类可以出现的地方,子类都可以了出现. “子类对象必须可以替换基类对象” 例如:假设有两个类Base和Derived,且Derived是Base的子类,如果有 method1(Base b) 且 d是Derived的一个对象 那么method1(d)同样成立. 但反过来不成立.,-76-,在C+ +中公有派生表达的是ISA的关系,A is a B,

23、即意味着A是B的一个子类型,即在C+中公有派生表达子类型的概念。Liskov替换原则在C+中就表达了这样一个意思,如果子类是公有派生的,那么父类或父类的所有子类,他们所形成的对象之间必须应该可以相互替换,替换之后,替换的上下文依然保持逻辑上的完整与一致。,-77-,Java语言对LSP的支持,右边的继承关系在Java编译器编译的时候会出现什么问题?原因是什么?,-78-,违背LSP原则,Square类针对height、width添加了Rectangle所没有的附加的约束(即要求height=width),这样Square类(子类)不能完全替换Rectangle(父类)违背了LSP原则带来潜在的

24、设计问题(使用resize方法时,子类出错!),-79-,怎么办?,在可能的情况下,由抽象类(接口)继承,-80-,抽象类与具体类,只要有可能,不要从具体类继承 行为集中的方向是向上的(抽象类) 数据集中的方向是向下的(具体类),-81-,上述长方形与正方形例子的解决方案,-82-,重构后的代码,public interface Quadrangle public Long getWidth(); public Long getHeight(); ,public static void resize(Rectangle r) while (r.getHeight() = r.getWidth(

25、) r.setHeight(r.getHeight() + 1); ,第一种情况:使用长方形 Rectangle r1 = new Rectangle(); r1.setHeight(5); r1.setWidth(15); resize(r1);,第二种情况:使用正方形 Rectangle r2 = new Square(); r2.setHeight(5); r2.setWidth(15); resize(r2);,-83-,程序语言中的SubClass与SubType是否等价,SubClass和SubType是否等价?P.America 给Subtyping作了如下定义:类型S是类型T的

26、子类型(Subtype),记为ST,如果总有:任何属于S的对象也属于T。换句话可叙述为:S是T的子类型,若对任何对象,它满足S的规范意味着它也满足T的规范。,-84-,现今的许多面向对象语言,如Java, C#都是采用了这种技术subclassing-implies-subtyping. 除此之外,还有一种称作inheritance-is-not-subtyping的方法,通过完全割裂subclassing和subtyping之间的联系而在更大程度上方便了代码的重用。,-85-,可替换性、Covariant协变和Contravariant反变规则,在面向对象系统及构件技术的研究中,经常涉及到可

27、替换性:Principle of Substitutability:An instance of a subtype can always be used in any context in which an instance of a supertype was expected.,-86-,Covariant (协变或共变)Rule:父类型的方法必须出现在子类型中,并且父类型中方法的结果类型是子类型中相应方法的结果类型的子类型; Contravariant (反变)Rule:父类型的方法必须出现在子类型中,并且父类型中方法的参数类型是子类型中相应方法的参数类型的父类型;在这些原则和规则基础

28、上,可以讨论各种Subtyping关系,这也构成了Java、C+和.Net等各种语言中的泛型机制以及契约编程(Design by contract)的基础。,-87-,Covariant规则和Contravariant规则,Covariant和Contravariant说明了在Subtyping概念下,Subclass方法与Superclass方法之间的参数类型和结果类型可以不一致,只要满足: (1)结果类型之间遵守Covariant规则 (2)参数类型之间遵守Contravariant规则:,-88-,Inheritance与Subtyping的不同,inheritance是在代码层次上作修

29、改,而subtyping是在语义层次上作修改。前者是代码共享的一种重要途径,但不能保证subclass能够继承superclass的行为;后者要求subtype保持supertype的某种外部可观察行为(或语义行为),同代码没有关系。,-89-,Inheritance层次关系可以理解为“is_similar_to”(或“like”)的关系,Subtyping可以理解成“is_a”关系(即“从某种语义行为来看,B是A的subtype 每个B的实例is_a A的实例”)。,-90-,小结,Liskov替换法则(LSP)清楚地表明了ISA关系全部都是与行为有关的。 为了保持LSP,所有子类必须符合使

30、用基类的client所期望的行为。 一个子类型不得具有比基类型更多的限制,可能这对于基类型来说是合法的,但是可能会因为违背子类型的其中一个额外限制,从而违背了LSP! LSP保证一个子类总是能够被用在其基类可以出现的地方,-91-,参考文献,1. P.America. Designing an Object-oriented Programming Language with Behavioural Subtyping. In Proc. of REX School/Workshop on Foundations of Object-oriented Languages(REX/FOOL),

31、Noordwijkerhout, the Netherlands, May, 1990, LNCS 489, Springer-verlag, 1991, pp60-902. P.Wegner, S.B.Zdonik. Inheritance as an Incremental Modification Mechanism or What Like is and Isnt Like. In ECOOP88 Proc. LNCS 322, Springer-Verlag, 1988, pp 55-77. 3.B.Liskov and J.M.Wing. A behavioural notion

32、of subtyping. ACM Transaction on Programming Languages and Systems, 1994, Vol. 16, No.6., Nov., pp1811-1841.,-92-,2. Open-Close Principle(OCP原则),1988年,Bertrand Meyer在他的著作Object Oriented Software Construction中提出了开闭原则.原文:“Software entities should be open for extension, but closed for modification”。“软件

33、实体应当对扩展开放,对修改关闭”,-93-,OCP,OCP(The Open-Close Principle, 开放-封闭原则) 软件实体(类、模块、函数等)应该是可扩展的,但是不可修改的 特征: 对于扩展是开放的(Open for extension):模块的行为可以扩展,当应用的需求改变时,可以对模块进行扩展,以满足新的需求 对于更改是封闭的(Closed for modification):对模块行为扩展时,不必改动模块的源代码或二进制代码,-94-,OCP的关键在于抽象,OCP的关键在于抽象 抽象技术:abstract class, Interface 抽象预见了可能的所有扩展(闭)

34、由抽象可以随时导出新的类(开),-95-,OCP原则,OCP原则认为应该试图去设计出永远也不需要改变的模块。关键在于抽象化:可给系统定义一个一劳永逸,不再更改的抽象设计,此设计允许有无穷无尽的行为在实现层被实现。抽象层预见所有扩展。,-96-,范例:手与门,如何在程序中模拟用手去开门和关门? 行为: 开门(open) 关门(close) 判断门的状态(isOpened),-97-,设计实现,public class Door private boolean _isOpen=false;public boolean isOpen()return _isOpen;public void open(

35、)_isOpen = true;public void close()_isOpen = false; ,public class Hand public Door door;void do() if (door.isOpen()door.close();elsedoor.open(); ,public class SmartTest public static void main(String args) Hand myHand = new Hand();myHand.door = new Door();myHand.do(); ,-98-,新的需求,需要手去开关抽屉,冰箱?,我们只好去修改

36、程序!,-99-,解决新的需求:修改设计,public class Hand public Door door;public Drawer drawer;void do(int item) switch (item)case 1:if (door.isOpen()door.close();else door.open();break;case 2:if (drawer.isOpen()drawer.close();else drawer.open();break; ,public class SmartTest public static void main(String args) Hand

37、 myHand = new Hand();myHand.door = new Door();myHand.do(1); ,手被改了! 主(使用手)程序也被改了!,-100-,符合OCP的设计方案,public interface Excutable public boolean isOpen();public void open();public void close(); ,-101-,新的实现,public class Door implements Excutable private boolean _isOpen = false;public boolean isOpen() retu

38、rn _isOpen;public void open() _isOpen = true;public void close() _isOpen = false; ,public class Hand public Excutable item;void do() if (item.isOpen()item.close();elseitem.open(); ,public class Drawer implements Excutable private boolean _isOpen = false;public boolean isOpen() return _isOpen;public

39、void open() _isOpen = true;public void close() _isOpen = false; ,public class SmartTest public static void main(String args) Hand myHand = new Hand();myHand.item = new Door();myHand.do(); ,-102-,新的需求,需要手去开关冰箱?,为冰箱实现Excutable接口 不需要修改任何原有的设计和代码,public class Refrigerator implements Excutable private bo

40、olean _isOpen = false;public boolean isOpen() return _isOpen;public void open() _isOpen = true;public void close() _isOpen = false; ,-103-,关于OCP,OCP是OOD中很多说法的核心 如果这个原则应用得有效,应用程序就会具有更多的可维护性、可重用性以及可健壮性 很多设计模式都是遵从这个原则而提出来的LSP是OCP成为可能的主要原则之一 正是子类型的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展 一个软件系统的所有模块不可能都满足OCP,但是应该

41、努力最小化这些不满足OCP的模块数量。,-104-,3. SRP,SRP(The Single Responsibility Principle, 单一职责原则) 就一个类而言,应该仅有一个引起它变化的原因有关类的职责分配问题,是面向对象设计中最重要的基本原则,“A critical, fundamental ability in OOA/D is to skillfully assign responsibility to software components.”Craig Larman,-105-,SRP本质,SRP体现了内聚性(Cohesion) 内聚性:一个模块的组成元素之间的功能相

42、关性类的职责定义为“变化的原因”,每个职责都是变化的一个轴线;当需求变化时,该变化会反映为类的职责的变化 如果一个类承担了多于一个的职责,那么引起它变化的原因就会有多个,-106-,违反SRP的案例,Rectangle类可能会因为两方面的原因而变化:计算几何方面的原因和用户界面设计方面的原因。其中之一发生变化之后,必须修改Rectangle类,而这种修改则可能导致另一个应用程序出错 除此之外,违反SRP还会带来物理依赖的缺点,-107-,解决方案,增加新的类,使得每个类仅有一个职责,-108-,4. ISP,ISP( The Interface Segregation Principle,接口

43、隔离原则)客户不应该依赖他们不用到的方法,只给每个客户它所需要的接口为了避免“肥接口(fat interface)”,应当以一个类实现多个接口,而各客户仅仅获知必须的接口,-109-,接口污染,需求:一扇能超时报警的门 Door Open() Close() Timeout()当需要其它的门时习惯性从Door中继承 问题在哪儿? 所有的门都拥有timeout接口,即便它不需要,-110-,解决方案:分离接口,(1)使用委托分离接口 Adapter模式,(2)使用多重继承分离接口,-111-,ISP本质,使用多个专门的接口比使用单一的接口好一个类对另一个类的依赖性应当是建立在最小的接口上的避免接

44、口污染(Interface Pollution),-112-,5. DIP,DIP(依赖倒置原则,The Dependency Inversion Principle) 高层模块不应该依赖于低层模块。二者都应该依赖于抽象 抽象不应该依赖于细节。细节应该依赖于抽象 针对接口编程,不要针对实现编程Booch:所有结构良好的面向对象架构都具有清晰的层次定义,每个层次通过一个定义良好的、受控的接口向外提供了一组内聚的服务,-113-,传统的依赖关系,依 赖 的 方 向,-114-,符合DIP的系统,依 赖 的 方 向,依 赖 的 方 向,-115-,启发式原则,“依赖于抽象”程序中所有依赖关系都应该终

45、止于抽象类或者接口启发式原则: 任何变量都不应该拥有指向具体类的指针或者引用 任何类都不应该从具体类派生 任何方法都不应该改写其任何基类中已经实现的方法,-116-,DIP的本质,通过抽象提取业务本质,并建立一个稳定的结构描述这个本质对于具体的业务规则是在这个本质的基础上的扩展技术、工具、意识形态等的发展可能使业务规则不断变化,但本质不变;而DIP则帮助我们轻松的适应这些变更,-117-,使用接口的优点,Client不必知道其使用对象的具体所属类。 一个对象可以很容易地被(实现了相同接口的)另一个对象所替换。 对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。

46、松散藕合(loosens coupling)。 增加了重用的可能性。 提高了(对象)组合的机率,因为被包含对象可以是任何实现了一个指定接口的类。,-118-,针对接口编程,不将变量声明为某个特定的具体类的实例对象,而让其遵从抽象类定义的接口。实现类仅实现接口,不添加方法。 例如. 应该使用Draw(shape*p),而不要使用 不要Cricle*p、Rectangle *p或Triangle *p),-119-,依赖于抽象,任何变量都不应该持有一个指向具体类的指针或引用 任何类都不应该从具体类派生 任何方法都不应该覆写它的任何基类中已实现了的方法,-120-,约束,如果一个类的实例必须使用另一

47、个对象,而这个对象又属于一个特定的类,那么复用性会受到损害。 如果“使用”类只需使用“被使用”类的某些方法,而不是要求“被使用”类与“使用”类有“is-a”的关系,就可考虑让“被使用”类实现一个接口,“使用”类通过这个接口来使用需要的方法,从而限制了类之间的依赖。 方案:为避免类之间因彼此使用而造成的耦合,让它们通过接口间接使用。,-121-,6. 组合复用原则,优先使用(对象)组合,而非(类)继承 Favor Composition Over Inheritance,-122-,组合优点,容器类仅能通过被包含对象的接口来对其进行访问。 “黑盒”复用,因为被包含对象的内部细节对外是不可见。 封

48、装性好。 实现上的相互依赖性比较小。 每一个类只专注于一项任务。 通过获取指向其它的具有相同类型的对象引用,可以在运行期间动态地定义(对象的)组合。,-123-,组合缺点,从而导致系统中的对象过多。 为了能将多个不同的对象作为组合块(composition block)来使用,必须仔细地对接口进行定义。,-124-,继承,(类)继承是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。 泛化类(超类)可以显式地捕获那些公共的属性和方法。 特殊类(子类)则通过附加属性和方法来进行实现的扩展,-125-,继承优点,容易进行新的实现,因为其大多数可继承而来。 易于修改或扩展那些被复用的实现。,

49、-126-,继承缺点,破坏了封装性,因为这会将父类的实现细节暴露给子类。 “白盒”复用,因为父类的内部细节对于子类而言通常是可见的。 当父类的实现更改时,子类也不得不会随之更改。 从父类继承来的实现将不能在运行期间进行改变。,-127-,仅当下列的所有标准被满足时,方可使用继承: 子类表达了“是一个的特殊类型”,而非“是一个由所扮演的角色”。 子类的一个实例永远不需要转化(transmute)为其它类的一个对象。 子类是对其父类的职责(responsibility)进行扩展,而非重写或废除(nullify)。 子类没有对那些仅作为一个工具类(utility class)的功能进行扩展。,-128-,小结,组合与继承都是重要的重用方法 在OO开发的早期,继承被过度地使用 随着时间的发展,我们发现优先使用组合可以获得重用性与简单性更佳的设计 当然可以通过继承,以扩充可用的组合类集。 因此组合与继承可以一起工作 但是基本法则是:优先使用对象组合,而非(类)继承,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报