依赖注入&构造函数疯狂修正
本文关键字:疯狂 构造函数 注入 依赖 | 更新日期: 2023-09-27 18:13:23
看完这个问题如何避免依赖注入构造函数的疯狂?我对我的应用程序设计还有一些顾虑。假设我有一个类,它在构造函数中接受几个参数:
public class SampleViewModel
{
public SampleViewModel(IReader1 reader1, IReader2 reader2, IReader3 reader3)
{
// ...
}
}
IReaderX
是一个从不同来源检索数据的接口,它看起来像这样:
public interface IReader1
{
int Value1 { get; }
string Value2 { get; }
}
现在,如果我想将这些接口聚合成一个,我就必须创建另一个类,比如ReaderManager
,它将充当底层类属性的包装器。大量的管道代码。如果你问我的话,我觉得不太好。
我尝试使用Composition并将所有读取器作为ReaderManager
类的属性,但如果我试图在外部使用这些读取器,我会违反Demeter定律。
所以问题是:我应该如何减少构造函数依赖的数量,不相互通信,只暴露属性,而不是内部逻辑?
从两个不同的角度来看:消费者和更高层次的设计。
从' SampleViewModel '的角度看
它不喜欢有这么多合作者吗?也许如果它有自己的选择,它只会有一个合作者。这个合作者会是什么样子?创建一个接口来表示它的角色。
例如:public interface ISampleViewModelReader
{
int Value1 { get; }
string Value2 { get; }
double Value3 { get; }
string Value4 { get; }
}
public class AggregatedSampleViewModelReader : ISampleViewModelReader
{
public AggregatedSampleViewModelReader(IReader1 reader1, IReader2 reader2, IReader3 reader3)
{
// ...
}
// ...
double Value3 { get { return reader2.Value3; } }
// ...
}
public class SampleViewModel
{
public SampleViewModel(ISampleViewModelReader reader)
{
// ...
}
}
你指出你对这种方法有顾虑,因为它会涉及"大量的管道代码"。但是考虑到这些管道代码将在有或没有包装器类的情况下存在。通过定义包装器类,至少可以确定一个对象,它的唯一职责是处理这个管道,而不是将其混合到SampleViewModel
的其他职责中。
从更高层次的设计角度看
其他对象如何使用IReaderX
对象?IReader1
、IReader2
和IReader3
经常一起使用吗?IReader1
和IReader3
呢?
问这个问题的目的是识别"隐藏的"抽象,以便使它们更显式。如果某些对象经常串联使用,它通常代表了更广泛的设计概念。
但有时玫瑰就是玫瑰。也许SampleViewModel
是唯一使用IReaderX
对象的东西。也许SampleViewModel
唯一的责任就是集合个人读者。在这种情况下,有几个合作者并没有什么错。
如果稍后添加了另一个合作者(例如,IReader4
),那么所有这些评估都应该再次进行。有时候设计就是突然出现在你眼前。