2012-07-02 7 views
8

Ich habe vor kurzem eine Klassenbibliothek geschrieben, die einige Objekte enthält, die bestimmte Dateitypen modellieren. Zum Beispiel gibt es eine abstrakte Document Klasse, mit abgeleiteten Klassen PdfDocument (Beton) und OfficeDocument (abstrakt, mit konkreten abgeleiteten Klassen wie WordDocument und ExcelDocument) usw.Wer sollte für die Auswahl der geeigneten abgeleiteten Klasse verantwortlich sein?

Derzeit wird die Art und Weise Kunden ein neues Objekt zu erstellen ist durch die Auswahl die entsprechende abgeleitete Klasse und übergibt ihr das Byte-Array. So zum Beispiel, wenn ich einen Byte-Array eines PDFDocument und ein worddocument habe, würde ich so etwas wie:

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

Ist das akzeptabel Design, dass der Kunde muss wissen, was Klasse abgeleitet zu benutzen? Oder wäre ich besser dran, alle außer der abstrakten Klasse Document zu verstecken und etwas wie ein abstraktes Fabrikmuster zu verwenden, um den korrekten abgeleiteten Typ zurückzugeben? z.B .:

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

Beachten Sie, dass die abgeleiteten Typen hinzufügen keine zusätzliche Eigenschaften/Methoden die abstrakten Klasse, implementieren sie nur die abstrakten Methoden auf unterschiedliche Weise.

+0

Definitiv die 2. Option. Ermöglicht eine wesentlich einfachere zukünftige Erweiterbarkeit und bedeutet, dass Benutzer weniger Zeit mit dem Aktualisieren von Klassendeklarationen verbringen, wenn neue, passendere Typen hinzugefügt werden. –

+0

Hat die 'Document'-Klasse alles, was der Endbenutzer jemals mit einem bestimmten 'Dokument' tun muss, oder wird gelegentlich (oder häufig) Zugriff auf Funktionalität benötigt, die für einen abgeleiteten Typ spezifisch ist? – Servy

+0

@Servy Ja, die Klasse 'Document' hat eine öffentliche abstrakte Methode. Alle abgeleiteten Klassen bestehen nur aus geschützten und privaten Hilfsmethoden (plus der überschriebenen öffentlichen Methode) mit dem einzigen Zweck, die eine öffentliche Methode zu implementieren. – Andrew

Antwort

9

Der zweite Ansatz ist viel besser als der erste, weil es die Existenz von Word und Pdf-Dokumenten von den Benutzern Ihrer Bibliothek versteckt. Dies wird besonders wichtig, wenn Sie sich entscheiden, weitere Dokumenttypen hinzuzufügen - z. Rtf, Html und so weiter: Die Benutzer würden die Vorteile der neu hinzugefügten Typen erhalten, ohne ihren Code neu kompilieren zu müssen. Tatsächlich würden sie gar nicht bemerken, dass Sie etwas verändert haben: Wenn es richtig gemacht wird, wird ihr Code "einfach funktionieren" mit den Dokumenten, von denen sie nie wussten, dass sie existieren.

P.S. Wenn Sie das Bytearray scannen und den richtigen Typ daraus ermitteln können, kann Ihre API "einige Punkte für Stil verdienen", indem Sie den zweiten Parameter eliminieren.

+0

Danke. Ich werde auf jeden Fall schauen, ob ich den Typ aus dem Byte-Array herausfinden kann, der einzige Grund, warum ich die Erweiterung in meinem Beispiel hinzugefügt habe, war, dass es nach einigen kurzen Recherchen keine sichere Methode zur Bestimmung der Datei gab Geben Sie jedes Mal aus der Binärdarstellung ein. – Andrew

3

Wenn die abgeleiteten Typen keine Eigenschaften/Methoden hinzufügen und Sie die technische Möglichkeit haben zu bestimmen, welcher Typ für ein gegebenes Byte [] verwendet wird, würde ich die abgeleiteten Klassen nicht einmal öffentlich machen die Oberfläche von Sachen, die der Konsument analysieren muss, wenn er seine Bibliothek lernt. Haben Sie einfach eine statische Factory-Methode wie zB public static Document OpenDocument(byte[] data) in der Document-Klasse.

+0

Danke. Ich werde mit der Factory-Methode statt einer abstrakten Fabrik gehen (was für den Zweck, den ich erreichen muss, wie Overkill aussieht). – Andrew

+0

* "Wenn die abgeleiteten Typen keine Eigenschaften/Methoden hinzufügen" * Das ist ein ziemlich großes "wenn". Es gibt viele Dinge, die möglicherweise mit einem bekannten Dateityp gemacht werden können, die nicht mit einem generischen "Dokument" gemacht werden können. – Servy

+0

@Servy Ich stimme zu, aber für den Zweck meiner Bibliothek, die ich nicht in der Frage angegeben habe, macht sie nur einige Änderungen an den Binärdaten.Die Funktionalität ist ziemlich spezifisch, in diesem Fall denke ich, dass die Annahme in Ordnung ist (die einzige Notwendigkeit für die abgeleiteten Klassen besteht in erster Linie darin, dass die Änderungen und ihre Implementierung vom Dateityp abhängen). – Andrew