开放封闭原理(Open Closed Principle)
类应该是开放的以便于扩展,又要是封闭的以利于修改。我们应该可以在不改动原有类的基础上,就能在系统中增加新的功能。原则就是减少类之间的耦合,在抽象层次上建立类之间的关联。
例子:一家公司对个人客户提供了不同类型的帐户,客户可以在帐户中存款。
Account类在抽象层次与AccountType继承树之间关联。由于Savings和Checking继承了AccountType,就可以利用动态绑定。如果我们创建新类型MoneyMarket,并不需要对原有的类进行改动,达到的OCP的要求。
替代原理(Liskov Substitution Principle)
子类应该可以用来替代其基类。
依赖性倒置原理(Dependency Inversion Principle)
依赖于抽象类,不要依赖于具体类。在Java中,当我们引用类创建实例时,就已经违背了DIP,解决办法有两种:
第一,通过Class类的newInstance方法来动态加载对象。
第二,使用对象工厂。创建一个类来负责创建对象实例。在工厂中使用了具体类,事实上违背了DIP,但这是被隔离的并且经过精心的考虑,是可以接受的。
具体的引用并不总是坏事。如果被引用的是稳定的类,不大会改动,使用工厂就会在系统中引入无根据的复杂性。
抽象耦合
它是指一个类不要与可实例化的类耦合,而应该与它的基类或抽象类耦合。在Java中,抽象类可以是有抽象方法的类,也可以是接口。这实际上是LSP实现其灵活性所必须的方法,是DIP所必须的机制,也是OCP的核心思想。
接口分离原理(Interface Segregation Principle)
多个专用接口优于一个单一的通用接口。所定义的任何接口都应具有高内聚性。在设计接口及接口的的操作时,不要让接口具有多重角色。一个接口应该保证实现该接口的类的实例对象可以只呈现为单一的角色。
例子:实现一个对各种不同的数据源进行统一访问,后台的数据源可能是关系数据库也可能是一般的文件。我们需要提供一个通用的数据访问机制,向任何可能作为数据客户的类提供一致的数据访问模型。
RowSetManager接口的有内聚性的问题:如果实现该接口的类是只读的,不需要插入、更新呢?如果客户端不关心数据获取,只想遍历已经获取的内部数据数据集呢?
经过分析,我们提供一些更专有的接口是很有意义的。
改进例子:
我们把RowSetManager的职责分割到多个接口,每个接口都担负着让类归从于一组内聚的职责。
构成重用原理(Composite Reuse Principle)
对象构成的多态优于继承。面向对象系统中,最具灾难性的错误就是把继承作为重用的主要机制。
例子:
我们在AccountType中增加了一个计算帐户利息的方法。这样做似乎还不错,Savings和MoneyMarket类都是有利息的帐户。而Checking则是无利息的帐户,我们可以简单的在Checking中实现一个空的操作,这个问题暂时解决了。
假如我们又有了新的需求。需要支持一种新的帐户类型Stock。Stock也需要计算利息,得Stock的计算方法与AccountType中定义的缺省实现不一样。我们也可以像Checking的做法一样,只不过实现了适合的算法,而不是空操作。到这时,一切都运行良好。新的需求出现了,MoneyMarket的利息计算方法要改成与Stock相同的机制,Savings还使用原来的机制。
我们有三个解决这个问题的办法:
第一种是采用新的算法重新改写AccountType的calculateInterest方法,然后用旧的算法为Savings实现一个新的方法。这种办法并不理想,因为它使我们改动了两个原有的类。
第二种是在MoneyMarket上重写calculateInterest方法,把Stock中的代码复制过来。很显然,这也不是很好的解决办法。重用的目的可不是复制和粘贴代码。
第三种方法,我们可以定义一个InterestCalculator类,在其它的基础上定义calculateInterest方法实现新的算法,然后把Stock和MoneyMarket中对利息计算移到新的类中。这种方法是我们一开始就应该采用的,这就是使用多态性的构成而不是继承来实现复用。
第三种方法的类图:
再次改进例子:
我们把与InterestCalculator的关系从派生类移到了基类AccountType中,实际上,我们又回到采用继承来实现征用,虽然存在一点差别。对于Checking我们可以使用一个空的算法实现来解决。
如果我们要在基类中定义缺省的行为的话,一定要确保这个行为适用于所有的派生类。
- 大小: 24.4 KB
- 大小: 11.5 KB
- 大小: 19.4 KB
- 大小: 42.5 KB
- 大小: 39.7 KB
- 大小: 26.1 KB
分享到:
相关推荐
《面向对象原理与语言》课程实验大纲 适用对象: 计算机科学与技术专业 先修课程: C语言程序设计、数据结构 后续课程: 算法设计与分析、面向对象技术 开课单位:信息工程学院计算机科学与技术系 实验题目 实验一...
### 面向对象原理与Java实践课程实验-对象和类 #### 实验目的与要求 本实验的主要目的是让学生深入理解面向对象编程的核心概念之一——类与对象,并通过实际编程来掌握这些概念的具体应用。实验重点包括: 1. **...
面向对象原理。主要是深入剖析面向对象的原理
面向对象原理与Java实践课程实验报告 继承与接口实验报告+代码
### Java虚拟机面向对象原理及应用 #### 一、引言 随着计算机技术的发展,Java作为一种跨平台、安全可靠的编程语言,在软件开发领域占据了一席之地。Java的强大之处在于其面向对象的特性,这一特性使得Java能够更...
《面向对象设计原理与模式(Java版)》全面介绍了Java面向对象程序设计的原理和模式,帮助解决Java程序中的设计问题。此外,该书十分注重Java面向对象程序设计的每个细节,以及继承、方法、类、设计模式等在程序设计...
### 面向对象设计原理解析 #### 四大发明之活字印刷——面向对象思想的胜利 在《戏说面向对象设计原理》一文中,作者通过一个生动的故事引入了面向对象编程的核心思想:可维护性、可复用性、可扩展性和灵活性。...
本文将深入探讨如何使用 `class` 实现面向对象编程,以及其背后的原理。 首先,让我们了解什么是类。在Python中,类是一个蓝图,用于创建具有相似属性和方法的对象。类定义了这些属性和方法,而对象是类的实例,...
通过这些示例,读者可以加深对面向对象原理的理解。 7. 结构化代码的局限:结构化编程是一种编程方法,强调代码的模块化和顺序、选择、循环的控制结构。虽然结构化编程在早期编程中占据主导地位,但随着软件开发...
本文将深入探讨基于同名书籍《JavaScript面向对象原理》的实现,通过简单的示例解析JavaScript的面向对象编程(OOP)原理。 在JavaScript中,面向对象编程主要体现在三个方面:封装、继承和多态。首先,我们来看看...
+ 通过案例分析和实践来加深对面向对象原理的理解 + 强调通过实践来应用面向对象原理解决实际问题 * 项目驱动学习和实践 + 通过设计具有实际意义的编程项目,要求学生应用所学的面向对象编程技术 + 项目驱动...
在本篇文章中,我们将深入探讨面向对象的原理、特征以及其在实际开发中的应用。 1. **对象和类**:在面向对象编程中,对象是程序的基本单元,它包含了数据(属性)和操作数据的方法(行为)。类是对具有相同属性和...
ian Graham 著《面向对象方法原理与实践》原书第三版,清晰版
Java面向对象教程是深入理解Java编程的关键,它涵盖了软件工程中的基本原则,并将其应用于实际编程实践。面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它基于“对象”的概念,这些对象封装了...
在这个名为"Turfe"的项目中,我们可以深入探讨Java的面向对象原理。 首先,面向对象有三大基本特征:封装、继承和多态。封装是将数据和操作这些数据的方法绑定在一起,形成一个独立的单元,防止外部代码随意访问和...
这种方法不仅有助于加深对面向对象原理的理解,同时也为那些希望在限制严格的环境中应用面向对象技术的开发者提供了宝贵的参考。本书是一本非常有价值的指南,适合于想要探索面向对象编程精髓的C语言开发者。