六大原则
单一职责原则
单一职责原则的定义是:应该有且仅有一个原因引起类的变更。
单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或 类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。
对于单一职责原则,我的建议是接口一定要做到单一职责,类的设计尽量做到只有一个 原因引起变化。
里氏替换原则
所有引用基类的地方必须能透明地使用其子类的对象。通俗的讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不行了,有子类出现的地方,父类未必就能适应。
public class Father{
public void doIt(HashMap<String,Object> it){
System.out.println("father doIt");
}
}
public class Son extends Father {
public void doIt(Map<String,Object> it){
System.out.println("son doIt");
}
public static void main(String[] args) {
invoke();
}
public static void invoke(){
Son f = new Son();
HashMap<String, Object> map = new HashMap<>(16);
f.doIt(map);
}
}
上面Father
类的方法类型是HashMap,在invoke()
中,创建的是HashMap,输出结果是father doIt
。如果改为Map
类型,输出的是son doIt
。子类的方法参数要大于父类,即子类的输入要大于父类。
public interface AMethod {
public Map<String,Object> hello();
}
public class AMethodImpl implements AMethod {
@Override
public HashMap<String, Object> hello() {
return null;
}
}
上面的AMethod
接口,返回参数是Map
,AMethodImpl
返回参数是HashMap
。假如颠倒返回值,编译器直接报错attempting to use incompatible return type
。这就是子类输出要小于父类。
依赖倒置原则
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
- 抽象不应该依赖细节;
- 细节应该依赖抽象。
高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的 原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。
在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的。
细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字new产生一个对象。
上图就是符合依赖倒置原则的设计,司机可以开不同的车,而司机并不需要改动。
依赖有三种方式,和Spring的依赖注入类似
- set方法注入
public interface IDriver {
public void setCar(ICar car);
public void drive();
}
public class Driver implements IDriver{
private ICar car;
public void setCar(ICar car){
this.car = car;
}
//司机的主要职责就是驾驶汽车
public void drive(){
this.car.run();
}
}
- 构造方法注入
public interface IDriver {
//是司机就应该会驾驶汽车
public void drive();
}
public class Driver implements IDriver{
private ICar car;
//构造函数注入
public Driver(ICar _car){
this.car = _car;
}
//司机的主要职责就是驾驶汽车
public void drive(){
this.car.run();
}
}
- 接口注入
public interface IDriver {
void driver(ICar car);
}
接口隔离原则
建立单一接口,不要建立臃肿庞大的接口。再通俗一点讲:接口尽量细化,同时接口中的方法尽量少。
- 接口要尽量小
接口隔离原则的核心定义,不出现臃肿的接口。根据接口隔离原则拆分接口时,首先必须满足单一职责原则。 - 接口要高内聚
高内聚就是提高接口、类、模块的处理能力,减少对外的交互。具体到接口隔离原则就是,要求在接口中尽量 少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越 少,同时也有利于降低成本。 - 定制服务
我们在做系统设计时需要考虑对系统之间或模块之间的接口采用定制服务。采用 定制服务就必然有一个要求:只提供访问者需要的方法。 - 接口设计是有限度的
接口的设计粒度越小,系统越灵活,这是不争的事实。但是,灵活的同时也带来了结构的复杂化,开发难度增加,可维护性降低。
迪米特法则
一个类应该对自己需要耦合或调用的类知道得最少。
- 只和朋友交流
朋友类的定义是这样的:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内 部的类不属于朋友类。
注意: 一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD()这种 情况(在一种极端的情况下允许出现这种访问,即每一个点号后面的返回类型都相同),类 与类之间的关系是建立在类间的,而不是方法间,因此一个方法尽量不引入一个类中不存在 的对象,当然,JDK API提供的类除外。
- 朋友间也是有距离的
注意:迪米特法则要求类“羞涩”一点,尽量不要对外公布太多的public方法和非静态的 public变量,尽量内敛,多使用private、package-private、protected等访问权限。
- 是自己的就是自己的
如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。 - 谨慎使用Serializable
开闭原则
开闭原则告诉我们应尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化,它是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则。
因为是书中的内容,大部分内容都摘抄自书本,如有侵权,请联系我。