从依赖中获取依赖
假设我有一个 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; }
}
}
我强烈怀疑,是的,这将是......
Let's say I have a PetManager and a Cat:
class PetManager
{
PetManager(IBusinessLayer businessLayer, IWashingService washingService);
IBusinessLayer BusinessLayer;
IWashingService WashingService;
}
class Cat
{
Cat(PetManager manager, string name, int levelOfStupidity);
}
Now let's say that my cat needs the washing service, would it be so baaaaad, to get the dependency from my pet manager ?
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; }
}
}
I strongly suspect that yes, it would be...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如前所述,Cat 是一个具体的类,因此它可以公开任何有意义的内容。将构造函数参数公开为只读属性是一件非常明智的事情。
但是,如果 Cat 实现了 ICat,我会强烈怀疑通过 ICat 公开像 PetManager 这样的依赖项将是一个泄漏抽象。
本质上,接口充当一种访问修饰符。公开对具体类的依赖关系是有意义的,但对接口的依赖关系则不然。依赖项是通过构造函数注入的,因此永远不能成为接口的一部分 - 构造函数签名是我们的自由度。
As stated, Cat is a concrete class, so it can expose whatever makes sense. Exposing constructor arguments as read-only properties is a perfectly sensible thing to do.
However, if Cat implemented ICat I would strongly suspect that exposing a dependency like PetManager through ICat would be a leaky abstraction.
In essence, interfaces serve as a sort of access modifier. It makes sense to expose dependencies on the concrete class, but not on the interface. Dependencies are injected through the constructor so can never be part of the interface - the constructor signature is our degree of freedom.
我想这要看情况。很多时候,当您发现自己有一个 SomethingManager 类时,您只是将逻辑分组到一个类中,而不是将其拆分为其组成的依赖项。在您的情况下,您似乎根本不应该拥有 PetManager 类,而应该直接注入
WashingService
和BusinessLayer
对象的依赖项。I guess that depends. Often times, when you find yourself having a SomethingManager class, you're just grouping logic into one class instead of splitting it into it's constituent dependencies. In your situation, it seems you really shouldn't have a PetManager class at all, and instead be injecting the dependencies for your
WashingService
andBusinessLayer
objects directly.我认为唯一的问题是cat依赖于一个具体的Petmanager,如果你将PetManager抽象为一个服务,能够提供洗涤服务,对我来说听起来更好。
I think the only problem is that cat depends on a concrete Petmanager, if you abstract PetManager as a service, able to provide a washing service, it sounds better to me.
好吧,如果您赞成控制反转/依赖注入风格(看起来您可能是这样),您必须考虑权衡。
我猜顽固分子可能会说,您可能会因此遇到一些维护问题。他们当然不会因为拥有大量参数而感到拘谨。例如,如果您在 10 种不同的宠物上使用 PetManager,而这 10 种宠物中的一种需要一些特殊功能来导致 PetManager 发生变化,那么您可能会影响依赖于 PetManager 的其他 9 个类,因此,单独注入依赖项会更好。
不过,务实一点......您所做的是将一堆相关的依赖项抽象到另一个类中,然后将其作为分组和简化对象构造的方式传递。我没问题。我什至有点喜欢它。
不过,全面披露:我并不像其他人那样顽固地对待这一点。我很可能是一个异教徒,但对我来说,更少的参数看起来和闻起来更干净。我有一种挥之不去的感觉,如果五年后再次问我,我可能会有不同的感觉,但这就是我现在的处境。
Well, if you're subscribing to the inversion of control/dependency injection style (and it seems like you might be), you have to think about the trade-offs.
I guess what the diehards might say that you could get some maintenance problems from this. They certainly do not seem squeemish about just having tons of parameters. So for instance, if you used PetManager on 10 different kinds of pets, and one of those ten pets needed some special functionality that caused PetManager to change, you could impact the other 9 classes that depend on PetManager, and therefore would have been better off just injecting the dependencies individually.
Being pragmatic though... What you're doing is abstracting a bunch of related dependencies into another class and just passing that through as a way of grouping and perhaps simplifying object construction. I'm okay with it. I even kind of like it.
Full disclosure though: I'm not as diehard about this as some other people. I may well be a heretic, but fewer parameters looks and smells cleaner to me. I have this nagging sense that if ask me again in five years I may feel differently, but that's where I'm at right now.