单一职责原则
英文名称是Single Responsibility principle,简称SRP。重点是怎么划分类的职责。
定义:应该有且仅有一个原因引起类的变更。
单一职责的好处:
- 类的复杂性降低。
- 可读性提高。
- 可维护性提高。
- 变更引起的风险降低。
注:用“职责”或“变化原因”来衡量接口或类设计的是否优良,但是”职责“和”变化原因“都是不可度量的,因项目而异,因环境而异。
最佳实践:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
里氏替换原则
定义:所有引用基类的地方必须能透明的使用其子类的对象。
通俗的讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常。但是有子类出现的地方,父类未必能适应。包括四层含义。
1. 子类必须完全实现父类的方法。如果子类不能完整的实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。
2. 子类可以有自己的个性。
3. 覆盖或实现父类的方法时输入参数可以被放大。方法中的输入参数称为前置条件。前置条件就是你让我执行,就必须满足我的条件。后置条件就是我执行完了需要反馈什么,标准是什么。子类中方法的前置条件必须与超类中被覆写的方法的前置条件相同或者更宽松。
public class Father{
public Collection doSomething(HashMap map){
System.out.println("父类被执行...");
return map.values();
}
}
public class Son extends Father{
public Collection doSomething(Map map){
System.out.println("子类被执行...");
return map.values();
}
}
public class Client{
public static void main(String[] args){
Son f = new Son();
HashMap map = new HashMap();
f.doSomething(map);//父类被执行
}
}
- 覆写或实现父类的方法时输出结果可以被缩小。也就是说父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么S和T是同一个类型或者S是T的子类。
依赖倒置原则
包含三层含义:
1. 高层模块不应该依赖低层模块,两者都应该依赖其抽象。
2. 抽象不应该依赖细节。
3. 细节应该依赖抽象。
接口隔离原则
这里的接口分为两种,
实例接口:在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述,这是一种接口。
类接口:java中使用的interface关键字定义的接口。
隔离:客户端不应该依赖他不需要的接口。客户端需要什么接口就提供什么接口。把不需要的接口剔除掉。那就要对接口进行细化,保证其纯洁性。建立单一接口,不要建立臃肿庞大的接口,方法中的方法尽量少。
包含四层含义:
- 接口要尽量小。但是根据接口隔离原则拆分接口时,首先必须满足单一职责原则。
- 接口要高内聚。高内聚就是提高接口、类、模块的处理能力,减少对外的交互 。
- 定制服务。只提供访问者需要的方法。
- 接口设计是有限度的。
迪米特法则
也成为最少知识原则。一个对象应该对其他对象有最少的了解。通俗地讲,一个类 应该对自己需要耦合或调用的类知道的最少。包含以下四层含义:
- 只和朋友交流。朋友类的定义:出现在成员变量、方法的输入输出参数中的类称为朋友类,而出现在方法体内部的类不属于朋友类。
- 和朋友类保持一定距离。不要太过耦合。尽量不要对外公布太多的public方法和非静态的pulic变量,尽量内敛。
- 如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中。
- 谨慎使用Serializable.
开闭原则
定义:一个软件实体如类、模块和函数应该对外扩展开放,对修改关闭。即通过扩展实现变化,而不是通过修改已有代码来实现变化。但也不是说不做任何修改,底层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无异议的代码片段。