Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于返回可能不总是完全填充的数据结构对象的设计模式?_C#_.net_Oop_Design Patterns_Data Structures - Fatal编程技术网

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

C# 用于返回可能不总是完全填充的数据结构对象的设计模式?,c#,.net,oop,design-patterns,data-structures,C#,.net,Oop,Design Patterns,Data Structures,在这种情况下,我查询一个以XML形式返回数据的RESTful web服务(使用.NET)。我已经围绕API编写了包装函数,因此,我不返回原始XML,而是返回反映XML结构的完整.NET对象。XML可能非常复杂,因此这些对象可能非常大,嵌套程度很高(例如,包含的集合反过来可能包含其他集合等) RESTAPI有一个返回完整结果或基本结果的选项。基本结果返回完整结果所返回的数据的一小部分。目前,我通过为两种类型的请求返回相同的.NET对象来处理这两种类型的响应,但是在基本请求中,一些属性没有填充。这最

在这种情况下,我查询一个以XML形式返回数据的RESTful web服务(使用.NET)。我已经围绕API编写了包装函数,因此,我不返回原始XML,而是返回反映XML结构的完整.NET对象。XML可能非常复杂,因此这些对象可能非常大,嵌套程度很高(例如,包含的集合反过来可能包含其他集合等)

RESTAPI有一个返回完整结果或基本结果的选项。基本结果返回完整结果所返回的数据的一小部分。目前,我通过为两种类型的请求返回相同的.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()
        };
    }
}
然而,这仍然不是很“感觉”正确-原因我不完全确定


是否有更好的设计模式来处理这种情况?我觉得我错过了更优雅的东西?谢谢

我认为您描述了一种代理模式。请参阅此处的详细信息:

对于使用继承来添加“额外数据”,而不是添加/修改行为,我也有一种不好的感觉。这样做的主要优点是,您的方法可以指定它们在参数类型中需要的详细程度


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

LifeHistory可以返回一个空集合,而不是null。@Robinson,但这可能会误导,因为一个空的生命历史可能是来自FullResponse的有效状态。区分未被查询的数据和合法为空的数据可能很重要。@Robinson通常我会这样做,但在本例中@Dan Bryant是正确的,因为null表示“未查询数据”而不是“未返回数据”。我想您可能在这里有所了解,但我可以举一个更清楚的例子,如果可能的话…我不是模式专家,但我不确定我是否同意。代理模式通常具有对实际实例的内部引用。然后,代理负责在适当的时间实例化内部引用,并将所有对代理的请求委托给被代理的实例。顺便说一句,我想说你在CP上提到的例子也不理想,因为它直接公开代理对象,而不是将代理调用委托给代理对象。@Chris Taylor,据我所知,你指的是一个身份验证或远程代理,它确实对客户端隐藏了一个真实的对象。但我提到了一个虚拟代理,它作为一个临时的轻量级对象实例服务,并在第一次调用后调用真实数据。对于这种模式,延迟加载可能是一个更广泛使用的术语。保护和虚拟代理都被定义为至少以纯形式将请求委托给subject。这符合“德墨忒尔定律”或知识最少原则。
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()
        {
            // ...
        };
    }
}