2012-07-02 19 views
8

Ho recentemente scritto una libreria di classi che include alcuni oggetti che modellano determinati tipi di file. Ad esempio, v'è un estratto Document di classe, con le classi derivate PdfDocument (cemento) e OfficeDocument (astratto, con classi concrete derivate come WordDocument e ExcelDocument), eccChi dovrebbe essere responsabile della selezione della classe derivata appropriata?

attualmente il modo i clienti a creare un nuovo oggetto è selezionando la classe derivata appropriata e passandogli la matrice di byte. Così, per esempio, se ho un array di byte di un PdfDocument e un WordDocument, vorrei fare qualcosa di simile:

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

È questo disegno accettabili, che il cliente deve sapere cosa classe derivata da usare? O sarebbe meglio nascondere tutti tranne la classe astratta Document e utilizzare qualcosa come un modello di fabbrica astratto per restituire il tipo corretto derivato? es .:

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

Nota che i tipi di derivati ​​non aggiungono ulteriori proprietà/metodi per la classe astratta, hanno appena implementare i metodi astratti in modi diversi.

+0

Sicuramente la seconda opzione. Consente un'estensibilità futura molto più semplice e significa che le persone impiegano meno tempo ad aggiornare le dichiarazioni di classe quando vengono aggiunti nuovi tipi più appropriati. –

+0

La classe 'Document' ha tutto ciò che l'utente finale avrà mai bisogno di fare con un dato' Documento', o avrà a volte (o frequentemente) bisogno di accedere a funzionalità specifiche per un tipo più derivato? – Servy

+0

@Servy Sì, la classe 'Document' ha un metodo astratto pubblico. Tutte le classi derivate consistono solo di metodi di supporto protetti e privati ​​(oltre al metodo pubblico sottoposto a override) con l'unico scopo di implementare l'unico metodo pubblico. – Andrew

risposta

9

Il secondo approccio è molto meglio del primo, perché nasconde il fatto stesso dell'esistenza di documenti Word e Pdf dagli utenti della libreria. Ciò diventa particolarmente importante quando decidi di aggiungere altri tipi di documenti, ad es. Rtf, Html e così via: gli utenti otterrebbero i benefici dei nuovi tipi aggiunti senza dover ricompilare il loro codice. Infatti, non si accorgerebbero nemmeno di aver cambiato nulla: se fatto bene, il loro codice "funzionerà" semplicemente con i documenti di tipo che non hanno mai saputo esistere.

P.S. Se riesci a scansionare l'array di byte e a capire il tipo corretto da esso, la tua API può "guadagnare alcuni punti per stile" eliminando il secondo parametro.

+0

Grazie. Cercherò sicuramente di vedere se riesco a capire il tipo dall'array di byte, l'unica ragione per cui ho aggiunto l'estensione nel mio esempio è perché da alcune ricerche molto brevi sembrava che non ci fosse un metodo infallibile per determinare il file digita ogni volta dalla rappresentazione binaria. – Andrew

3

Se i tipi derivati ​​non aggiungono proprietà/metodi e si ha la capacità tecnica di determinare il tipo da utilizzare per un determinato byte [], non renderei pubbliche le classi derivate ... semplicemente aumentano la superficie di materiale che il consumatore dovrà analizzare durante l'apprendimento della libreria. Basta avere un metodo factory statico come public static Document OpenDocument(byte[] data) nella classe Document.

+0

Grazie. Vado con il metodo factory invece di una factory astratta (che sembra eccessivo per quello che devo realizzare). – Andrew

+0

* "Se i tipi derivati ​​non aggiungono proprietà/metodi" * È piuttosto grande "se". Ci sono molte cose che potrebbero essere fatte con un tipo di file noto che non può essere fatto con un "Documento" generico. – Servy

+0

@Servy Sono d'accordo ma per lo scopo della mia libreria, che non ho indicato nella domanda, tutto ciò che fa è apportare alcune modifiche ai dati binari.La funzionalità è abbastanza specifica quindi in questo caso penso che l'ipotesi sia ok (l'unica necessità per le classi derivate in primo luogo è perché le modifiche e la loro implementazione variano in base al tipo di file). – Andrew