Guice随笔

随着时间的推移. 当初吵翻了天的依赖注入再也不是什么新鲜玩意儿.

在日复一日给资本家拉磨的平淡中, Spring和自己写的小玩具也都被扔在记忆的垃圾堆里不必提起. 对Guice的激情也逐渐磨灭到麻木和冷淡了.

日常一些邮件列表中, 仍然能看到对使用Guice之类框架的反感或者死忠的两种截然不同的观点碰撞, 甚至于是否使用依赖注入也仍然没有尘埃落定.

个人从前是依赖注入的坚定粉丝, 也是Guice的欢呼者. 到现在我在需要使用一个框架的时候还是会使用Guice, 但是, 各位看官, 如果你们以前曾经见过那个挥舞着Guice超级大棒见什么都砸几下的不屈身影, 他已经移民去火星了.

如今, 我理想的使用Guice的方法. 就是说我有一堆类, 互相有依赖关系, 假设A依赖B, C, D; B依赖X, Y, Z; C依赖于D, B和D需要是Singleton, 那么就写成:
[code]
class A {
@Inject A(B b, C c, D d) {...}
}

@Singleton
class B {
@Inject B(X x, Y y, Z z) {...}
}

class C {
@Inject C(D d) {...}
}

@Singleton
class D {
@Inject D(...) {}
}
[/code]

如果你对Guice熟悉的话, 就会看出来这正是Guice幼儿园小班级别的代码啊.

这就对了, 几年用下来的经验告诉我, Guice对这种最简单的情况的处理方式是最简单, 最直接的. 不需要写什么Module, 不需要什么binding, 那些东西带来太多的复杂性.

很多对依赖注入或者Guice的疑虑主要集中在代码不容易理解, 依赖关系被隐藏在Module中不容易发现等等. 但是我发现这些疑虑在尽量有意减少module和binding的前提下, 都不再是问题.

比如我在读A类的代码, 需要知道B到底是怎么回事, 直接一个F3(Eclipse), 就到了B的代码里面. 然后需要知道X是怎么回事, 再一个F3. 许多在线代码检查工具也支持这种简单的导航.

相比之下, 手工注入(就是说, 某个地方你需要手工调用new A(b, c, d))反而难于理解, 因为我还要去找new A()在什么地方调用的, B, C, D都是怎么传递进来的.

当然, 这个前提是我的B, C, D, X, Y, Z都是类而不是interface. 我发现在一个大的代码库里, interface很多时候是有害的. 因为它们人为的增加了一个间接层, 增大了跟踪导航阅读代码的难度. 在加上在Guice里你就需要额外的Module, 额外的binding, 额外的@ForApple, @ForOrange的注解, 然后Module多了, 你就要面对如何管理整个项目, 怎么样在不同的main()函数里选择不同的Module, 而又避免不能把一个Module通过不同的父Module安装两遍等等复杂讨厌的问题.

interface只有在真正存在那么一个自然的抽象的情况下才是适合的. 比如, 一个List和ArrayList就是两个不同的抽象. java.sql.Connection和任何特定的Connection实现也是两个不同的抽象.

而如果你需要写一个User, Authenticator, 或者TaskMonitor, 直接写就是了. 不管三七二十一上来先一个IUser接口加一个User实现, 或者一个User接口加一个UserImpl实现, 那就是人为增加的复杂性. 类和接口命名的尴尬雷同就已经表明这根本不是一个自然的抽象.

okay, 理想如此, 事实上当然不可能永远都没有一个接口, 两个实现的情况出现. 不过, 如果Module和binding只在有这种需求的时候才写的话, Guice代码也还可以相对容易地管理和理解. (当然, 还要小心robot leg问题的出现, 然后如果你用assistedinject来绕过这个问题的话, 又是一些额外的复杂性需要管理和维护了).

嗯, 嗯. 大致就随笔到这里. 回头我还会写写为什么我不喜欢assistedinject, 以及为什么Guice的Module会难以管理等等.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值