Get dependencies from a dependency
假设我有一个宠物管理员和一只猫:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class PetManager { PetManager(IBusinessLayer businessLayer, IWashingService washingService); IBusinessLayer BusinessLayer; IWashingService WashingService; } class Cat { Cat(PetManager manager, string name, int levelOfStupidity); } |
现在让我们假设我的猫需要洗衣服务,是这样的巴亚德,从我的宠物经理的依赖?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Cat { Cat(PetManager manager, string name, int levelOfStupidity) { this.manager = manager; this.name = name; this.levelOfStupidity = levelOfStupidity; } IWashingService WashingService { get { return this.manager.WashingService; } } } |
我强烈怀疑是的,那会是…
如前所述,cat是一个具体的类,因此它可以公开任何有意义的内容。将构造函数参数公开为只读属性是一件非常明智的事情。
然而,如果cat实现了i cat,我会强烈怀疑通过i cat暴露像petmanager这样的依赖关系是一种泄漏的抽象。
本质上,接口是一种访问修饰符。公开对具体类的依赖关系是有意义的,但不公开对接口的依赖关系。依赖项是通过构造函数注入的,因此永远不能成为接口的一部分-构造函数签名是我们的自由度。
我认为唯一的问题是,cat依赖于一个具体的petmanager,如果你将petmanager抽象为一个服务,能够提供一个清洗服务,对我来说就更好了。
好吧,如果您订阅了控制/依赖注入风格的反转(看起来您可能是这样),那么您必须考虑权衡。
我想顽固派会怎么说,你可能会从中得到一些维护问题。他们当然不会因为参数太多而显得拘谨。因此,例如,如果您在10种不同的宠物上使用petmanager,而这10种宠物中的一种需要一些特殊的功能,从而导致petmanager发生变化,那么您可能会影响其他9个依赖petmanager的类,因此最好是单独地注入依赖项。
但是要务实…您所要做的是将一系列相关的依赖项抽象到另一个类中,并将其作为一种分组的方式传递,或者简化对象构造。我同意。我甚至有点喜欢。
但要完全公开:我并没有其他人那么顽固。我可能是一个异端,但更少的参数看起来和气味更干净。我有一种烦人的感觉,如果五年后再问我,我可能会有不同的感觉,但这就是我现在的处境。
我想这要看情况了。通常,当你发现自己有一个ThingManager类时,你只是将逻辑分组到一个类中,而不是将它分解为它的组成依赖项。在您的情况下,似乎您根本不应该有petmanager类,而是直接为您的