【问题标题】:Who should be responsible for selecting the appropriate derived class?谁应该负责选择合适的派生类?
【发布时间】:2012-07-02 16:05:26
【问题描述】:

我最近编写了一个类库,其中包含一些对某些类型的文件进行建模的对象。比如有一个抽象的Document类,有派生类PdfDocument(具体的)和OfficeDocument(抽象的,有具体的派生类如WordDocumentExcelDocument)等

目前客户端创建新对象的方式是选择适当的派生类并将字节数组传递给它。例如,如果我有一个 PdfDocument 和一个 WordDocument 的字节数组,我会执行以下操作:

var wordDocument = new WordDocument(wordDocumentByteArray);
var pdfDocument = new PdfDocument(pdfDocumentByteArray);

这是可接受的设计吗,客户端必须知道要使用什么派生类?还是我最好隐藏除抽象 Document 类之外的所有内容并使用抽象工厂模式之类的东西来返回正确的派生类型?例如:

var wordDocument = DocumentFactory.GetDocument(wordDocumentByteArray, "docx");
// pass file extension so we know what the file is

请注意,派生类型不会向抽象类添加额外的属性/方法,它们只是以不同的方式实现抽象方法。

【问题讨论】:

  • 绝对是第二个选项。允许更容易的未来可扩展性,并意味着当添加新的、更合适的类型时,人们花费更少的时间来更新类声明。
  • Document 类是否具有最终用户对给定Document 所做的一切,或者他们是否偶尔(或经常)需要访问特定于更衍生的功能输入?
  • @Servy 是的,Document 类有一个公共抽象方法。所有派生类仅包含受保护的和私有的辅助方法(加上被覆盖的公共方法),其唯一目的是实现一个公共方法。

标签: c# oop class-design


【解决方案1】:

第二种方法比第一种方法好得多,因为它向图书馆的用户隐藏了 Word 和 Pdf 文档存在的事实。当您决定添加更多文档类型时,这一点变得尤为重要 - 例如Rtf、Html 等:用户无需重新编译代码即可从新添加的类型中受益。事实上,他们甚至不会注意到您已经更改了任何内容:如果操作正确,他们的代码将“正常”处理他们从未知道存在的类型的文档。

附:如果您可以扫描字节数组并从中找出正确的类型,那么您的 API 可以通过消除第二个参数来“为风格赢得一些分数”。

【讨论】:

  • 谢谢。我肯定会看看我是否可以从字节数组中找出类型,我在示例中添加扩展名的唯一原因是因为从一些非常简短的研究来看,似乎没有确定文件的万无一失的方法每次都从二进制表示中键入。
【解决方案2】:

如果派生类型不添加任何属性/方法,并且您具有确定给定字节[]使用哪种类型的技术能力,我什至不会公开派生类...它们只会增加消费者在学习你的图书馆时必须解析的东西的表面积。只需在 Document 类中有一个像 public static Document OpenDocument(byte[] data) 这样的静态工厂方法。

【讨论】:

  • 谢谢。我将使用工厂方法而不是抽象工厂(这对于我需要完成的事情来说似乎有点矫枉过正)。
  • “如果派生类型不添加任何属性/方法” 这是一个相当大的“如果”。可以想象,许多事情可以用已知的文件类型完成,而不能用通用的“文档”完成。
  • @Servy 我同意,但出于我的图书馆的目的,我没有在问题中说明,它所做的只是对二进制数据进行一些修改。该功能非常具体,因此在这种情况下,我认为假设是可以的(首先,派生类的唯一需要是因为更改及其实现因文件类型而异)。
猜你喜欢
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多