对面向对象设计原则的总结计算机C资料计算机C++资料.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《对面向对象设计原则的总结计算机C资料计算机C++资料.pdf》由会员分享,可在线阅读,更多相关《对面向对象设计原则的总结计算机C资料计算机C++资料.pdf(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、对面向对象设计原则的总结 正如牛顿三大定律在经典力学中的位置一样,开-闭原则(Open-Closed Principle)是面向对象的可复用设计(Object Oriented Design或 OOD)的基石。其他设计原则(里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法 则、接口隔离原则)是实现 开-闭原则的手段和工具。一、开-闭原则(Open-Closed Principle,OCP)1.1 开-闭原则的定义及优点 1)定义:一个软件 实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed
2、for modification.)。即在设计一个模块的时候,应当使这个模 块可以在不被修改的前提下被扩展。2)满足 开-闭原则的系统的优点 a)通过 扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的 软件系统有一定的适应性和灵活性。b)已有的软件模块,特别是最重要的抽象层 模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。c)这样的 系统同时满足了可复用性与可维护性。正如牛顿三大定律在经典力学中的位置一样,开-闭原则(Open-Closed Principle)是面向对象的可复用设计(Object Oriented Design或 OOD)的基石。其他设计原
3、则(里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法 则、接口隔离原则)是实现 开-闭原则的手段和工具。一、“开-闭”原则(Open-Closed Principle,OCP)1.1“开-闭”原则的定义及优点 1)定义:一个软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed for modification.)。即在设计一个模块的时候,应当使 这个模块可以在不被修改的前提下被扩展。2)满足开-闭原则的系统的优点 a)通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变 化
4、中的软件系统有一定的适应性和灵活性。b)已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软 件系统有一定的稳定性和延续性。c)这样的系统同时满足了可复用性与可维护性。1.2如何实现“开-闭”原则 在面向对象设计中,不允许更改的是系统的抽象层,而允许扩展的是系统的实现 层。换言之,定义一 个一劳永逸的抽象设计层,允许尽可能多的行为在实现层被实现。解决问题关键在于抽象化,抽象化是面向对象设计的第一个核心本质。对一个事物抽象化,实质上是在概括归纳总结它的本质。抽象让我们抓住最最重 要的东西,从更高一层去思考。这降低了思考的复杂度,我们不用同时考虑那么 多的东西。换言之,我们封装了事
5、物的本质,看不到任何细节。在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对 稳定,不需更改,从而满足 对修改关闭;而从抽象类导出的具体类可以改变系 统的行为,从而满足 对扩展开放。对实体进行扩展时,不必改动软件的源代码或者二进制代码。关键在于抽象。1.3对可变性的封装原则 开-闭原则也就是 对可变性的封装原则(Principle of Encapsulation of Variation,EVP)。即找到一个系统的可变因素,将之封装起来。换言之,在你 的设计中什么可能会发生变化,应使之成为抽象层而封装,而不是什么会导致设 计改变才封装。对可变性的封装原则 意味着:a)一种
6、可变性不应当散落在代码的许多角落,而应当被封装到一个对象里面。同 一可变性的不同表象意味着同一个继承等级结构中的具体子类。因此,此处可以 期待继承关系的出现。继承是封装变化的方法,而不仅仅是从一般的对象生成特 殊的对象。b)一种可变性不应当与另一种可变性混合在一起。作者认为类图的继承结构如果 超过两层,很可能意味着两种不同的可变性混合在了一起。使用 可变性封装原则 来进行设计可以使系统遵守 开-闭原则。即使无法百分之百的做到 开-闭原则,但朝这个方向努力,可以显著改善一个 系统的结构。二、里氏代换原则(Liskov Substitution Principle,LSP)2.1概念 定义:如果对
7、每一个类型为 T1的对象 O1,都有类型为 T2 的对象 O2,使得以 T1定义的所有程序 P在所有的对象 O1 都代换为 O2时,程序 P的行为没有变 化,那么类型 T2是类型 T1 的子类型。即,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类。而且它 觉察不出基类对象和子类对象的区别。也就是说,在软件里面,把基类都替换成它 的子类,程序的行为没有变化。反过来的代换不成立,如果一个软件实体使用的是一个子类的话,那么它不一定 适用于基类。任何基类可以出现的地方,子类一定可以出现。基于契约的设计、抽象出公共部分作为抽象基类的设计。2.2 里氏代换原则与“开-闭”原则的关系 实现开-闭
8、原则的关键步骤是抽象化。基类与子类之间的继承关系就是抽象化 的体现。因此里氏代换原则是对实现抽象化的具体步骤的规范。违反里氏开闭原则或的基石其他设计原则里氏代换原则依赖倒转原则合成聚合复用原则迪米特法则接口隔离原则是实现开闭原则的手段和开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候应当使这满足对软件的新需求使变化中的软件系统有一定的适应性和灵活性已有的软件模块特别是最重要的抽象层模块不再修改这就使变化中的软件系统有一定的稳定性和延续性这样的系统同时满足了可复用性与可维护性正如牛顿三大定律迪米特法则接口隔离原则是实现开闭原则的手段和工具置一样开闭原则一开闭原则
9、开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候应当使这个模块可以在不被修改的前提下被扩展满足开代换原则意味着违反了 开-闭原则,反之未必。三、依赖倒转原则(dependence inversion principle,DIP)3.1概念 依赖倒转原则就是要依赖于抽象,不要依赖于实现。(Abstractions should not depend upon details.Details should depend upon abstraction)s.要针对接口编程,不 要针对实现编程。(Program to an interface,not an impl
10、ementation).也就是说应当使用接口和抽象类进行变量类型声明、参数类型声明、方法返还类 型说明,以及数据类型的转换等。而不要用具体类进行变量的类型声明、参数类 型声明、方法返还类型说明,以及数据类型的转换等。要保证做到这一点,一个 具体类应当只实现接口和抽象类中声明过的方法,而不要给出多余的方法。传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块,抽象 层次依赖于具体层次。倒转原则就是把这个错误的依赖关系倒转过来。面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化,具体化给出 不同的实现。继承关系就是一种从抽象化到具体化的导出。抽象层包含的应该是应用系统的商务逻辑
11、和宏观的、对整个系统来说重要的战略 性决定,是必然性的体现。具体层次含有的是一些次要的与实现有关的算法和逻 辑,以及战术性的决定,带有相当大的偶然性选择。具体层次的代码是经常变动 的,不能避免出现错误。从复用的角度来说,高层次的模块是应当复用的,而且是复用的重点,因为它含 有一个应用系统最重要的宏观商务逻辑,是较为稳定的。而在传统的过程性设计 中,复用则侧重于具体层次模块的复用。依赖倒转原则则是对传统的过程性设计方法的 倒转,是高层次模块复用及其可 维护性的有效规范。特例:对象的创建过程是违背 开闭原则以及依赖倒转 原则的,但通过工厂模式,能很好地解决对象创建过程中的依赖倒转问题。3.2关系
12、开-闭原则与依赖倒转原则是目标和手段的关系。如果说开闭原则是目标,依赖 倒转原则是到达 开闭 原则的手段。如果要达到最好的 开闭原则,就要尽量的遵 守依赖倒转原则,依赖倒转原则是对 抽象化 的最好规范。里氏代换原则是依赖倒转原则的基础,依赖倒转原则是里氏代换原则的重要补 充。3.3耦合(或者依赖)关系的种类:零耦合(Nil Coupling)关系:两个类没有耦合关系 具体耦合(Concrete Coupling)关系:发生在两个具体的(可实例化的)类之 间,经由一个类对另一个具体类的直接引用造成。抽象耦合(Abstract Coupling)关系:发生在一个具体类和一个抽象类(或接口)之间,使
13、两个必须发生关系的类之间存有最大的灵活性。开闭原则或的基石其他设计原则里氏代换原则依赖倒转原则合成聚合复用原则迪米特法则接口隔离原则是实现开闭原则的手段和开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候应当使这满足对软件的新需求使变化中的软件系统有一定的适应性和灵活性已有的软件模块特别是最重要的抽象层模块不再修改这就使变化中的软件系统有一定的稳定性和延续性这样的系统同时满足了可复用性与可维护性正如牛顿三大定律迪米特法则接口隔离原则是实现开闭原则的手段和工具置一样开闭原则一开闭原则开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候
14、应当使这个模块可以在不被修改的前提下被扩展满足开3.3.1如何把握耦合 我们应该尽可能的避免实现继承,原因如下:1 失去灵活性,使用具体类会给底层的修改带来麻烦。2 耦合问题,耦合是指两个实体相互依赖于对方的一个量度。程序员每天都在(有 意识地或者无意识地)做出影响耦合的决定:类耦合、API 耦合、应用程序耦合等 等。在一个用扩展的继承实现系统中,派生类是非常紧密的与基类耦合,而且这 种紧密的连接可能是被不期望的。如 B extends A,当 B不全用 A 中的所有 methods时,这时候,B 调用的方法可能会产生错误!我们必须客观的评价耦合度,系统之间不可能总是松耦合的,那样肯定什么也做
15、 不了。3.3.2我们决定耦合的程度的依据何在呢?简单的说,就是根据需求的稳定性,来决定耦合的程度。对于稳定性高的需求,不容易发生变化的需求,我们完全可以把各类设计成紧耦合的(我们虽然讨论类之 间的耦合度,但其实功能块、模块、包之间的耦合度也是一样的),因为这样可以 提高效率,而且我们还可以使用一些更好的技术来提高效率或简化代码,例如 c#中的内部类技术。可是,如果需求极有可能变化,我们就需要充分的考虑类之间 的耦合问题,我们可以想出各种各样的办法来降低耦合程度,但是归纳起来,不 外乎增加抽象的层次来隔离不同的类,这个抽象层次可以是抽象的类、具体的 类,也可以是接口,或是一组的类。我们可以用一
16、句话来概括降低耦合度的思 想:针对接口编程,而不是针对实现编程。在我们进行编码的时候,都会留下我们的指纹,如 public 的多少,代码的格式等 等。我们可以耦合度量评估重新构建代码的风险。因为重新构建实际上是维护编 码的一种形式,维护中遇到的那些麻烦事在重新构建时同样会遇到。我们知道在 重新构建之后,最常见的随机 bug 大部分都是不当耦合造成的。如果不稳定因素越大,它的耦合度也就越大。某类的不稳定因素=依赖的类个数/被依赖的类个数 依赖的类个数 在编译此类的时被编译的其它类的个数总和 3.3.3怎样将大系统拆分成小系统 解决这个问题的一个思路是将许多类集合成一个更高层次的单位,形成一个高内
17、 聚、低耦合的类的集合,这是我们设计过程中应该着重考虑的问题!开闭原则或的基石其他设计原则里氏代换原则依赖倒转原则合成聚合复用原则迪米特法则接口隔离原则是实现开闭原则的手段和开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候应当使这满足对软件的新需求使变化中的软件系统有一定的适应性和灵活性已有的软件模块特别是最重要的抽象层模块不再修改这就使变化中的软件系统有一定的稳定性和延续性这样的系统同时满足了可复用性与可维护性正如牛顿三大定律迪米特法则接口隔离原则是实现开闭原则的手段和工具置一样开闭原则一开闭原则开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即
18、在设计一个模块的时候应当使这个模块可以在不被修改的前提下被扩展满足开耦合的目标是维护依赖的单向性,有时我们也会需要使用坏的耦合。在这种情况 下,应当小心记录下原因,以帮助日后该代码的用户了解使用耦合真正的原因。3.4 怎样做到依赖倒转?以抽象方式耦合是依赖倒转原则的关键。抽象耦合关系总要涉及具体类从抽象类 继承,并且需要保证在任何引用到基类的地方都可以改换成其子类,因此,里氏 代换原则是依赖倒转原则的基础。在抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性,如果一个具体类 发生变化的可能性非常小,那么抽象耦合能发挥的好处便十分有限,这时可以用 具体耦合反而会更好。层次化:所有结构良好的面向
19、对象构架都具有清晰的层次定义,每个层次通过一 个定义良好的、受控的接口向外提供一组内聚的服务。依赖于抽象:建议不依赖于具体类,即程序中所有的依赖关系都应该终止于抽象 类或者接口。尽量做到:1、任何变量都不应该持有一个指向具体类的指针或者引用。2、任何类都不应该从具体类派生。3、任何方法都不应该覆写它的任何基类中的已经实现的方法。3.5依赖倒转原则的优缺点 依赖倒转原则虽然很强大,但却最不容易实现。因为依赖倒转的缘故,对象的创 建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用可能还会 导致产生大量的类,对不熟悉面向对象技术的工程师来说,维护这样的系统需要 较好地理解面向对象设计。依
20、赖倒转原则假定所有的具体类都是会变化的,这也不总是正确。有一些具体类 可能是相当稳定,不会变化的,使用这个具体类实例的应用完全可以依赖于这个 具体类型,而不必为此创建一个抽象类型。四、合成/聚合复用原则(Composite/Aggregate Reuse Principle或 CARP)4.1概念 定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新 的对象通过向这些对象的委派达到复用这些对象的目的。应首先使用合成/聚合,合成/聚合则使系统灵活,其次才考虑继承,达到复用的 目的。而使用继承时,要严格遵循里氏代换原则。有效地使用继承会有助于对问 题的理解,降低复杂度,而滥用继承
21、会增加系统 构建、维护时的难度及系统的复杂度。如果两个类是 Has-a关系应使用合成、聚合,如果是 Is-a关系可使用继承。Is-A 是严格的分类学意义上定义,意思是一个类是另一个类的 一种 。而Has-A 则不同,它表示某一个角色具有某一项责任。4.2什么是合成?什么是聚合?开闭原则或的基石其他设计原则里氏代换原则依赖倒转原则合成聚合复用原则迪米特法则接口隔离原则是实现开闭原则的手段和开闭原则的定义及优点定义一个软件实体应当对扩展开放对修改关闭即在设计一个模块的时候应当使这满足对软件的新需求使变化中的软件系统有一定的适应性和灵活性已有的软件模块特别是最重要的抽象层模块不再修改这就使变化中的软
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 对面 对象 设计 原则 总结 计算机 资料 C+
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内