处理继承接口的不同对象
本文关键字:对象 继承 接口 处理 | 更新日期: 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)方法,但是我如何处理与销售订单和发票不同的几个字段?这是对接口的不良使用吗?
你不继承接口,你实现它们;在这种情况下,接口是一个抽象;它说"所有实现这个接口的东西都有以下共同特征(属性,方法等)"
在您的案例中,您发现事实上Invoices
和Sales Orders
并不完全具有相同的特征。因此,从以CSV格式表示它们的角度来看,它不是一个很好的抽象(尽管对于其他事情,如计算文档的值,它是一个很好的抽象)
有很多方法可以解决这个问题,这里有两个
将工作委托给类
您可以声明一个ICanDoCSVToo
接口,它以某种表示CSV的结构返回文档(我们说一个CSVFormat
类,它包装了字段和值的集合)。然后你可以在Invoices
和Sales 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选项相当简单,应该可以让您在考虑其他选项时启动并运行。