Go 控制反转和依赖注入
当前问题
- 当模块A依赖B,模块B依赖C,模块C依赖D,模块D依赖模块A时,GO编译就会报错 import cycle not allowed (循环依赖)
- 多个模块就像多个齿轮一样共同协作完成任务,但是也可能会出现一个齿轮出现问题将会影响到整个齿轮组的运转的情况
- 真实的服务可能需要依赖很多其他的服务,比如第三方,内部模块或者其他内部服务,当多个模块相互依赖增多时,也会增加项目的耦合,不利于后续功能拓展
解决方法
控制反转
控制反转(Inversion of Control
)(IOC
)是一种是面向对象编程中的一种设计原则,用来降低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦
由于引进了中间位置的“第三方”,也就是IOC
容器,使得A、B、C、D这4个对象没有了耦合关系,将控制权都交给了IOC
,齿轮之间的转动全部依靠“第三方”,对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来
对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度
依赖注入
假设原本A依赖B,现在IOC
需要new
一个B出来,然后把B的实例注入到A里面去,这样A就可以正常使用基于B的方法了,这个过程被称为依赖项注入,而基于IOC
的这种方法就叫做依赖注入
“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC
容器主动注入
代码演示
当前场景
目前有一个创建文章Article
的接口,分别做了http接口和gRPC接口。为了避免代码冗余,现在将具体逻辑放在gRPC中实现,而http接口将会调用gRPC函数来实现对应功能,而gRPC方法的调用需要创建相应的实例才能调用,下面是改造前的代码
1 |
|
此时可以看出在http包中,创建router前,初始化了gRPC调用的实例,并将此实例传进了http具体的业务函数中,从而实现能在http接口中使用gRPC的函数,减少代码冗余的同时增加了http模块对gRPC模块的依赖
1 |
|
引入IOC
下面是使用控制反转和依赖注入的模式后的代码
1 |
|
1 |
|
从上面改进后的代码可以看出,之前的逻辑是是http模块依赖gRPC模块,使用IOC
容器后,逻辑就变成了IOC
容器初始化gRPC模块的实例,然后再将该实例注入到http模块中,解除了http模块和gRPC模块之间的耦合
总结
使用控制反转和依赖注入可以减少项目的耦合度,有利于后续功能的拓展
项目中由于引入了第三方
IOC
容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,现在又凭空多出一道手续,会使得项目变得不太直观
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!