Ade*_*lin 4 refactoring dependency-injection
将类注入其他类被认为是不好的,其中一些论点是很难模拟一个类,并且将对象耦合在一起。
但是我看到许多开发人员每天都会这样做,并且大多数模拟框架都非常擅长模拟类并提供测试模拟,那么这是什么问题呢?
抽象类型(如接口)比具体类倾向于更稳定(随时间变化较小)。依靠更稳定的事物通常风险较小。将它们放在一起,相较于具体类,通常依赖于接口的风险较小。
我还发现,当我更多地依赖接口时,更容易检测到行为的重大变化。当接口必须更改时,发生了重要的事情。当发生不重要的事情(令人惊讶地)导致接口发生变化时,我将其解释为提高设计抽象水平的信号。对于具体的类,此信号对我而言不那么“清晰”,清晰,明显。
与直接在客户端模块中实例化这些风险相比,注入一个具体的类所产生的风险要少得多。如果您不担心注入具体类的风险,请花一会儿,然后等待该风险成为问题。然后,您可以决定介意多少。幸运的是,随着重构的进行,从具体类中提取接口是相当安全的。只要记住,当需要时,提取出客户端所需的最小接口,不要盲目地将每个具体的类方法放入接口中。(接口隔离原理。)
某些(有影响力的)人,例如 Robert Martin,声称在源代码中使用具体类的名称基本上是您应该避免的,以防止“耦合太紧”。
让我引用他关于“敏捷原则”的书:
高级模块不应该依赖于低级模块。两者都应该依赖于抽象。抽象不应该依赖于细节。细节应该取决于抽象
并进一步:
考虑依赖于低级模块的高级模块的含义。它是包含应用程序的重要策略决策和业务模型的高级模块。这些模块包含应用程序的标识。然而,当这些模块依赖于较低级别的模块时,对较低级别模块的更改会对较高级别的模块产生直接影响,并可以迫使它们依次更改。这种困境是荒谬的!应该影响低级详细模块的是高级策略设置模块。包含高级业务规则的模块应该优先于包含实现细节的模块,并且独立于包含实现细节的模块。高级模块不应该以任何方式依赖低级模块。
但当然,在现实中,总是有平衡的。当你非常确信
那么更喜欢接口而不是类就没有多大意义了。
但是 - 如果有疑问,接口是更好的方法。
我不得不经常向人们解释,他们使用 PowerMock 以允许模拟某些最终类/方法的想法是错误的方法;更好的答案是将参数的类型更改为某个接口。
| 归档时间: |
|
| 查看次数: |
396 次 |
| 最近记录: |