C# 用于返回可能不总是完全填充的数据结构对象的设计模式?
在这种情况下,我查询一个以XML形式返回数据的RESTful web服务(使用.NET)。我已经围绕API编写了包装函数,因此,我不返回原始XML,而是返回反映XML结构的完整.NET对象。XML可能非常复杂,因此这些对象可能非常大,嵌套程度很高(例如,包含的集合反过来可能包含其他集合等) RESTAPI有一个返回完整结果或基本结果的选项。基本结果返回完整结果所返回的数据的一小部分。目前,我通过为两种类型的请求返回相同的.NET对象来处理这两种类型的响应,但是在基本请求中,一些属性没有填充。这最好通过(非常简单的)代码示例来说明: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对象来处理这两种类型的响应,但是在基本请求中,一些属性没有填充。这最
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()
{
// ...
};
}
}