单一职责原则 SRP
Single responsibility principle,
一个类或者模块只负责完成一个职责(或者功能)。
解决什么样的问题?
实现高内聚低耦合,提高代码复用性可读可维护性。
总结
要理解封装,知道要把什么样的内容放到一起;
要理解分离关注点,知道要把不同的内容拆分开来;
要理解变化的来源,知道要把不同行为者的代码放到不同的地方;
开闭原则 OCP
Open Closed Principle,
软件实体,应该对扩展开放对修改关闭。
解决什么样的问题?
- 代码扩展性问题,扩展性也是衡量代码好坏的重要标准之一,
- 容易应对未来需求变化就是扩展性好的代码,设计模式大部分都是为了解决这个问题而设计的。
总结
提高扩展意识,利用多态,面向接口编程,依赖注入等提高代码的扩展性
里氏替换原则 LSP
Liskov substitution principle,
又称里斯科夫替换原则,由Barbara Liskov提出,并以她的名字命名。
子类在设计的时候,要遵守父类的行为约定(或者叫协议)。父类定义了函数的行为约定,子类可以改变函数的内部实现逻辑,但不能改变函数原有的行为约定。
解决什么样的问题?
告诉我们什么样的继承关系是正确的
里氏代换原则是开闭原则的前提,在开放-封闭原则中,父类保持封闭,用子类继承父类的方式,对父类进行扩展,实现开放。父类保持封闭,此时父类是可以被复用的。然而在实际开发过程中,在继承父类创建一个子类过程,经常会犯一毛病,在子类中去修改父类的方法和属性,这就导致父类不在封闭
接口隔离原则 ISP
Interface segregation principle
不应强迫使用者依赖它们不用的方法
要为各个类建立它们需要的专用接口,而不是试图去建立一个很庞大的接口供所有依赖它的类去调用。
解决什么样的问题?
每个接口应承担一种相对独立的角色,不干不该干的事,该干的事都要干。
总结
- 设计接口时,要分离关注点,设计职责单一的小而美的接口。
- 胖接口减肥(让这个接口尽可能的少暴露过多方法,提供他们需要的方法)
依赖倒置原则 DIP
Dependency inversion principle
- 将高层模块和低层模块解耦;
- 依赖关系越少,代码越简单,项目越容易维护。
例子
现在有一个,只有9个方法的系统。
一共有多少种依赖?15种
应用了 DIP:
现在有多少种?9种
a —> D b —> D c —> D
d —> D
d —> e d —> f d —> g d —> h d —> i
倒置在哪?
最开始_d_是低层,现在_d_是高层
总结:
- 高层不要直接去依赖低层。高层和低层都去依赖接口。
- 高层不要直接依赖低层,要依赖于规范。这样的话,只要规范不变,对低层做任何修改,只要还符合规范的话,就不需要高层。
简单原则 KISS / YAGNI / DRY
Keep it simple, stupid, short, straightforward
让系统尽量保持简单,愚蠢,短小,直白
- 具体的实施层面的指导原则包括 YAGNI - 不做,DRY - 不重复,APO - 不过度优化等。
总结
- 我们要让系统保持”简单“,或让系统变的“简单”
- 通过”不做“来让系统变的简单
- 通过”不重复“来让系统变得简单
- 通过”不过度设计“让系统变简单
迪米特法则 LOD
Law of Demeter(迪米特法则) 简称LoD
别名: Principle of Least Knowledge(最少知识原则)
注:Demeter不是人名,是项目名。
- 每个单元对于其他的单元只能拥有有限的知识,除了与当前单元紧密联系的单元;
- 每个单元只能和它的朋友交谈,不能和陌生单元交谈;
- 只和自己直接的朋友交谈
a.getB().methodB(); // disobey
a.methodB(); // obey
总结
- 不要依赖不该直接依赖的类(低耦合)
- 有依赖关系的类之间,尽量只依赖必要最小限的接口
- 然这种方式可能在一定程度上减少对象之间的依赖,但是中间的第三者对象也会因此变得复杂,甚至可能变得难以维护。跟单一职责原则一样,我们要根据实际情况来决定是否要是用迪米特法则。