依赖倒置 (DIP)
架构0期-W2-实战作业
请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?
请描述一个你熟悉的框架,是如何实现依赖倒置原则的。
一、什么是依赖倒置原则(DIP)?
1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
2.抽象不应该依赖于细节,细节应该依赖于抽象。
3.层次化角度来说,就是高层决定低层,高层被重用。
4.依赖倒置原则更像是一种应该养成的编程习惯,它要求你面向接口编程。
这里提到的“高层模块”和“低层模块”,从调用链的角度来说就是调用者属于高层,被调用者属于低层。
举个例子:
controller通常都是依赖service里的方法,依赖倒置的意思就是controller层应该依赖接口,也就是controller来定义接口,然后service去实现这些接口,也就是依赖倒置了。
二、依赖倒置的例子
以golang的Gin框架为例,我的体会是它使用了IoC(Inversion of Control)和DIP(Dependency Inversion Principle)。
以一个简单的例子开始,如下是一个最简单的http请求响应+server的代码。
gin.Default()函数返回的是一个Engin指针,而后续的func函数是类似语句的Web业务函数,由此我们很形象的就能认为Gin框架是高层模块,而具体的Web应用程序就是底层模块,不考虑DIP,就应该是高层依赖底层框架,就像下面这样。
但这样是明显不可行的,假如Web程序改动了涉及到了Gin了该怎么办?Gin官方是不可能给我们改的,要改也是我们自己改。把DIP加进去考虑这个问题就是应该是像下面这样
Gin和Web应用程序同时依赖与抽象才能隔离变化,这也就刚好符合了DIP的原则。
这个我在Gin的源码中找到的DIP的依据,应用程序r.get都是依赖于IRouter接口,而IRouter最终依赖的是net/http,gin.Context最终依赖的也是net/http,因此可以确定我上面的分析。
再说说IoC
r.Get是在将“Web应用程序”的逻辑注入到Gin(容器)中,func(c *gin.Context)函数就将自己的HttpHandler注册进入Gin这个容器中,Gin在截获到ping这个Get请求的时候会主动调用func这个后续的方法,这个过程也就是Ioc的过程,也可以形象的理解为它非常符合好莱坞原则,即(Web应用程序)你不要联系我(Gin),我(Gin)会主动找你(Web应用程序),
综上所述,Gin符合了两个面向对象的设计原则,IoC(Inversion of Control)和DIP(Dependency Inversion Principle)。
三、为什么有时候依赖倒置原则又被称为好莱坞原则?
好莱坞原则是这样描述的
Don't call me,I'll call you. 别打电话给我,有事我会打电话给你。
好莱坞原则在IoC(Inversion of Control) 控制反转中得到了很好的体现,IoC就是由容器来负责控制对象的生命周期和对象间的关系。
通俗来将就是所有的类都在容器登记,类是个什么东西,需要什么东西都告诉容器,容器会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由容器来控制,也就是说控制对象生存周期的不再是引用它的对象,而是容器。
这体现了好莱坞原则,类不用主动找容器要你需要的东西,在容器需要你(类)的时候会主动找你的,即低层应该只管好自己的工作(具体实现),而高层自有它自己的工作
依赖倒置原则是指高层不依赖低层只依赖抽象,低层也依赖抽象。
综上所述,好莱坞原则和依赖倒置还是有不同点的,相同点是他们都是描述高层与下层之间关系的,都是为了解决类之间的紧耦合而总结出来的
评论