设计原则之依赖倒置原则

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

问题:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,
负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。

举个栗子:讲一个读者读书的故事。。。

1. 新建一个类Book,包含获取书的内容的方法,代码如下:

2. 新建一个类Reader,依赖类Book,包含一个读书的read方法,代码如下:

3. 在类DIPFragment中,通过类Reader的对象调用read方法来实现读者读书的功能,代码如下:

4. 运行后的效果是:

 

      以上,就实现了一个读者读书的故事。现在要改需求,我们不读书了,改读报纸了,那么我们要新建一个报纸类Newspaper,同样包含一个获取报纸的内容的方法,然后去修改读者类Reader,替换掉类Book,又去修改实现类DIPFragment,这样是不是觉得改动的地方太多了,跟重新写无异,试想一下,如果原有的功能比较复杂的话,那样再进行需求变动,要做的工作是很多的,原因就是Reader与Book的耦合性太高,所以必须降低他俩之间的耦合度才行,于是我们可以引入抽象的接口IRead,包含一个获取读物内容的getReadContent方法,具体实现如下:


1. 新增一个抽象的接口IRead,包含一个获取读物内容的getReadContent方法,代码如下:

2. 新增一个报纸类Newspaper,实现接口IRead;同样让类Book也去实现接口IRead。代码如下:

3. 让高层模块去依赖接口,即类Reader依赖接口IRead,它负责完成主要的具体的业务逻辑。代码如下:

4. 在类DIPFragment中,通过类Reader的对象调用read方法来实现读者读书的功能,代码如下:

5. 运行后的效果是:

 

      以上就是采用的依赖倒置原则,降低了Reader和Book、Newspaper之间的耦合性,无论以后怎样扩展DIPFragment类,都不需要再修改Reader类了,给多人并行开发带来了极大的便利,Reader和Book、Newspaper可以同时开工,互不影响,这样也就提高了系统的稳定性,降低了修改程序造成的风险。

 

原则:面向接口编程。抽象指的是接口或抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,
而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

注意:
1. 在代码中传递参数或关联关系时,尽量引用高层的抽象层类,即使用接口和抽象类进行变量声明、参数类型声明、
方法返回类型声明以及数据类型的转换;
2. 当一个对象和其他对象有依赖关系时,可以利用依赖注入的方法将类之间进行解耦,主要有:构造注入、Set方法注入
和接口注入;
3. 开闭是原则,里氏是基础,依赖倒置是手段;
4. 低层模块尽量都要有抽象类或接口,或者两者都有;
5. 变量的声明类型尽量是抽象类或接口;
6. 使用继承时遵循里氏替换原则。

好处:
1. 可降低类之间的耦合性;
2. 可提高系统的稳定性;
3. 可降低修改程序所造成的风险。

posted @ 2017-04-01 22:25  chenxkang  阅读(...)  评论(... 编辑 收藏