用于返回可能并非总是完全填充的数据结构对象的设计模式?

时间:2011-06-13 15:38:09

标签: c# .net oop design-patterns data-structures

我遇到的情况是我正在查询以XML格式返回数据的RESTful Web服务(使用.NET)。我已经围绕API编写了包装器函数,这样我就不会返回原始XML,而是返回镜像XML结构的完整.NET对象。 XML可能非常复杂,因此这些对象可能非常大并且嵌套很多(即包含集合,而这些集合可能包含其他集合等)。

REST API可以选择返回完整结果或基本结果。基本结果返回完整结果所做的一小部分数据。目前,我通过为两种类型的请求返回相同的.NET对象来处理这两种类型的响应 - 但在基本请求中,某些属性未填充。最好通过(非常简单的)代码示例显示:

public class PersonResponse
{
    public string Name { get; set; }
    public string Age { get; set; }
    public IList<HistoryDetails> LifeHistory { get; set; }
}

public class PersonRequest
{
    public PersonResponse GetBasicResponse()
    {
        return new PersonResponse() 
        { 
            Name = "John Doe", 
            Age = "50", 
            LifeHistory = null 
        };
    }

    public PersonResponse GetFullResponse()
    {
        return new PersonResponse() 
        { 
            Name = "John Doe", 
            Age = "50", 
            LifeHistory = PopulateHistoryUsingExpensiveXmlParsing()
        };
    }
}

正如您所看到的,PersonRequest类有两个方法都返回PersonResponse对象。但是GetBasicResponse方法是一个“精简”版本 - 它不会填充所有属性(在示例中它不会填充LifeHistory集合,因为这是一个“昂贵的”操作)。请注意,这是实际发生的非常简化版本。

然而,对我来说这有一定的气味(因为GetBasicResponse方法的调用者需要了解哪些属性不会被填充)。

我在考虑更多的OOP方法是拥有两个PersonResponse个对象 - 一个BasicPersonResponse个对象和一个FullPersonResponse,后者继承自前者。类似的东西:

public class BasicPersonResponse
{
    public string Name { get; set; }
    public string Age { get; set; }
}

public class FullPersonResponse : BasicPersonResponse
{
    public IList<object> LifeHistory { get; set; }
}

public class PersonRequest
{
    public BasicPersonResponse GetBasicResponse()
    {
        return new FullPersonResponse()
        {
            // ...
        };
    }

    public FullPersonResponse GetFullResponse()
    {
        return new FullPersonResponse()
        {
            // ...
        };
    }
}

然而,这仍然没有“感觉”正确 - 因为我不完全确定!

有没有更好的设计模式来应对这种情况?我觉得我错过了更优雅的东西?谢谢!

2 个答案:

答案 0 :(得分:3)

我认为你已经描述了代理模式。详情请见Illustrated GOF Design Patterns in C#

答案 1 :(得分:2)

我对使用继承添加'额外数据'而不是添加/修改行为感到不安。这样做的主要优点是您的方法可以在参数类型中指定它们所需的详细程度。

在这个特定的例子中,我倾向于使用第一种方法来处理数据传输对象(Response对象),但是然后立即使用这个数据传输对象来创建数据模型对象,其确切性质在很大程度上取决于你的具体应用。数据传输对象应该是内部的(因为数据字段的存在与否是实现细节),公共对象或接口应该提供更适合使用代码的视图。

相关问题