我有以下构建器/工厂,可从类中提取可序列化模型。
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
}
}
我有IFooModel的具体实现,如下所示:
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
}
public class ConcreteFooModel : IFooModel
{
public string AbstractedData1 { get; set; }
public string AbstractedData2 { get; set; }
public int AbstractedData3 { get; set; }
public bool ExtraData1 { get; set; }
}
现在出现了问题,我正在努力寻找一种方法来不引用我的构建器/工厂方法中的任何具体实现,例如
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
}
}
有关此代码的事情对我来说很奇怪,也许这是唯一的方法,但是我不喜欢被迫引用具体实现以实例化数据类IFooModel的想法。
如果我现在在IFooModel中引入另一个数据持有者接口,这将变得更加复杂
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
IBarData BarData { get; }
}
public interface IBarData
{
// some data in here
}
然后强迫我为嵌套接口创建另一个具体参考
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
在坚持SOLID原则和IoC的同时,还有更好的方法吗?
答案 0 :(得分:1)
重要的是从依赖于IFooModel
的类的角度来看待这一点。这很可能是您要防止耦合的第一个地方。
您可以通过将工厂注入需要它的类中来实现这一点,就像这样:
public class NeedsFooFactory
{
private readonly IFooBarFactory _factory;
public NeedsFooFactory(IFooBarFactory fooBarFactory)
{
_factory = factory;
}
public void WhatEverThisClassDoes(IFoo foo)
{
var fooBar = _factory.Create(foo);
// Do something
}
}
现在,将依赖工厂的类与任何实现分离。您可以替换或模拟工厂的另一个实现,该实现返回IFooModel
的另一个实现。
这时需要停下来思考一下:您是否完全需要ConcreteFooModel
的抽象?如果这只是一个保存数据的类,那么您可能就没有。
回到工厂:现在您可以用任何实现替换工厂,这不再是一个问题:
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
工厂的此实现返回IFooModel
的特定具体实现。那不好吗?在某些级别上,班级将处理具体班级。在这种情况下,我认为可以,因为这家工厂正在执行应有的工作。您不必担心它与ConcreteFooModel
耦合。如果您想要一个返回不同实现的类,则可以创建IFooBarFactory
的不同实现,该实现返回IFooModel
的不同实现。
同样,如果您质疑是否需要对foo模型进行抽象,这将不再是一个问题。您可能只需要具体的类,而重要的是您可以对填充它的工厂进行不同的实现。