设计原则之依赖反转原则(DIP)
依赖反转原则的英文翻译是“ Dependency Inversion Principle”,缩写为 DIP。Robert Martin 在 SOLID 原则中是这样定义它的:“High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.”。王争老师描述是这样的:高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。
所谓高层模块和低层模块的划分,简单来说就是,在调用链上,调用者属于高层,被调用者属于低层。
刚开始学习依赖反转,估计会问谁依赖谁?怎么反转?
首先有个问题请想想,调用者和被调用者、消费者和生产者,谁依赖谁?因为有可被调用的事物(类、模块),调用者才可以调用,生产出产品了消费者才可以消费使用,所以相信大部分人都会认为调用者依赖被调用者、消费者依赖生产者。
以消费者和生产者为例:
但实际是顾客才是上帝,让上帝依赖你,你还有活路吗?
所以生产者的产品要想被消费,需要了解消费者的需求?这个时候依赖就反转了。
需求是消费者想要的产品(抽象的产品),生产者根据这个需求去生产具体的产品。这里的需求从广义讲可以理解为协议、接口、约定、风俗习惯等。
这样理解是不是觉得依赖反转也很好理解?那为什么大部分人一开始会不理解呢?这跟很多文章的例子有关系。网上很多文章一上来就举很具体的例子。
如:
看到这样的图,潜意识里会怎么分高层模块与低层模块?
是不是像下面这样:
这样划分模块本身没有错,但是不是觉得依赖并没有反转。在平时的开发过程中,ICar都认为是低层的代码,shopper依赖ICar,说明高层依赖低层,依赖并没有反转。这正是例子太具象,让人产生了这样的潜意识。
而实际上虽然ICar被划分到低层模块,但是ICar应该理解成顾客买车的需求的抽象,Jeep、Passat这些具体车商只是根据需求实现而已。
此原则就是告诉大家要基于接口(抽象)而非实现编程的设计思想,至于为什么基于接口,请看基于接口(抽象)而非实现编程的设计思想章节。
本文地址:https://blog.csdn.net/xjj1314/article/details/112008752