【发布时间】:2016-11-23 07:45:48
【问题描述】:
我在 factory 方法中遇到了依赖倒置的问题,它也违反了开放封闭原则。我的代码如下所示
public interface IWriter
{
void WriteToStorage(string data);
}
public class FileWriter : IWriter
{
public void WriteToStorage(string data)
{
//write to file
}
}
public class DBWriter : IWriter
{
public void WriteToStorage(string data)
{
//write to DB
}
}
现在我使用工厂类来解决对象创建问题。它看起来像下面的代码
public interface IFactory
{
IWriter GetType(string outputType);
}
public class Factory : IFactory
{
public IWriter GetType(string outputType)
{
IWriter writer = null;
if (outputType.Equels("db"))
{
writer = new FileWriter();
}
else if (outputType.Equels("db"))
{
writer = new DBWriter();
}
}
}
现在的问题是Factory 类违反了开放封闭原则,因此它也违反了依赖倒置原则
然后
public interface ISaveDataFlow
{
void SaveData(string data, string outputType);
}
public class SaveDataFlow : ISaveDataFlow
{
private IFactory _writerFactory = null;
public SaveDataFlow(IFactory writerFactory)
{
_writerFactory = writerFactory;
}
public void SaveData(string data, string outputType)
{
IWriter writer = _writerFactory.GetType(outputType);
writer.WriteToStorage(data);
}
}
由于上述工厂类破坏了依赖倒置,我删除了 Factory 类并更改了 SaveDataFlow 类,如下所示
public class SaveDataFlow : ISaveDataFlow
{
private IWriter _dbWriter = null;
private IWriter _fileWriter = null;
public SaveDataFlow([Dependency("DB")]IWriter dbWriter,
[Dependency("FILE")]IWriter fileWriter)
{
_dbWriter = dbWriter;
_fileWriter = fileWriter;
}
public void SaveData(string data, string outputType)
{
if (outputType.Equals("DB"))
{
_dbWriter.WriteToStorage(data);
}
else if (outputType.Equals("FILE"))
{
_fileWriter.WriteToStorage(data);
}
}
}
并使用 Unity 框架解决了这些依赖项
container.RegisterType<IWriter, DBWriter>("DB");
container.RegisterType<IWriter, FileWriter>("FILE");
但最终我还是打破了开放封闭原则。 我需要更好的设计/解决方案来解决这样的问题,但我必须遵循 SOLID 原则。
【问题讨论】:
-
在我看来你不想要工厂。实际上,您需要一种策略模式。但是,如果您正在使用
[Dependency("DB")],那么您将自己耦合到您的 DI 框架,这也不理想。 -
为什么
SaveDataFlow需要处理字符串输入类型?你不能简单地注入合适的作家吗?至于工厂,如果您希望使其可扩展,那么您可以使用反射来扫描程序集并找到IWriter的所有实现者,以便自动注册它们。
标签: c# dependency-injection unity-container solid-principles open-closed-principle