在面向对象设计中有一个重要的原则是依赖倒置(Dependence Inversion Principle),主要做用是解耦,让对象与对象之间松耦合。定义以下:高层模块不该该依赖底层模块,他们都应该依赖抽象。抽象不该该依赖于细节,细节应该依赖于抽象。html
光看定义很难理解依赖倒置究竟是什么意思,先举一个简单的例子。git
有如下两个类:github
public class Dao {
private MysqlConnection connection;
public Dao(MysqlConnection connection) {
this.connection = connection;
}
public void findAll() {
connection.executeQuery("SELECT * FROM test");
}
}
复制代码
public class MysqlConnection {
public void executeQuery(String sql) {
System.out.println(sql);
}
}
复制代码
Dao
类经过调用MysqlConnection
类的executeQuery
方法执行sql
语句,依赖关系以下图所示:sql
这里就违反了依赖倒置原则,高层模块DAO
强耦合了底层模块MysqlConnection
。若是系统须要更换数据库为SqlServer
,咱们就不得不去修改Dao
类,增长一个SqlserverConnection
类,这又违反了面向对象设计的开闭原则。例子中的Dao
是一个不稳定、随时会由于底层模块的变动而出现BUG的类。数据库
如今根据依赖倒置原则对例子进行修改。编程
public class Dao {
private Connection connection;
public Dao(Connection connection) {
this.connection = connection;
}
public void findAll() {
connection.executeQuery("SELECT * FROM test");
}
}
复制代码
public interface Connection {
void executeQuery(String sql);
}
复制代码
public class MysqlConnection implements Connection {
@Override
public void executeQuery(String sql) {
System.out.println(sql);
}
}
复制代码
Dao
类经过调用Connection
接口的executeQuery
方法执行sql
语句,依赖关系以下图所示:bash
修改后的Dao
类依赖于Connection
抽象接口,MysqlConnection
类也以实现接口的方式依赖于Dao
类。这时若是要更换为SqlServer
数据库,只要增长一个SqlserverConnection
类并实现Connection
接口就完成了,不须要去修改Dao
类了,大大的下降了耦合度。ide
之因此要细节依赖于抽象,归根结底是由于抽象是对细节的概括和本质总结,细节可能会不停的变动,其本质却不会变化。依赖倒置原则感受和面向接口编程的思想是一模一样的,一样都是经过依赖抽象来下降耦合度,只是侧重点不一样。学习
只是看书可能学习效率并非很高,仍是须要多写写学到的东西,这就是这篇文章出现的理由了。可能会有错误或不全的地方,欢迎指出。ui
参考资料: