具有许多可选属性的对象的工厂模式

时间:2013-12-05 19:40:09

标签: c# factory

我正在重构一个代表某些XML数据的类。目前,该类加载XML本身,属性实现每次都解析XML。我想分解XML逻辑并使用工厂来创建这些对象。但是有几个“可选”属性,我很难找到一种优雅的方法来处理这个问题。

假设XML看起来像这样:

<data>
    <foo>a</foo>
    <bar>b</bar>
</data>

假设foo和bar都是可选的。类实现看起来像这样:

interface IOptionalFoo
{
    public bool HasFoo();

    public string Foo { get; }
}

// Assume IOptionalBar is similar
public class Data : IOptionalFoo, IOptionalBar
{
    // ...
}

(不要问我为什么会有混合的方法和属性。我没有设计那个界面而且它没有改变。)

所以我有一个工厂,它看起来像这样:

class DataFactory
{
    public static Data Create(string xml)
    {
        var dataXml = new DataXml(xml);

        if (dataXml.HasFoo())
        {
            // ???
        }

        // Create and return the object based on the data that was gathered
    }
}

这是我似乎无法满足优雅解决方案的地方。我做了一些搜索,发现了一些我不喜欢的解决方案。假设我遗漏了构造函数中的所有可选属性:

  • 我可以将Foo和Bar实现为对数据的读/写。这满足了界面,但我不喜欢它从设计的角度来看。这些属性是不可改变的,这会捏造它。
  • 我可以在Data中提供SetFoo()和SetBar()方法。这只是在最后一种方法上涂上口红。
  • 我可以使用内部访问说明符;在大多数情况下,我不相信这个类在其组装之外被使用,所以再次它只是采用第一种技术的另一种方式。

我能想到的唯一其他解决方案是在数据类中添加一些方法:

class Data : IOptionalFoo, IOptionalBar
{
    public static Data WithFoo(Data input, string foo)
    {
        input.Foo = foo;
        return input;
    }
}

如果我这样做,Foo的制定者可以是私人的,这让我更快乐。但我真的不喜欢用很多创建方法乱丢数据对象。有很多可选属性。我已经考虑过为每个属性创建一个带有可为空的版本的get / set API的DataInitialization对象,但是很多属性都是可选的,它最终更像是我重构的对象变成了读取的外观/写版本。也许这是最好的解决方案:类的内部读/写版本。

我是否列举了这些选项?我是否需要放弃如此挑剔并坚持上述技巧之一?还是有其他一些我没有想过的解决方案?

2 个答案:

答案 0 :(得分:0)

您可以将这些关键字视为虚拟/城堡动态代理/反射/ T4脚本 - 每个人都可以在稍微不同的角度解决问题。

另一方面,这似乎是完全合理的,除非我误解了你:

private void CopyFrom(DataXml dataXml) // in Data class
{
    if (dataXml.HasFoo()) Foo = dataXml.Foo;
    //etc
}

答案 1 :(得分:0)

我做了什么:

我创建了一个新类,它代表了所有属性的读/写接口。现在,Data类的构造函数通过构造函数获取该类型的实例,并使用只读版本包装读/写属性。这有点乏味,但没有我想象的那么糟糕。