构建复杂的数据类

时间:2018-11-28 22:53:05

标签: c# design-patterns inversion-of-control factory solid-principles

我有以下构建器/工厂,可从类中提取可序列化模型。

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的同时,还有更好的方法吗?

1 个答案:

答案 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模型进行抽象,这将不再是一个问题。您可能只需要具体的类,而重要的是您可以对填充它的工厂进行不同的实现。