简体   繁体   中英

Who should be responsible for selecting the appropriate derived class?

I recently wrote a class library that includes some objects that model certain types of files. For example, there is an abstract Document class, with derived classes PdfDocument (concrete) and OfficeDocument (abstract, with concrete derived classes such as WordDocument and ExcelDocument ), etc.

Currently the way clients create a new object is by selecting the appropriate derived class and passing it the byte array. So for example, if I have a byte array of a PdfDocument and a WordDocument, I would do something like:

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

Is this acceptable design, that the client must know what derived class to use? Or would I be better off hiding all but the abstract Document class and using something such as an abstract factory pattern to return the correct derived type? eg:

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

Note that the derived types do not add additional properties/methods to the abstract class, they just implement the abstract methods in different ways.

The second approach is much better than the first one, because it hides the very fact of existence of Word and Pdf documents from the users of your library. This becomes especially important when you decide to add more document types - eg Rtf, Html, and so on: the users would get the benefits of the newly added types without having to recompile their code. In fact, they would not even notice that you have changed anything: if done right, their code will "just work" with the documents of type they have never knew existed.

PS If you can scan the byte array and figure out the correct type from it, your API can "earn some points for style" by eliminating the second parameter.

If the derived types don't add any properties/methods and you have the technical ability to determine what type to use for a given byte[], I would not even make the derived classes public... they just increase the surface area of stuff the consumer will have to parse when learning your library. Just have a static factory method like like public static Document OpenDocument(byte[] data) in the Document class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM