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...
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.
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
and BusinessLayer
objects directly.
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.
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.
精彩评论