我刚刚读完了 Mark Seemann 的书.NET 中的依赖注入(inject),现在我正在尝试重构一些遗留代码。 (在这个阶段,我不依赖于任何特定的 DI 容器,而只是试图将所有依赖项移动到一个地方)。
我正在查看以下工厂类,它通过使用 archiveReader.GetArchiveType()
读取存档的前几个字节来确定 ArchiveType
,然后返回一个实例ArchiveRestorer
基于 ArchiveType
枚举。
public class ArchiveRestorerFactory : IArchiveRestorerFactory
{
public ArchiveRestorer Create(ArchiveReader archiveReader)
{
ArchiveType type = archiveReader.GetArchiveType();
switch (type)
{
case ArchiveType.CurrentData:
return new CurrentDataArchiveRestorer(archiveReader);
break;
case ArchiveType.HistoricalData:
return new HistoricalDataArchiveRestorer(archiveReader);
break;
case ArchiveType.AuditTrail:
return new AuditTrailArchiveRestorer(archiveReader);
break;
default:
throw new Exception("ArchiveRestorerFactory error: Unknown value for ArchiveType.");
}
}
}
如何重构它,使该类不依赖于具体类型 CurrentDataArchiveRestorer
、HistoricalDataArchiveRestorer
和 AuditTrailArchiveRestorer
?
我是否应该将三个混凝土恢复器移到工厂的构造器中?
public ArchiveRestorer Create(ArchiveReader archiveReader,
ArchiveRestorer currentDataArchiveRestorer,
ArchiveRestorer historicalDataArchiveRestorer,
ArchiveRestorer auditTrailDataArchiveRestorer)
{
// guard clauses...
// assign to readonly fields
}
这似乎是建议的方法here ,但是当只需要一个恢复器时它会实例化所有三个恢复器?如果我有 20 种不同的可能的具体实现呢?
我觉得我应该为每种类型的恢复器实现一个具体的工厂并返回它,但我只是将一个 new
替换为另一个。
重构它的最佳方法是什么?
最佳答案
根据您已有的代码,我这样做的方法是为每个具有 Create()
方法的对象创建一个工厂。
我也有一个用于这些工厂的接口(interface),并让它们继承自通用工厂接口(interface)。
然后您可以使用这些接口(interface)作为注入(inject)构造函数的点。
这将被称为类似这样:
case ArchiveType.CurrentData:
return _currentDateArchiveRestorerFactory.Create(archiveReader);
break;
或者,最好有一个工厂来创建给定类型的实例。由于所有这些对象都是恢复器,您可以只基于 enum
而不是 switch
创建实例。
_restorerFactory.Create(ArchiveType.CurrentData);
关于c# - 如何将依赖注入(inject)应用于抽象工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9117403/