概述
- 单一职责原则(SRP):一个类应该仅有一个引起他变化的原因。
- 开闭原则(OCP):对扩展是开放的,但是对修改是关闭的。
- 里式替换原则(LSP):子类可以去扩展父类的功能,但是不能改变父类原有的功能。
- 接口隔离原则(ISP):类间的依赖关系应该建立在最小的接口上。
- 依赖倒置原则(DIP):面向接口编程,而不是具体实现。
- 迪米特原则(LOD):一个对象应该对其他对象保持最小的了解。
- KISS原则:Keep It Simple and Stupid
- YAGNI原则:You Ain’t Gonna Need It
- DRY原则:Don’t Repeat Yourself
单一职责原则(Single Responsibility Principle)
简单地说就是一个类只做一件事。
注意,这并不是说一个类只有一个函数,而是说这个类中的函数所做的工作是高度相关的,也就是高内聚。
优点:
(1)类的复杂性降低,实现什么职责都有清晰明确的定义
(2)可读性提高,复杂性降低,那当然可读性提高了
(3)可维护性提高,可读性提高,那当然更容易维护了
(4)变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助
开闭原则(Open Closed Principle)
开闭原则是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。
开闭原则:对扩展是开放,对修改是关闭。
在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码引入错误。因此,当软件需要变化时,我们应该尽量通过扩展的方式来实现变化,而不是通过修改已有的代码来实现。
通俗的讲,添加一个新的功能时,尽量在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。
这样通过扩展的形式来应对软件的变化或者说用户需求的多样性,既避免了破坏原有系统,又保证了软件系统的可扩展性。
优点:
(1)增加稳定性
(2)可扩展性高
里氏替换原则(Liskov Substitution Principle)
里氏替换原则:子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。
通俗的讲,子类可以去扩展父类的功能,但是不能改变父类原有的功能。
细想一下,很多应用框架不就是这样实现吗?框架定义一系列相关的逻辑骨架与抽象,使得用户可以将自己的实现注入到框架中,从而实现变化万千的功能。
优点:
(1)代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性
(2)提高代码的重用性
(3)提高代码的可扩展性,实现父类的方法就可以“为所欲为”了,很多开源框架的扩展接口都是通过继承父类来完成的
(4)提高产品或项目的开放性
缺点:
(1)继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法
(2)降低代码的灵活性。子类必须拥有父类的属性和方法,让子类自由的世界中多了些约束
(3)增强了耦合性。当父类的常量、变量和方法被修改时,必需要考虑子类的修改,而且在缺乏规范的环境下,这种修改可能带来非常糟糕的结果——大片的代码需要重构
接口隔离原则(Interface Segregation Principle)
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。
优点:
(1)降低耦合性
(2)提升代码的可读性
(3)隐藏实现细节
依赖倒置原则(Dependency Inversion Principle)
依赖倒置原则的几个关键点如下
(1)高层模块不应该依赖低层模块,两者都应该依赖其抽象。
(2)抽象不应依赖细节。
(3)细节应该依赖抽象。
在Java中,抽象就是指接口或抽象类,两者都是不能直接被实例化的。细节就是实现接口或继承抽象类而产生的类,其特点就是可以直接被实例化。
依赖倒置原则在 Java 语言中的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
其实就是一句话:面向接口编程,或者说是面向抽象编程,这里的抽象指的是接口或者抽象类。面向接口编程是面向对象精髓之一。
优点:
(1)可扩展性好
(2)耦合度低
迪米特原则(Least Knowledge Principle)
迪米特法则也称为最少知识原则(Least Knowledge Principle),虽然名字不同,但描述的是同一个原则
:一个对象应该对其他对象有最少的了解。
通俗地讲,
一个类应该对自己需要耦合或调用的类知道得最少,这有点类似接口隔离原则中的最小接口的概念。 类的内部如何实现、如何复杂都与调用者或者依赖者没有关系,调用者或者依赖者只需要知道它需要的方法即可,其他的一概不关心。
迪米特法则是希望减少类之间的耦合,让类越独立越好。
迪米特法则还有一个英文解释是:Only talk to your immedate friends(只与直接的朋友通信)。什么叫做直接的朋友呢?每个对象都必然会与其他对象有耦合关系,两个对象之间的耦合就成为朋友关系,这种关系的类型有很多,例如组合、聚合、依赖等。
优点:
(1)降低复杂度
(2)降低耦合度
(3)增加稳定性
KISS原则(Keep It Simple and Stupid)
简单并不是以代码行数来考量的。代码行数越少并不代表代码越简单,我们还要考虑逻辑复杂度、实现难度、代码的可读性等。
有下面几条指导原则:
- 不要使用同事可能不懂的技术来实现代码
- 不要重复造轮子,要善于使用已经有的工具类库
- 不要过度优化
优点:
(1)提升可读性
(2)提升可维护性
YAGNI原则(You Ain’t Gonna Need It)
YAGNI 原则直译过来就是:你不需要它。核心思想:不要做过度设计。
DRY原则(Don’t Repeat Yourself)
DRY原则(Don’t Repeat Yourself)典型的代码重复
- 实现逻辑重复
- 功能语义重复
- 代码执行重复
这三种代码重复,有的看似违反DRY,实际上并不违反;有的看似不违反,实际上却违反了,需要灵活应用!