构建复杂数据 class

Building complex data class

我有以下 builder/factory,它从 class.

中抽象出一个可序列化的模型
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; }
}

现在出现了问题,我正在努力寻找一种方法来在我的 builder/factory 方法中不引用任何具体实现,例如

public class FooBarFactory : IFooBarFactory
{
    public IFooModel Create(IFoo someClass)
    {
        // some complex model building code here
        var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
    }
}

我觉得这段代码有点臭,也许这是唯一的方法,但我不喜欢被迫引用具体实现来实例化数据的想法 class,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?

重要的是从依赖于IFooModel的class的角度来看待这个问题,这可能是您要防止耦合的第一个地方。

您可以通过将工厂注入到需要它的 class 中来完成此操作,如下所示:

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
    }
}

现在,依赖于工厂的 class 与任何实现都解耦了。您可以替换或模拟 returns IFooModel.

的不同实现的工厂的另一个实现

此时需要停下来思考一下:您是否需要对 ConcreteFooModel 进行抽象?如果它只是一个 class 来保存数据,那么你可能不需要。

回到工厂:现在您可以用任何实现替换工厂,这就不再是一个问题了:

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);
    }
}

这个工厂的实现returns一个具体的具体实现IFooModel。那不好吗?在某种程度上 classes 将处理具体的 classes。在这种情况下,我认为没关系,因为这家工厂正在做它应该做的事情。您不必担心它与 ConcreteFooModel 耦合。如果您想要 class 和 returns 不同的实现,您可以创建 IFooBarFactory 的不同实现,returns IFooModel.[=19= 的不同实现]

同样,如果您质疑是否需要对您的 foo 模型进行抽象,那么这就不再是一个问题了。很可能具体的 class 就是您所需要的,重要的是您可以拥有填充它的工厂的不同实现。