使用继承接口

时间:2016-10-04 17:12:53

标签: c# interface

我一直在努力学习如何在c#中正确使用界面,我想我大多理解应该如何使用它们,但仍然对某些事情感到困惑。

我想创建一个程序,用于从销售订单或发票创建CSV。由于它们非常相似,我想我可以创建一个可用于制作CSV文档的IDocument接口。

class Invoice : IDocument
{
    public Address billingAddress { get; set; }
    public Address shippingAddress { get; set; }
    public Customer customer { get; set; }
    public List<DocumentLine> lines { get; set; } 
    // other class specific info for invoice goes here       
}

我可以创建一个方法CreateCSV(IDocument),但我如何处理与销售订单和发票不同的几个字段?这是一个糟糕的接口使用?

1 个答案:

答案 0 :(得分:3)

你没有继承接口,你实现它们;在这种情况下,接口是抽象;它说&#34;所有实现此接口的东西都具有以下共同特征(属性,方法等)&#34;

在您的情况下,您发现事实上InvoicesSales Orders并没有完全相同的特征。 因此,从以CSV格式表示它们的角度来看,它并不是一个很好的抽象(尽管对于其他事情,比如计算文档的价值,它是一个很好的抽象)

有很多方法可以解决这个问题,这里有两个(很多)

将工作委托给班级

您可以声明一个ICanDoCSVToo接口,该接口以某种表示CSV的结构返回文档(让我们说一个包含字段和值集合的CSVFormat类)。 然后,您可以在InvoicesSales Orders上实现此功能,特别是针对这些用例,当您想将其中任何一种转换为CSV格式时,可以通过ICanDoCSVToo接口传递它们。

  

但是,我个人并不喜欢这样,因为您并不真的希望您的业务逻辑与您的导出/格式化逻辑相混淆 - 这违反了SRP。请注意,您可以使用抽象类实现相同的效果,但最终它是相同的概念 - 您允许某人告诉知道自己的类,来完成工作。

通过工厂将工作委托给专门的对象

你也可以创建一个Factory类 - 让我们说一个CSVFormatterFactory,它给出一个IDocument对象来确定要返回的格式化程序 - 这是一个简单的例子

public class CSVFormatterLibrary
{
     public ICSVFormatter GetFormatter(IDocument document)
     {
       //we've added DocType to IDocument to identify the document type.
        if(document.DocType==DocumentTypes.Invoice)
        {
             return new InvoiceCSVFormatter(document);
        }
        if (document.DocType==DocumentTypes.SalesOrders)
        {
            return new SalesOrderCSVFormatter(document);
        }
        //And so on
     }
}
  

实际上,您可能会使这个通用并使用IOC库来担心您将返回哪个具体实现,但它是相同的概念。

然后,各个格式化程序本身可以将IDocument强制转换为正确的具体类型,然后执行生成该特定类型的CSV表示所需的任何内容。

还有其他方法可以解决这个问题,但工厂选项相当简单,在您考虑其他选项时应该让您启动并运行。