依赖倒置原则
- 高层模块不应该依赖底层模块,二者都应该依赖抽象。
- 抽象不应该依赖具体实现,具体实现应该依赖抽象。
例如:JDBC 我们在java开发中访问数据库,代码并不直接依赖数据库驱动,而是依赖JDBC,当应用程序需要更换数据库,不需要修改任何代码。这正是因为应用代码,高层模块,不依赖数据库驱动,而是依赖抽象JDBC,而数据库驱动,作为底层模块,也依赖JDBC。
日常开发中,service层依赖DAO层,并不是直接依赖DAO的具体实现,而是依赖DAO提供的抽象接口,但这并不是依赖倒置,依赖倒置中,除了具体实现要依赖抽象,最重要的是抽象是属于谁的抽象。
按照依赖倒置原则,接口的所有权是被倒置的,也就是说,接口被高层模块定义,高层模块拥有接口,底层模块实现接口。不是高层模块依赖底层模块的接口,而是底层模块依赖高层模块的接口,从而实现依赖关系的倒置。 在上面的依赖层次中,每一层的接口都被高层模块定义,由底层模块实现,高层模块完全不依赖底层模块,及时是底层模块的接口。这样,底层模块的改动不会影响高层模块,高层模块的复用也不会依赖底层模块。对于Service和DAO这个例子来说,就是Service定义接口,DAO实现接口,这样才符合依赖倒置原则。
所以依赖倒置原则也被称为好莱坞原则:Dont't call me, I will call you. 即不要来调用我,我会调用你。Tomcat、Spring 都是基于这个原则设计出来的,应用程序不需要调用Tomcat或者Spring这样的框架,而是框架调用应用程序。而实现这一特性的前提就是应用程序必须实现框架的接口规范,比如实现Servlet接口。
依赖倒置原则通俗说就是,高层模块不依赖底层模块,而是都是依赖抽象接口,这个抽象接口通常是由高层模块定义,底层模块实现。
遵循依赖倒置守则
- 应用代码中多使用抽象接口,尽量避免使用那些多变的具体实现类。
- 不要继承具体类,如果一个类在设计之初不是抽象类,那么尽量不要去继承它。对具体的继承是一种强依赖关系,维护的时候难以改变。
- 不要重写包含具体实现的函数
典型场景
依赖倒置原则最典型的使用场景就是框架的设计。
框架提供框架核心功能,比如HTTP处理,MVC等,并提供一组接口规范,应用程序只需要遵循接口规范编程,就可以被框架调用。程序使用框架的功能,但是不调用框架的代码,而是实现框架的接口,被框架调用,从而框架有更高的可复用性,被应用于各种软件开发中。
来源:oschina
链接:https://my.oschina.net/u/939952/blog/3164512