第8章面向对象设计原则_第1页
第8章面向对象设计原则_第2页
第8章面向对象设计原则_第3页
第8章面向对象设计原则_第4页
第8章面向对象设计原则_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、面向对象建模技术面向对象建模技术第第8章章 面向对象设计原则面向对象设计原则第第2章章 面向对象设计原则面向对象设计原则n本章导读本章导读n软件的可维护性与可复用性软件的可维护性与可复用性n“开放开放-封闭封闭”原则(原则(OCP)n接口和抽象类接口和抽象类n里氏代换原则(里氏代换原则(LSP)n依赖倒置原则(依赖倒置原则(DIP)n接口隔离原则(接口隔离原则(ISP)n组合组合/聚合复用原则(聚合复用原则(CARP)n迪米特法则(迪米特法则(LoD)软件的可维护性与可复用性软件的可维护性与可复用性软件开发的目标软件开发的目标n可维护性(可维护性(Maintainability)n可复用性(可

2、复用性(Reusability)兔子兔子兔子兔子?软件的可维护性软件的可维护性n一个电视机,一用就是好几年,我们很少要求一个电视机,一用就是好几年,我们很少要求把一台黑白电视机升级成彩色电视机,或者把把一台黑白电视机升级成彩色电视机,或者把一个小电视机升级成大的电视机一个小电视机升级成大的电视机n软件则不同,问题在使用过程中逐步被发现,软件则不同,问题在使用过程中逐步被发现,新的需求层出不穷新的需求层出不穷n开发一个软件可能只需要半年,维护一个软件开发一个软件可能只需要半年,维护一个软件可能至少两年以上可能至少两年以上n软件的维护成本远远大于开发成本软件的维护成本远远大于开发成本n随着系统的不

3、断升级维护,系统逐渐演化成一随着系统的不断升级维护,系统逐渐演化成一个个“腐败腐败”的系统的系统软件的可维护性差的原因软件的可维护性差的原因n过于僵硬过于僵硬q很难在现有软件中增加新功能,增加新功能可能会很难在现有软件中增加新功能,增加新功能可能会修改很多现有的模块修改很多现有的模块n过于脆弱过于脆弱q对一个地方的修改往往会使不相干的模块出现故障对一个地方的修改往往会使不相干的模块出现故障n复用率低复用率低q想复用现有代码时发现它们还依赖于一大堆东西想复用现有代码时发现它们还依赖于一大堆东西n黏度过高黏度过高q系统升级或修改时如果破坏原始设计总是比保持原系统升级或修改时如果破坏原始设计总是比保

4、持原始设计更容易始设计更容易设计的目标设计的目标n可扩展的可扩展的q新功能很容易加入到现有系统中去新功能很容易加入到现有系统中去n灵活的灵活的q允许代码修改平稳的发生,而不会波及到其他很多允许代码修改平稳的发生,而不会波及到其他很多模块模块n可插入的可插入的q很容易将现有的组件用新的组件代替很容易将现有的组件用新的组件代替传统的软件复用传统的软件复用nCtrl C Ctrl Vn函数函数n算法的复用算法的复用n数据结构的复用数据结构的复用可复用性与可维护性的关系可复用性与可维护性的关系n传统的复用方法往往容易破坏可维护性传统的复用方法往往容易破坏可维护性n真正需要的是支持可维护性的复用真正需要

5、的是支持可维护性的复用面向对象设计的复用面向对象设计的复用n面向对象中的抽象、封装、继承、多态在更高面向对象中的抽象、封装、继承、多态在更高层次上实现复用层次上实现复用q抽象和继承使得概念和定义可复用抽象和继承使得概念和定义可复用q多态使得实现可复用多态使得实现可复用q抽象和封装可以保持和促进系统的可维护性抽象和封装可以保持和促进系统的可维护性n重用不仅体现在函数和算法这样的实现细节上重用不仅体现在函数和算法这样的实现细节上n面向对象的面向对象的可维护性复用可维护性复用是以是以原则原则和和设计模式设计模式为基础的为基础的设计的目标设计的目标n可扩展性和可插入性可扩展性和可插入性q“开放开放-封

6、闭封闭”原则原则q里氏代换原则里氏代换原则q依赖倒置原则依赖倒置原则q组合组合/聚合复用原则聚合复用原则n灵活性灵活性q“开放开放-封闭封闭”原则原则q迪米特法则迪米特法则q接口隔离原则接口隔离原则 “开放开放-封闭封闭”原则(原则(OCP)什么是什么是“开放开放-封闭封闭”原则原则nSoftware entties should be open for extension, but closed for modification.qBertrand MeyerMEYER88n一个软件实体应该对扩展开放,对修改关闭一个软件实体应该对扩展开放,对修改关闭进一步解释进一步解释“开放开放-封闭封闭”

7、原则原则n通过扩展已有的软件系统,可以提供新的行为,通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性有一定的适应性和灵活性n已有的软件模块,特别是最重要的抽象层模块已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软件系统有一定不能再修改,这就使变化中的软件系统有一定的稳定性和延续性的稳定性和延续性具有这两个优点的软件系统是一个具有这两个优点的软件系统是一个在高层次上在高层次上实现了复用实现了复用的系统,也是一个的系统,也是一个易于维护易于维护的系统的系统怎样做到怎样做到“开放开放-

8、封闭封闭”原则原则n玉帝招安美猴王玉帝招安美猴王q孙悟空说:皇帝轮流做,明年到我家孙悟空说:皇帝轮流做,明年到我家q太白金星:降一道招安圣旨太白金星:降一道招安圣旨不更改现有天庭秩序,将妖猴纳入现有秩序中不更改现有天庭秩序,将妖猴纳入现有秩序中怎样做到怎样做到“开放开放-封闭封闭”原则原则n抽象化是关键抽象化是关键q定义出一劳永逸、不再更改的抽象设计定义出一劳永逸、不再更改的抽象设计q将无穷无尽的行为在实现层被实现将无穷无尽的行为在实现层被实现q在在Java中用抽象类和接口规定出所有具体类必须提中用抽象类和接口规定出所有具体类必须提供的方法特征(供的方法特征(Signature)作为系统设计的

9、抽象)作为系统设计的抽象层,让抽象层能够预见所有的可能扩展,在任何情层,让抽象层能够预见所有的可能扩展,在任何情况下系统抽象层都不需要修改,满足况下系统抽象层都不需要修改,满足“开放开放=封闭封闭”原则的原则的“关闭关闭”,即,即对修改是关闭的对修改是关闭的q由抽象层导出一个或多个新的具体类可以改变系统由抽象层导出一个或多个新的具体类可以改变系统的行为,即系统的设计的行为,即系统的设计对扩展是开放的对扩展是开放的,满足,满足“开开放放-封闭封闭”原则的原则的“开放开放”里氏代换原则里氏代换原则n任何基类可以出现的地方,子类一定可以出现任何基类可以出现的地方,子类一定可以出现n里氏代换原则是对里

10、氏代换原则是对“开放开放-封闭封闭”原则的补充原则的补充n违反了里氏代换原则也会违背违反了里氏代换原则也会违背“开放开放-封闭封闭”原则,反过来并不一定成立原则,反过来并不一定成立n里氏代换原则是实现里氏代换原则是实现“开放开放-封闭封闭”原则的原则的必必要条件要条件依赖倒置原则依赖倒置原则n要依赖于抽象,不要依赖于实现要依赖于抽象,不要依赖于实现n“开放开放-封闭封闭”原则是目标,依赖倒置原则是原则是目标,依赖倒置原则是实现这一目标的手段实现这一目标的手段n要实现要实现“开放开放-封闭封闭”原则就必须坚持依赖倒原则就必须坚持依赖倒置原则,违反依赖倒置原则就不可能达到置原则,违反依赖倒置原则就

11、不可能达到“开开放放-封闭封闭”原则的要求原则的要求组合组合/聚合复用原则聚合复用原则n要尽量使用组合要尽量使用组合/聚合,而不是继承关系达到聚合,而不是继承关系达到复用的目的复用的目的n组合组合/聚合复用原则与里氏代换原则是相辅相聚合复用原则与里氏代换原则是相辅相成的,两者都是对实现成的,两者都是对实现“开放开放-封闭封闭”原则的原则的具体步骤的规范具体步骤的规范n组合组合/聚合复用原则要求设计师首先考虑组合聚合复用原则要求设计师首先考虑组合/聚合关系,里氏代换原则要求使用继承关系时,聚合关系,里氏代换原则要求使用继承关系时,必须确定这个关系是符合一定条件的必须确定这个关系是符合一定条件的n

12、组合组合/聚合复用原则是实现聚合复用原则是实现“开放开放-封闭封闭”原则原则的的必要条件必要条件迪米特法则迪米特法则n一个软件实体应当与尽可能少的其他实体发生一个软件实体应当与尽可能少的其他实体发生相互作用相互作用n符合迪米特法则设计的系统,在功能需要扩展符合迪米特法则设计的系统,在功能需要扩展时时不会将修改的压力传递给其他模块不会将修改的压力传递给其他模块,即相对,即相对更容易地做到对修改的更容易地做到对修改的“封闭封闭”n迪米特法则是一条通向迪米特法则是一条通向“开放开放-封闭封闭”原则的原则的道路道路接口隔离原则接口隔离原则n应该为客户提供尽可能小的单独的接口,而不应该为客户提供尽可能小

13、的单独的接口,而不要提供大的总接口要提供大的总接口n接口隔离原则与迪米特法则都是对一个软件实接口隔离原则与迪米特法则都是对一个软件实体与其他的软件实体的通信的限制体与其他的软件实体的通信的限制n迪米特法则要求尽可能迪米特法则要求尽可能限制限制通信的通信的宽度宽度和和深度深度n接口隔离原则接口隔离原则限制限制的是通信的的是通信的宽度宽度,即通信应,即通信应该尽可能的窄该尽可能的窄n都是保证软件在功能扩展过程中不会将修改的都是保证软件在功能扩展过程中不会将修改的压力传递到其他的模块压力传递到其他的模块接口和抽象类接口和抽象类为什么使用接口为什么使用接口n接口保证代码的可插入性接口保证代码的可插入性

14、没有接口会怎样没有接口会怎样n上一页中的例子能否用抽象的父类代替接口上一页中的例子能否用抽象的父类代替接口接口的另一个作用接口的另一个作用n接口可以为类提供混合类型接口可以为类提供混合类型n使得单继承的使得单继承的Java具有多继承语言的特性具有多继承语言的特性接口的常见用法接口的常见用法n多方法接口多方法接口n单方法接口单方法接口qRunnableqActionListenern标识接口标识接口qCloneableqSerializablen常量接口常量接口qSwingConstants 抽象类抽象类n所有的父类都应该是抽象类所有的父类都应该是抽象类n具体类不是用来继承的具体类不是用来继承的

15、n抽象类应拥有尽可能多的代码抽象类应拥有尽可能多的代码n抽象类应拥有尽可能少的数据抽象类应拥有尽可能少的数据重构不合理的继承重构不合理的继承n继承一定要符合里氏代换原则继承一定要符合里氏代换原则什么时候使用继承复用什么时候使用继承复用n满足子类满足子类 is a 父类父类n子类具有扩展超类的责任,而不是置换掉超类子类具有扩展超类的责任,而不是置换掉超类的责任,子类不能大量置换(的责任,子类不能大量置换(Override)掉父)掉父类的行为类的行为接口和抽象类的区别接口和抽象类的区别n接口只定义子类行为,实现同一个接口的子类接口只定义子类行为,实现同一个接口的子类可能没有任何联系可能没有任何联系

16、n接口描述其子类具有的能力接口描述其子类具有的能力n子类和抽象父类之间的子类和抽象父类之间的 is a 特点更强特点更强n子类和父接口之间的子类和父接口之间的is a特点不强,更强调子特点不强,更强调子类具有的一种能力类具有的一种能力n抽象类一般是名词抽象类一般是名词n接口一般是形容词,也可以是名词接口一般是形容词,也可以是名词接口和抽象类的区别接口和抽象类的区别里氏代换原则(里氏代换原则(LSP)什么是里氏代换原则什么是里氏代换原则n定义定义q如果对每一个类型为如果对每一个类型为T1的对象的对象o1,都有类型为,都有类型为T2的对象的对象o2,使得以,使得以T1定义的所有程序定义的所有程序P

17、在所有的对在所有的对象象o1都代换成都代换成o2时,程序时,程序P的行为没有变化,那么的行为没有变化,那么类型类型T2是类型是类型T1的子类型的子类型n作用作用q里氏代换原则是指导继承复用的标准里氏代换原则是指导继承复用的标准q只有当子类可以替换掉基类并且软件的功能不受影只有当子类可以替换掉基类并且软件的功能不受影响时,才可以使用继承复用响时,才可以使用继承复用长方形和正方形长方形和正方形n正方形是长方形的子类吗?正方形是长方形的子类吗?n圆是椭圆的子类吗?圆是椭圆的子类吗?代码:代码:comjavapatternsliskovversion2代码:代码:comjavapatternslisk

18、ovversion3依赖倒置原则(依赖倒置原则(DIP)怎样理解怎样理解 Inversionn传统的面向过程系统传统的面向过程系统依赖方向依赖方向业务调用者业务调用者中层模块中层模块中层模块中层模块中层模块中层模块底层模块底层模块底层模块底层模块底层模块底层模块底层模块底层模块怎样理解怎样理解 Inversionn面向对象系统面向对象系统依赖方向依赖方向业务调用者业务调用者抽象层抽象层抽象层抽象层抽象层抽象层实现层实现层实现层实现层实现层实现层依赖倒置原则的表述依赖倒置原则的表述n抽象不应该依赖于细节;细节应该依赖于抽象抽象不应该依赖于细节;细节应该依赖于抽象n要针对抽象编程,不要针对实现编程

19、要针对抽象编程,不要针对实现编程q应使用应使用Java接口和抽象类进行变量的类型声明、方接口和抽象类进行变量的类型声明、方法参数的类型声明、方法返回类型声明以及数据类法参数的类型声明、方法返回类型声明以及数据类型的转换等型的转换等q要保证做到这一点,一个具体要保证做到这一点,一个具体Java类应只实现接口类应只实现接口和抽象类中声明的方法,而不应给出多余的方法和抽象类中声明的方法,而不应给出多余的方法依赖倒置原则的优缺点依赖倒置原则的优缺点n使用依赖倒置原则,对象的创建很可能要使用使用依赖倒置原则,对象的创建很可能要使用对象工厂,以避免直接对具体类进行引用,此对象工厂,以避免直接对具体类进行引

20、用,此原则会导致大量的类原则会导致大量的类n依赖倒置原则假定所有的具体类都是会变化的,依赖倒置原则假定所有的具体类都是会变化的,有些时候一些具体类是相当稳定、不会变化的,有些时候一些具体类是相当稳定、不会变化的,消费这样的类时完全可以不必为其发明一个抽消费这样的类时完全可以不必为其发明一个抽象类型象类型依赖倒置之经典:回调依赖倒置之经典:回调nC语言的函数指针语言的函数指针nC#的的Delegaten事件处理中的监听器接口事件处理中的监听器接口q例如例如Java中的中的ActionListenern以上这些统统都是回调,典型的依赖倒置以上这些统统都是回调,典型的依赖倒置n案例:案例:q回调在回

21、调在“分割文件时显示进度条分割文件时显示进度条”案例中的应用案例中的应用代码:代码:callbackHello.java和和FileUtils.java接口隔离原则(接口隔离原则(ISP)什么是接口隔离原则什么是接口隔离原则n一个类对另外一个类的依赖应该是建立在最小一个类对另外一个类的依赖应该是建立在最小的的“接口接口”上的上的n接口有接口有两层含义两层含义q一个类所提供的所有方法的集合,是这个类对外提一个类所提供的所有方法的集合,是这个类对外提供服务的供服务的“接口接口”q另一个接口就是特制另一个接口就是特制Java中的中的interface接口即角色接口即角色n一个接口相当于剧本中的一种角

22、色,而此角色一个接口相当于剧本中的一种角色,而此角色由哪一个演员来演相当于接口的实现由哪一个演员来演相当于接口的实现n一个接口应当简单地代表一个角色,而不是多一个接口应当简单地代表一个角色,而不是多个角色个角色n如果系统涉及多个角色,那么每一个角色都应如果系统涉及多个角色,那么每一个角色都应该由一个特定的接口代表该由一个特定的接口代表分割角色、定制服务分割角色、定制服务组合组合/聚合复用原则(聚合复用原则(CARP)什么是组合什么是组合/聚合复用原则聚合复用原则n要尽量使用组合要尽量使用组合/聚合,而不是继承关系达到聚合,而不是继承关系达到复用的目的复用的目的组合与聚合的区别组合与聚合的区别n

23、组合和聚合均是关联的特殊种类组合和聚合均是关联的特殊种类n聚合表示聚合表示“拥有拥有”关系或者整体与部分的关系关系或者整体与部分的关系n组合表示一种更强的组合表示一种更强的“拥有拥有”关系。在一个组关系。在一个组合关系里,部分和整体的生命周期是一样的。合关系里,部分和整体的生命周期是一样的。一个组合的新的对象完全拥有对其组成部分的一个组合的新的对象完全拥有对其组成部分的支配权,包括它们的创建和销毁等支配权,包括它们的创建和销毁等n使用程序语言的术语讲,组合而成的新对象对使用程序语言的术语讲,组合而成的新对象对组成部分的内存分配、内存释放有绝对的责任组成部分的内存分配、内存释放有绝对的责任组合与

24、聚合的区别组合与聚合的区别nJava中的聚合和组合在代码上没有分别中的聚合和组合在代码上没有分别组合与聚合的区别组合与聚合的区别nC+中的聚合和组合在代码上的差别中的聚合和组合在代码上的差别组合组合/聚合复用的好处聚合复用的好处 n组合对象存取成分对象的唯一方法是通过成分组合对象存取成分对象的唯一方法是通过成分对象的接口(方法)对象的接口(方法)n这种复用是黑箱复用,因为成分对象的内部细这种复用是黑箱复用,因为成分对象的内部细节是组合对象所看不见的节是组合对象所看不见的 n这种复用比继承复用的依赖更小这种复用比继承复用的依赖更小继承复用继承复用n新的实现较为容易,因为超类的大部分功能可新的实现

25、较为容易,因为超类的大部分功能可以通过继承关系自动进入子类以通过继承关系自动进入子类 n修改或扩展继承而来的实现较为容易修改或扩展继承而来的实现较为容易n继承是为多态服务的,而不是为了复用继承是为多态服务的,而不是为了复用n如果超类的实现发生变化,那么子类的实现也如果超类的实现发生变化,那么子类的实现也不得不发生变化。因此当一个基类发生改变时,不得不发生变化。因此当一个基类发生改变时,这种改变会先像水中投入石子引起来的水波一这种改变会先像水中投入石子引起来的水波一样,将变化一圈又一圈地传导到一级又一级的样,将变化一圈又一圈地传导到一级又一级的子类,使设计师不得不相应地改变这些子类,子类,使设计

26、师不得不相应地改变这些子类,以适应超类的变化以适应超类的变化 将继承转换成组合将继承转换成组合/聚合聚合迪米特法则(迪米特法则(LoP)什么是迪米特法则什么是迪米特法则n又称又称最少知道原则最少知道原则n只与你直接的朋友通信只与你直接的朋友通信n不要跟不要跟“陌生人陌生人”说话说话n一个对象应当对其他对象有尽可能少的了解一个对象应当对其他对象有尽可能少的了解n如果两个类不必彼此直接通信,那么这两个类如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用就不应该发生直接的相互作用n如果其中的一个类需要调用另一个类的某一个如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者

27、转发这个调用方法的话,可以通过第三者转发这个调用迪米特法则迪米特法则朋友和陌生人朋友和陌生人n什么是朋友什么是朋友q当前对象本身(当前对象本身(this)q当前对象的实例变量直接引用的对象当前对象的实例变量直接引用的对象q当前对象所创建的对象当前对象所创建的对象q以参数形式传入到当前对象方法中的对象以参数形式传入到当前对象方法中的对象q当前对象的实例变量如果是一个聚集,那么聚集中当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友的元素也都是朋友n什么是陌生人什么是陌生人q满足上面条件之一就是朋友,不满足就是陌生人满足上面条件之一就是朋友,不满足就是陌生人不满足迪米特法则的系统不满足迪米特法则的系统nSomeone与与Friend是朋友是朋友nFriend与与Stranger是朋友是朋友nSomeone不认识不认识Stranger不满足迪米特法则的系统不满足迪米特法则的系统nSomeone不满足迪米特法则的系统不

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论