面向对象的设计原则
面向对象的三大特性:封装、继承、多态
面向对象的七(或五大原则,前五项)大基本原则:单一职责原则(SRP) 、开放封闭原则(OCP) 、里氏替换原则(LSP)、 依赖倒置原则(DIP)、 接口隔离原则(ISP)、迪米特法则(Law Of Demeter)、组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP)
一、开闭原则
开闭原则是面向对象的可复用设计的第一块基石,是最重要的面向对象设计原则
软件实体应当对扩展开放,对修改关闭。
Open-Closed Principle (OCP): Software entities should be open for extension, but closed for modification.
开闭原则的实现方法:
可以通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
二、里氏代换原则
所有引用基类的地方必须能透明地使用其子类的对象。
Liskov Substitution Principle (LSP): Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
里氏代替原则的实现方法:
子类可以扩展父类的功能,但不能改变父类原有的功能。 【例2】里氏代替原则在“几维鸟不是鸟”实例中的应用。 分析:鸟一般都会飞行,如燕子的飞行速度大概是每小时可达120公里。但是新西兰的“几维鸟”,由于翅膀退化,因此无法飞行。
三、依赖倒转原则
高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
Dependency Inversion Principle (DIP): High level modules should not depend upon low level modules, both should depend upon abstractions. Abstractions should not depend upon details, details should depend upon abstractions.
我们在实际编程中只要遵循以下四点,就能在项目中满足依赖倒置原则:
⑴ 每个类尽量提供接口或抽象类,或者两者都具备。 ⑵ 变量的声明类型尽量是接口或者是抽象类。 ⑶ 任何类都不应该从具体类派生。 ⑷ 使用继承时尽量遵循里氏替换原则。
【例3】依赖倒置原则在“顾客购物程序”中的应用。 分析:如顾客类的shopping(ShaoguanShop shop)方法只访问韶关网店,如果该顾客想从另外一家商店(如:婺源网店WuyuanShop)购物,就要修改该方法的参数类型,这违背了“依赖倒置”原则。
解决方法是:定义一个商店接口Shop,顾客类面向该接口编程,其类图如下。
四、单一职责原则
单一职责原则是最简单的面向对象设计原则,用于控制类的粒度大小
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
Single Responsibility Principle (SRP): Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.
单一职责原则的实现方法:需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。 【例4】大学学生工作管理程序。 分析:大学学生工作主要包括学生生活辅导和学生学业指导两个方面的工作,其中生活辅导主要包括班委建设、出勤统计、心理辅导、费用催缴、班级管理等工作,学业指导主要包括专业引导、学习辅导、科研指导、学习总结等工作。如果将这些工作交给一位老师负责显然不合理,正确的做法是生活辅导由辅导员负责,学业指导由学业导师负责,其类图如下。
五、接口隔离原则
客户端不应该依赖那些它不需要的接口。
Interface Segregation Principle (ISP): Clients should not be forced to depend upon interfaces that they do not use.
接口隔离原则的实现方法: ⑴ 接口尽量小,但是要有限度。 ⑵ 只提供调用者需要的方法,屏蔽不需要的方法。 ⑶ 了解环境,拒绝盲从。 ⑷ 提高内聚,减少对外交互。
【例5】学生成绩管理程序。 分析:学生成绩管理程序一般包含插入成绩、删除成绩、修改成绩、计算总分、计算均分、打印成绩信息、查询成绩信息等功能,如果将这些功能全部放到一个接口中显然不太合理,正确的做法是将它们分别放在输入模块、统计模块和打印模块等3个模块中,其类图如下。
六、迪米特法则
迪米特法则又称为最少知识原则(Least Knowledge Principle, LKP)
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
Law of Demeter (LoD): Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
七、合成复用原则
合成复用原则定义 合成复用原则又称为组合/聚合复用原则(Composition/ Aggregate Reuse Principle, CARP)
优先使用对象组合,而不是继承来达到复用的目的。
Composite Reuse Principle (CRP):Favor composition of objects over inheritance as a reuse mechanism.
合成复用原则实例 现使用合成复用原则对其进行重构。
-
实例解析
复用时要尽量使用组合/聚合关系(关联关系), 少用继承