2015-11-06 60 views
3

最近,我有一个面试问题,显示的问题是传递参数作为其接口。现在,我一直觉得你必须通过Concretes,因为没有办法知道实现哪个实例化。另外,我总是觉得你“可以”返回接口......但是你应该回归混凝土(以及)。将接口传递到RESTFUL API调用

问:参数化接口是一个坏主意吗?
问:返回接口“好吗”?
问:如果存在多个问题,您将如何知道实例化哪个派生?

更新 - 以使其更清晰
对不起,我澄清...

如果我送这个给服务器:
- 它将如何知道哪些推导实例? (这会失败,对吧?)

var customer = { Name: 'Frank The Tank', Orders: [] } 
$.get(url, customer, cb); 

对战,如果我把这个给服务器:
- 它将如何知道哪些推导实例?
- 具体类型是否遵循? (我从来没有真正选中)

var customer = new InsideSalesCustomer('Frank The Tank', []); 
$.get(url, customer, cb); 

var customer = new ExternalCustomer('Bilbo Baggins', []); 
$.get(url, customer, cb); 

代码示例:

public interface ICustomer 
{ 
    string Name { get; } 
    IEnumerable<IOrder> Orders { get; } 
} 

public interface IOrder 
{ 
    IEnumerable<IOrderItem> OrderItems { get; } 
} 

public interface IOrderItem 
{ 
    IEnumerable<IProduct> Products { get; } 
} 

public interface IProduct 
{ 
    string Name { get; } 
} 

public class CustomersController : ApiController 
{ 
    // I was always told Customer & OrderItem should be a concretes 
    public IEnumerable<IOrderItem> ListOrderItems(ICustomer customer) 
    { 
     // Return All OrderItems for all orders 
     return customer.Orders.SelectMany(o => o.OrderItems); 
    } 
} 
+0

如果有一个正确的理由有'ICustomer'或'IOrder'的多重派生(可能特定于一个'ICustomer'),那么使用通用代码没有任何问题,因此您不必重复每个具体类型。我总是尽可能在最抽象的层上运行功能来实现目标。 –

+0

'ApiController'提供(鼓励你使用)'IHttpActionResult'的几个实现。所以可以肯定地说,返回一个接口非常好。我很好奇面试官说的是正确的? – Jonesopolis

+0

@PrisonerZERO,你是什么意思,“你怎么知道哪个派生实例化?”? – Jonesopolis

回答

2

通过在这种情况下使用接口您允许更多的代码重用。任何使用ICustomer接口的客户都可以传入此方法。另外,使用IOrderItem的任何OrderItem都可以迭代。这为您提供了更多可能的用途,而不仅仅是使用USACustomersUSOrderItem,这将锁定您的具体类型。通过使用interfacses,您可以传递任何客户并遍历返回的OrderItem。

回答您的问题

问:参数化接口是一个坏主意?

不,这在你的情况下绝对不是一个坏主意。

问:返回接口“好吗”?

是的,返回一个接口只是返回实现该接口的任何类型。

问:如果存在多个问题,您将如何知道实例化哪个派生?

您可以收集对象的类型,它永远不会返回您的界面。

Type objectType = myObject.GetType(); 

然后,您可以根据需要投射对象。 ref

object result = Convert.ChangeType(input, someOtherObject.GetType()); 
+0

我更新了问题...你可以看看吗? –

+0

没问题,回答! –

0

这张贴,实际上将无法正常工作中的WebAPI的一切,可能已经对面试问题的目的。

为什么? WebAPI模型绑定器将无法找出给定的运行时类型ICustomer,因此,当您实际进入该方法时,您会看到ICustomer对象因为在绑定过程中被跳过而仅为null。

我只是用一个超简单的例子自己试了一下。如果我使用ICustomer作为我的参数类型,它总是为空。 如果我使用Customer,一切工作正常。

能够使用接口作为参数通过使用自定义模型活页夹,顺便说一句,它只是不直接“开箱即用”。关于如何做到这一点有很多材料,我不会在这里进入。