baohuanlove 2019-06-27
在面向对象设计中有一个重要的原则是依赖倒置(Dependence Inversion Principle),主要作用是解耦,让对象与对象之间松耦合。定义如下:高层模块不应该依赖底层模块,他们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
光看定义很难理解依赖倒置到底是什么意思,先举一个简单的例子。
有以下两个类:
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
语句,依赖关系如下图所示:
这里就违反了依赖倒置原则,高层模块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
语句,依赖关系如下图所示:
修改后的Dao
类依赖于Connection
抽象接口,MysqlConnection
类也以实现接口的方式依赖于Dao
类。这时如果要更换为SqlServer
数据库,只要增加一个SqlserverConnection
类并实现Connection
接口就完成了,不需要去修改Dao
类了,大大的降低了耦合度。
之所以要细节依赖于抽象,归根结底是因为抽象是对细节的归纳和本质总结,细节可能会不停的变更,其本质却不会变化。依赖倒置原则感觉和面向接口编程的思想是如出一辙的,同样都是通过依赖抽象来降低耦合度,只是侧重点不同。
只是看书可能学习效率并不是很高,还是需要多写写学到的东西,这就是这篇文章出现的理由了。可能会有错误或不全的地方,欢迎指出。
参考资料: