我正在使用C#,但我的问题适用于任何OOP语言。
我有许多不同的对象,它们使用一系列服务。我想访问这些服务的方式来满足一些约束,但我正在努力找出一个好的设计。
我认为这些都是很好的目标,但事实证明它们在实践中很难实现。我目前的方法是一种依赖注入手动:
class MyObject
{
// ...
public MyObject(IFooService fooService, IBarService barService)
{
this.fooService = fooService;
this.barService = barService;
}
}
到目前为止一切顺利。但是当我有很多服务依赖项时会发生什么?我有几十个对象,其中一些需要访问许多服务。
我考虑过构建一个“服务容器”对象并将其传递给:
class Services
{
// ...
public IFooService FooService
{
get { return this.fooService; }
}
public IBarService BarService
{
get { return this.barService; }
}
public Services(IFooService fooService, IBarService barService)
{
this.fooService = fooService;
this.barService = barService;
}
}
class MyObject
{
// ...
public MyObject(Services services)
{
this.services = services;
}
}
这节省了输入,但它模糊了对象实际使用的服务。给定构造函数,MyObject
可能会使用任何!
答案 0 :(得分:5)
这可能表明存在两个问题
无论如何,如果你认为你的课程不是太复杂,你可以阅读,维护和测试它,我不会过多关注依赖的数量。我更喜欢拥有清晰,明确的依赖关系,而不是依赖于作为服务工厂并取决于所有事物的上帝对象。这将损害可测试性和可读性。
答案 1 :(得分:2)
Mark Seemann用解决方案here描述了这个问题。
总结:
它会为您的代码带来另一个抽象,但提取的行为很可能会描述应该分开的域概念。
答案 2 :(得分:1)
“我考虑建立一个”服务容器“对象”
就像你已经注意到的那样,只是将问题转移到其他地方,但并没有真正解决它。
有一种类似的设计模式,通常称为"Parameter Object" ......但我不认为它真的适用于此。根据前一句中引用的文章,它只适用于......
“......一组特定的参数,往往会一起传递。”
因此,参数对象模式仅适用于您的情况,如果您有多个类都依赖于相同的服务组件组合(如果您的构造函数参数列表非常长,则这种情况不太可能)。
“当我有很多服务依赖项时会发生什么?”
如果你有如此多的服务依赖项,你的构造函数参数列表变得笨拙的怪物,那么或许你的类有太多的责任,即尝试做太多事情你应该把它分解成几个小班。
我不记得我在哪里阅读它,我并不是说我完全同意,但是一些聪明的人曾经声称任何对象不应该有超过两个字段/引用其他对象。这只是为了表明有些人非常重视“单一责任原则”并走极端(恕我直言)来实现这一目标。