依赖倒置原则

来源:互联网 发布:淘宝已经收货申请退款 编辑:程序博客网 时间:2024/06/07 12:55

依赖倒置原则:其定义是说,高层模块不应该依赖于低层模块,二者之间都应该依赖于其各自的抽象;抽象不应该依

于细节,而细节应该依赖于抽象


上述的说法,可能很绕口。简单点理解,打个比方,我们电脑如果要读取U盘中的文件内容,那么我们只需要在电脑

USB接口中插入我们的U盘即可,而不是采用电烙铁将我们U盘烙在电脑的某个线路上。在这个例子中,电脑算是

一个模块,U盘也算是一个模块,电脑读取U盘,那么电脑属于高层模块,U盘属于低层模块,他们二者要进行数据交

互,依赖的是各自的抽象(接口),而不是依赖的各自底层实现的线路;U盘不管是金士顿的,还是其他牌子,电脑

都不管,都可以读取内容,也就是抽象不依赖于细节,但是无论是金士顿的U盘,还是其他牌子,都要通过USB接口

才能与电脑进行数据交互,也就是细节依赖于抽象


相对于细节的多变性,抽象于则要稳定的多。在JAVA中,抽象指的是接口或抽象类,而细节则是具体的实现类,模

与模块之间进行交互,最好采用接口或者抽象类制定好规范和契约,而不要去涉及具体的操作,把具体的细节交由

它们各自的实现类即可。


依赖倒置原则的核心思想正是像电脑与U盘的实现一样,采用面向接口编程。由接口定义一系列各自的规范和契约,

具体的实现则由接口的实现类去完成,那么如果有天需要更换具体的实现类时,只需要更换具体的实现即可,而不用

去关心到底是哪一个实现类需要更换,或者说如何更换。


看了网上一个例子,感觉很不错,也就是母亲给孩子讲故事的那个示例



当客户端,需要母亲讲故事时,调用母亲的read(),并传递一本具体的书进去,好了,母亲正常给小孩讲讲故事……


可以突然某一天,小孩要求母亲给他读报,怎么办呢?难道我们将read()里面的参数修改为Newspaper么,那后面又

需要读书,或者读故事会怎么办?所以上述的设计,显然不是一个很好的设计……


首先,我们分析,上述这个示例中,我们可以抽象出2个对象类型,1、读者,2、读物,那么我们就围绕着这2个类型

进行设计



上面这种设计,就不用关心到底是谁来讲,讲什么了,如果需要扩展,那么直接实现接口即可。

代码演示:

package yuanze;/** * 抽象读者 *  * @author Administrator * */public interface Reader {public String read(Resource resource);}




具体的读者,可以是母亲,可以是父亲……

package yuanze;public class Mother implements Reader {@Overridepublic String read(Resource resource) {// TODO Auto-generated method stubreturn resource.getContent();}}



抽象读物:

package yuanze;/** * 把任何读物都认为是一种资源 *  * @author Administrator * */public interface Resource {public String getContent();}



具体的读物,可以是报纸,可以是书籍:

package yuanze;public class NewsPaper implements Resource {@Overridepublic String getContent() {// TODO Auto-generated method stubreturn "今天的新闻是:……";}}


package yuanze;public class Book implements Resource {private String name;private String content;public Book() {super();// TODO Auto-generated constructor stub}public Book(String name) {super();this.name = name;}public Book(String name, String content) {super();this.name = name;this.content = content;}@Overridepublic String getContent() {// TODO Auto-generated method stubreturn "书名是: 《" + name + "》,内容是:" + content;}}




好,客户端调用开始:

package yuanze;public class Test {public static void main(String[] args) {// 母亲读取书籍Reader reader = new Mother();Resource resource = null;resource = new Book("钢铁是如何炼成的", "这一本关于励志的书籍,书的内容是……");String content = reader.read(resource);System.out.println(content);// 母亲现在开始读报纸resource = new NewsPaper();content = reader.read(resource);System.out.println(content);}}



好,如果需要扩展父亲来读取的话,只需要将母亲的实例修改为父亲的实例即可了。这就是依赖倒置原则带来的好

处,扩展性得以提升。


关于这个依赖倒置的好处,我们后面在使用SpringIOC容器注入实例后,就更清晰了。那么在实际编程中,我们需要

做到以下几点:

1、低层模块尽量都要有抽象类或接口,或者两者都有。

2、变量的声明类型尽量是抽象类或接口。

3、在使用继承时,遵循里氏替换原则。

0 0
原创粉丝点击