处理继承接口的不同对象

本文关键字:对象 继承 接口 处理 | 更新日期: 2023-09-27 18:11:41

我一直在学习如何在c#中正确使用接口,我想我基本上理解了它们应该如何使用,但仍然对某些事情感到困惑。

我想创建一个程序,将创建一个CSV从销售订单或发票。因为它们都非常相似,所以我想我可以创建一个iddocument接口,可以用来制作CSV文档。

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(iddocument)方法,但是我如何处理与销售订单和发票不同的几个字段?这是对接口的不良使用吗?

处理继承接口的不同对象

你不继承接口,你实现它们;在这种情况下,接口是一个抽象;它说"所有实现这个接口的东西都有以下共同特征(属性,方法等)"

在您的案例中,您发现事实上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表示。

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