3)依赖倒置原则(Dependence Inversion Principle)
定义:
1、High-level modules should not depend on low-level modules. Both should depend on abstractions.(高级模块不应依赖于低级模块。两者都应依赖抽象)
2、Abstractions should not depend on details. Details should depend on abstractions.(抽象不应依赖细节。细节应依靠抽象)
比如需要实施某一个项目,暂时分为前端和后端开发者,一般是这样设计
前端开发者类
public class BackEndDeveloper {
public void writeJava() {
}
}
后端开发者类
public class FrontEndDeveloper {
public void writeJavascript() {
}
}
项目整体实施类
public class Project {
private BackEndDeveloper backEndDeveloper = new BackEndDeveloper();
private FrontEndDeveloper frontEndDeveloper = new FrontEndDeveloper();
public void implement() {
backEndDeveloper.writeJava();
frontEndDeveloper.writeJavascript();
}
}
上面的代码违反了依赖倒置的两个含义
1、Project类(高级模块)直接依赖于BackEndDeveloper (低级模块)和FrontEndDeveloper (低级模块);
2、Project类直接依赖于writeJava和writeJavascript等开发细节
这样的代码会导致一个问题是,假如FrontEndDeveloper 的工作不是写javascript,而是改成写typescript,project类也要更改;或者假如再增加一类中间件工作者MiddlewareDeveloper,那么Project的implement也要更改。
那么,根据依赖倒置原则可以怎样设计呢?
首先定义一个开发者接口Developer
public interface Developer {
void develop();
}
再者前端和后端开发者分别实现接口
public class BackEndDeveloper implements Developer {
@Override
public void develop() {
writeJava();
}
private void writeJava() {
}
}
public class FrontEndDeveloper implements Developer {
@Override
public void develop() {
writeJavascript();
}
public void writeJavascript() {
}
}
最后Project输出工作
public class Project {
private List<Developer> developers;
public Project(List<Developer> developers) {
this.developers = developers;
}
public void implement() {
developers.forEach(d->d.develop());
}
}
这样设计,当低级模块需要更改的时候,也不会影响到高级模块了。