WebService有单独的方法来填充复合类中的属性吗?

时间:2010-12-07 19:56:07

标签: wcf web-services

我正在构建一个Web服务来检索复合对象列表。是否应该立即填充列表中每个对象的复杂子属性,或者是否可以让客户端根据需要请求该信息。

示例:

class InvoiceLine
{
  string ServiceDescription;
  decimal ChargeTotal;
}

class Invoice
{
  string InvoiceNumber;
  string CustomerNumber;
  List<InvoiceLine> InvoiceLines;
}

//Returns all invoices send to this customer
public List<Invoice> GetInvoices(string customerNumber);

在WebService中使用另一种方法是不好的设计:

public List<InvoiceLine> GetInvoiceLines(string invoiceNumber)

并要求客户首先获取所有已保存发票的清单(其中包含InvoiceLines的空列表,并期望他们致电:

invoices[0].InvoiceLines = webService.GetInvoiceLines(customerNumber);

模拟“懒惰”。

这似乎是一种节省数量的好方法,但代价是在需要时获取更多数据。这是值得的还是某种反模式?

返回一个人口稠密的物体似乎是不对的......

提前感谢任何指针/链接。

3 个答案:

答案 0 :(得分:2)

在设计服务时,服务接口粒度始终是一项重要决策。由于Web服务调用通常是网络调用,或者至少是进程外调用,因此它们相对昂贵。如果您的服务接口太精细(或“聊天”),那么这可能会影响性能。当然,在确定正确的粒度级别时,您需要考虑您的应用程序和您的要求。 Software components: Coarse-grained versus fine-grained虽然有点干,但有一些很好的信息。

  

返回一个似乎不对   人口稀少的物体......

我同意。

在您的情况下,我们假设InvoiceLines的检索成本很高,而且大部分时间都不需要。如果是这种情况,您可以封装发票摘要或标题并返回该信息。但是,如果消费者需要完整的发票,那么他们就有能力这样做。

class InvoiceLine
{
  string ServiceDescription;
  decimal ChargeTotal;
}

class Invoice
{
  InvoiceSummary InvoiceSummary;
  List<InvoiceLine> InvoiceLines;
}

class InvoiceSummary
{
  string InvoiceNumber;
  string CustomerNumber;
}

public InvoiceSummary GetInvoiceSummary(string customerNumber);
public Invoice GetInvoice(string customerNumber);

一般来说,我更愿意避免对服务的消费者强加一系列调用。首先,您必须获得发票,然后您必须获取详细信息。这可能会导致性能问题以及应用程序之间更紧密的耦合。

答案 1 :(得分:1)

Web服务不应该“健谈”:您通过网络进行通信,任何请求/响应交换都需要时间。你不想要求客户在问他一次时问十次。

让客户端立即请求所有数据。

如果结果是性能问题,那么允许客户端指定他们想要的数据量,但是仍然应该在一次调用中返回所有数据。

答案 2 :(得分:1)

我认为这不是一个糟糕的设计,我认为这是一个你需要考虑的权衡。更重要的是:返回完整的对象图,或潜在的传输节省。

例如,如果您更有可能拥有数百或数千InvoiceLines的客户,并且您只需要在非常具体的情况下使用这些客户,那么将它们拆分为您的方式似乎是合乎逻辑的提。

但是,如果你几乎总是需要InvoiceLines,并且你通常只会说10个实例,那么总是将它们一起发送会更有意义。