假设我有一个 PetManager 和一个 Cat :
class PetManager
{
PetManager(IBusinessLayer businessLayer, IWashingService washingService);
IBusinessLayer BusinessLayer;
IWashingService WashingService;
}
class Cat
{
Cat(PetManager manager, string name, int levelOfStupidity);
}
现在让我们说我的猫需要洗衣服务,这样做是否会让我的宠物经理受到依赖?
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; }
}
}
我强烈怀疑是的,它会......
答案 0 :(得分:4)
如上所述,Cat是一个具体的类,所以它可以暴露任何有意义的东西。将构造函数参数公开为只读属性是一件非常明智的事情。
但是,如果Cat实现了ICat,我强烈怀疑通过ICat暴露像PetManager这样的依赖是漏洞抽象。
实质上,interfaces serve as a sort of access modifier。在具体类上公开依赖关系是有意义的,但在接口上却没有。依赖关系是通过构造函数注入的,因此永远不能成为接口的一部分 - 构造函数签名是我们的自由度。
答案 1 :(得分:1)
我想这取决于。通常,当您发现自己拥有SomethingManager类时,您只需将逻辑分组到一个类中,而不是将其分成它的组成依赖项。在您的情况下,您似乎根本不应该拥有PetManager类,而是直接为WashingService
和BusinessLayer
对象注入依赖项。
答案 2 :(得分:1)
好吧,如果你订阅了控制/依赖注入风格的反转(看起来你可能会这样),你必须考虑权衡。
我猜顽固分子可能会说你可以从中获得一些维护问题。他们肯定似乎没有关于只有大量参数的狡猾。因此,例如,如果您在10种不同类型的宠物上使用PetManager,并且这10只宠物中的一只需要一些导致PetManager更改的特殊功能,那么可能影响依赖于PetManager的其他9个类,因此,仅仅单独注入依赖项会更好。
虽然务实但是...你正在做的是将一堆相关的依赖项抽象到另一个类中,并将其作为一种分组方式传递,并可能简化对象构造。我很好。我甚至喜欢它。
虽然完全披露:我并不像其他人那样顽固。我可能是一个异教徒,但参数看起来更少,对我来说更清洁。我有这种唠叨的感觉,如果五年后再问我一次,我可能会有不同的感受,但那就是我现在所处的位置。
答案 3 :(得分:1)
我认为唯一的问题是猫取决于具体的Petmanager,如果你将PetManager抽象为服务,能够提供洗涤服务,这对我来说听起来更好。