笔者在使用Golang的时候就发现构建系统依赖树非常繁琐,New了很多对象,又手工代码将它们拼接起来,写了一堆非常冗繁的代码。然后就开始想,要是Golang像Java一样有一个好用的依赖注入框架就好啦。
果不其然,Golang还真有,居然还是大厂facebook团队开源的。
Golang的很多用户都不是来自Java,依赖注入他们可能听过,可是从来没有玩过。为了说明依赖注入有多好用,我先用Java代码来解释一下。
先来看一下没有依赖注入的Java世界是怎样的
Golang的很多用户都不是来自Java,依赖注入他们可能听过,可是从来没有玩过。为了说明依赖注入有多好用,我先用Java代码来解释一下。
先来看一下没有依赖注入的Java世界是怎样的
在main方法里面,我们new出来很多对象,然后用他们构造了一颗依赖树。我们还写了很多构造器,为了能方便的构造出每个节点。
这里我们使用的是另一个开源大厂google的依赖注入框架Guice。我们发现main方法缩减了很多代码,所有的new操作都不见了,然后我们还发现每个对象的构造器也消失了,取而代之的是多了两个注解@Singleton和@Inject,Singleton表示类是单例的,Inject表示当前字段使用依赖注入自动设置。好处不用多说,一目了然,就是帮我们节省代码,省去了很多系统初始化时构建一系列对象的细节。另外Guice还需要定义一个Module,把依赖树的叶子节点手工实例化一下,叶子结点对象往往不是简单的依赖注入,而需要手动构造。如果把整个系统的状态比喻成现实的物理世界,那么Module里面干的事就是宇宙大爆炸,所有一切对象的输入源点。依赖注入仅仅帮我们省去了中间节点的构建工作。
在我们的例子中,这棵树还谈不上复杂,毕竟节点数很有限,节点之间的连接也很有限。在大型的复杂业务系统中,这样的对象那就是成百上千了,如果没有使用依赖注入的话,那就真是剪不断理还乱了。
好,接下来我们说说facebookgo团队开源的这个Inject框架如何使用。我们还使用上面的例子,用golang 改写一下。
首先,我们看一下没有依赖注入的Golang世界是怎样的。
跟Java版本一样,定义了不少构造器,然后手工组装依赖树。
然后我们把这段代码改造成facebookgo依赖注入版本的
这个跟Java版本也很类似,只是Module的定义直接放在了main方法里,也就是上面代码中的Provide方法调用,@Singleton不需要了,@Inject变成了`inject:""`。然后用Populate方法一次性将整个依赖树构建出来就可以使用了。
看这个开源库的源码发现,整个类库的实现才500多行代码。这是多么轻量级的一个类库,只不过代码这么短,功能也不会太多,相比Java的依赖注入而言,它的功能就单一太多了。不过没关系,相比Guice而言这些缺失的功能不是必须的,能帮我们省掉很多代码它已经做得很好了,这就足够了。要知道Java里面非常完善的依赖注入框架80%的代码那都是为了实现那20%的特殊功能,基本功能所需要的代码量是非常少的。
阅读相关文章,关注微信公众号/知乎专栏/头条号【码洞】