目的
解决软件的耦合性、内聚性、可扩展性、重用性、灵活性
- 重用性:相同功能的代码,不用多次编写
- 可读性:便于其他人阅读
- 可扩展性(可维护性):方便添加新功能
- 可靠性:增加新功能,对原功能没影响
单一职责原则
- 降低类的复杂度,一个类只负责一项职责
- 提高类的可读性,可维护性
- 降低变更引起的风险
- 特殊情况下,比如类中方法数量少,可以在方法级别保持单一职责原则
接口隔离原则
- 客户端不要实现不需要的接口,即一个类对另一个类的依赖应该建立再最小的接口上
- 接口隔离原则的要点就是要细化接口,客户端只实现需要的接口和里面的方法。
- 好处:避免接口污染、提高灵活性、提供定制服务、实现高内聚
依赖倒置原则
- 底层模块尽量都有抽象类或接口,或两种都有,程序稳定性更好
- 变量的声明类型尽量是抽象类或接口,这样对于变量引用(形参)和实际对象(实参)来讲,就利于扩展和优化
- 继承时遵循里氏替换原则
- 高层模块不应该依赖低层模块,它们都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象
- 依赖倒置原则也可以理解为“依赖抽象原则”
里氏替换原则
若有两个条件:
- A条件:将程序P中的类1的对象o1改为类2的对象o2,而程序P的行为没有发生变化
- B条件:类1是父类,类2是子类
根据里氏替换原则的第一个定义,A条件可以推导出B条件;
根据里氏替换原则的第二个定义,B条件可以推导出A条件;
所以,里氏替换原则其实就是:A条件和B条件互为充要条件。
在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法,继承实际上让两个类耦合性增强了,如果必须重写,可以通过聚合,组合,依赖的方式,重新写一个基类让之前的父子类变成兄弟类来解决问题。
里氏替换原则的意义,就是规范继承的用法,让我们最大限度地发挥继承的优点。
开闭原则
对扩展开放(提供方),对修改关闭(使用方)
迪米特法则
6) 避免类中出现非直接朋友关系的耦合
合成复用原则
- 尽量使用依赖、聚合、组合的方式,而不是使用继承
- 能使用依赖、聚合、组合,就不要用继承
UML类关系
依赖
- 类中用到了对方
- 类的成员属性
- 方法的返回类型
- 方法的接收参数类型(重要)
- 方法体中使用的局部变量(重要)
- A类用到了B类,就说A依赖B
泛化
- 泛化=继承,是依赖的一种特例
- A类继承了B类,就说A和B存在泛化关系
实现
A类实现了B类接口,就是实现关系,是依赖的一种特例
关联
- 关联关系就是类与类之间的联系,是依赖的特例
- 关联有导航性:即双向关系或单向关系
- 关系有多重性:
聚合
- 聚合表示整体与部分的关系,整体与部分可以分开
- 聚合是关联的特例,所以具有关联的导航性与多重性
组合
- 若整体和部分是不可分离的,则为组合关系
例子:有三个实体:Person、IDCard、Head,那Head和Person是组合,IDCard和Person是聚合。 但是若在Person中对IDCard进行
级联删除,即删除Person时连IDCard一起删除,那IDCard和Person是组合了。