0%
本站点已归档(不再维护),点击立即前往新站点: https://yourbatman.cn

系统设计:你的service要用Dependency Injection吗?

当大潮退去,才知道谁在裸泳。
作者:A哥(YourBatman)
公众号:BAT的乌托邦(ID:BAT-utopia)
文末是否有彩蛋:有

前言

各位小伙伴大家好,我是A哥。以下文章来源于硅谷成长攻略 ,作者大西Xi

依赖注入,它不仅仅是Spring,而是一种通用思想。本文硅谷大佬用简短的语句道出了其核心思想,值得参阅。


正文

我最近在给一个Go service升级重构framework。我和一个朋友提了下,他点评到,搞这种基础升级,就是悟道啊,类似于《禅与摩托车维修艺术》。

他这个说法挺有道理的,大家平时写业务代码,更多是站在地面想着怎么快速完成目标。只有趁升级的时候,才有空飞在1000公里天上,想想为啥要这么设计的哲学问题。

今天就给大家介绍一个重要的基本设计原则:Dependency Injection。这个设计模式在复杂的业务service非常有用,没有它,每次改一个模块的初始化接口,你都要把用到这个模块的代码都改一遍,非常麻烦。

今天很多主流的开源framework都用到了它,比如:

  • Guice: Google 维护的一个基于Java的 lightweight dependency injection framework
  • Fx: Uber 维护的一个基于Go的dependency injection framework
  • AngularJS: Google 维护的基于JavaScript的前端 framework
  • Wire: Google维护的Compile-time Dependency Injection for Go

什么是Dependency Injection?

这个翻译成中文叫做依赖注入,用大白话解释就是即插即用。

举个例子,假设你的service里面有个模块A叫“笔记本”,它有个依赖叫“耳机”,用了这个设计原则,你需要听音乐,只用插”耳机“就可以了。后端service中常见的“耳机”依赖有哪些?比如Logging,输出Metrics等。

下面的代码是用 Dependency Injection 创建模块A的伪代码:

1
2
3
4
5
6
7
func CreateLaptopService() *LaptopService {
panic(wire.Build(
wire.Struct(new(Logger), "*"),
NewHttpClient,
NewHeadphoneService,
))
}

不用这个原则,有什么后果?

你需要自己搞一堆耳机的原材料,然后自己组装配置。模块A需要耳机的时候,手动装一遍,模块B需要耳机的时候,再手动装一遍。

下面是不用Dependency Injection,创建模块A的伪代码:

1
2
3
4
5
6
func CreateLaptopService() *LaptopService {
logger := &Logger{}
headphone := &Headphone{}
client := NewHttpClient(logger)
return NewLaptopService(logger,client,headphone)
}

如果service很简单,还可以忍受。但是在业务很复杂时,项目里有上百个依赖的时候就更痛苦了。每次配置”耳机“,你都需要手动把所有模块的接口配置一遍。

下面是不用Dependency Injection,再创建模块B的伪代码:

1
2
3
4
5
6
7
8
9
10
func CreateDesktopService() *DesktopService {
logger := &Logger{}
headphone := &Headphone{}
client := NewHttpClient(logger)
cdDisk := &CdDisk{}
cdDrive := &CdDrive{cdDisk}
headphone := &Headphone{}

return NewLaptopService(logger, client, headphone, cdDrive)
}

优点一:减少依赖关系、方便重复使用

有了Dependency Injection,每次配置时,模块A和模块B都是连接到同一个设置的耳机,你只要组装一次耳机。即使有100个模块都需要用耳机,你也只需要组装一次。

优点二:提高可维护性

而对于更复杂的场景,模块B依赖于一个”CD机“,而”CD机“又需要一个”CD碟片“。如果有100个类似的模块都有”CD机“,而你需要做的只是更改”CD机”里的CD碟片,有了Dependency Injection,你也可以省去在“电子厂”里面翻找所有”CD机“的时间,只需要换一张”CD碟片“。

优点三:简化测试流程

每次升级时,只需要测试”耳机“本身的性能,测试不需要和使用”耳机“的代码有任何关联。


总结

最后,划一下重点,Dependency Injection适用的场景,是复杂的大型系统,有很多个服务相互依赖的情况。它能够避免一些重复劳动带来的小错误,提高生产力。如果是一个人写的小玩具,那杀鸡就不用牛刀啦。


关注YourBatman

Author A哥(YourBatman)
个人站点 www.yourbatman.cn
E-mail yourbatman@qq.com
微 信 fsx1056342982
活跃平台
公众号 BAT的乌托邦(ID:BAT-utopia)
知识星球 BAT的乌托邦
每日文章推荐 每日文章推荐

BAT的乌托邦

  • 本文标题: 《系统设计:你的service要用Dependency Injection吗?》
  • 本文作者: 大西Xi
  • 发布时间: 2020-06-18 07:17:57
  • 本文链接: https://www.yourbatman.cn/x2y/5715d235.html
  • 许可协议: 本站所有文章均采用 BY-NC-SA 许可协议。转载:No!转发:Yes!
-------------您已触及底线 感谢阅读-------------