2012-06-27 16 views
13

Diciamo che ho un file CSV e creo una classe chiamata CsvFile che si estende da java.io.File. Questa classe può analizzare un file CSV e restituire alcuni dati come il numero di colonne nel file. Può anche essere utilizzato per funzioni che richiedono java.io.File come input. Come F ileUtils.copyFile(File from, File to).L'incapsulamento per interruzione di eredità?

Il mio collega pensa che espongo troppo dall'eredità. La sua idea è quella di avvolgere java.io.File trattenendolo in una proprietà privata, invece di ereditarla. Pensa di esporre tutto il metodo/proprietà pubblico dall'incapsulamento delle interruzioni di file, ma lo considero un vantaggio poiché otteniamo tutte le funzioni in java.io.File gratuitamente.

Cosa ne pensi?

+0

O o penso di no, ma la combinazione di entrambi è la via. Prima eredità in modo che la ruota non sia reinventata, piuttosto che modelli che incapsulano in modo che la ruota serva al suo scopo. –

risposta

15

avrei preferito essere d'accordo con il collega: ereditare java.util.File esporrebbe i metodi che non sono applicabili a CsvFile oggetti, come ad esempio list(), listFiles(), setExecutable(), e così via.

Fare java.util.File una proprietà dietro un getter suona come una scelta migliore: non rivela operazioni non pertinenti per gli utenti della classe e consente di ereditare da una classe base di propria scelta.

+1

da aggiungere alla risposta: sì, in questo caso l'eredità interromperà l'incapsulamento perdendo i dettagli dell'implementazione che un file CVS è implementato utilizzando un file java.io. – Soronthar

+1

potrebbe non essere un caso di o-o. Eredita per personalizzare, piuttosto che avvolgere per restringere i metodi che desideri esporre. –

+0

O o penso di no, ma la combinazione di entrambi è la via. Prima eredità in modo che la ruota non sia reinventata, piuttosto che modelli che incapsulano in modo che la ruota serva al suo scopo. –

5

Penso che tutto dipenda dallo scopo della classe. Se stai veramente cercando di estendere il comportamento, direi che ha senso. Se non si sta estendendo il comportamento di File ma si sta semplicemente creando un oggetto CSV, l'incapsulamento limiterebbe i suoi comportamenti solo a ciò che è intenzione.

1

Si potrebbe anche considerare di renderlo più generico in modo che possa accettare un InputStream o Reader formattato CSV da un'ampia varietà di fonti che non possono (o non possono facilmente) emettere sul filesystem. Puoi ancora avere un setter/costruttore java.io.File per comodità.

1

Questo è davvero un grande dibattito. Il tuo collega è dalla parte giusta della storia su questo. In generale, la questione dell'ereditarietà si riduce alle relazioni tra is-a e ha-a. In generale è più flessibile usare la composizione che l'ereditarietà. Nel tuo caso è una chiamata ravvicinata. Dopo tutto un file CSV è un file. dicendo che csvfile ha-un file non ha nemmeno un suono corretto. Ciò che potrebbe essere considerato bene è di fare l'ereditarietà, ma di avvolgere il file ereditato in modo che vengano esposti solo i metodi di file CSV che si desidera. Vorrei anche esaminare alcuni schemi di progettazione intorno a questo in cui si desidera ereditare da A, ma esporre un'interfaccia più limitata al mondo. Sono quasi sicuro che ci sia un modello di design per questo. non ricordo il nome ...

"O o penso di no, ma la combinazione di entrambi è la via: la prima eredità in modo che la ruota non sia reinventata, che i modelli che incapsulano in modo che la ruota serva scopo."

0

Forse il mio punto di vista è troppo liberale ma ... L'incapsulamento e l'ereditarietà sono lì per una ragione. (Guarda l'evoluzione dagli assemblatori ai linguaggi di alto livello). Questo è il motivo del programmatore. Con astrazioni/paradigmi di livello superiore puoi scrivere codice migliore. Il trucco è definire "migliore", naturalmente. Per me questo è manutenibilità, auto documentazione e riutilizzo del codice. Ecco perché sceglierei l'incapsulamento sull'ereditarietà nel tuo caso particolare. Forse è un po 'più di lavoro da scrivere una volta, ma molto più facile da mantenere in futuro. (Supponendo che questo materiale CSV faccia parte di un progetto più ampio, ovviamente.)

0

L'approccio descritto dal tuo collega ha anche il vantaggio che la tua API diventa molto piccola esponendo solo i metodi di cui hai veramente bisogno - il che rende chiaro come all'utente come usare la classe (puoi pensare alla tua API pubblica come una sorta di documentazione).

0

Quanto alla tua domanda

Will successione pausa incapsulamento?

Poi, secondo Effective Java di Joshua Bloch, eredità rompe sempre incapsulamento:

A differenza di chiamata di metodo, eredità viola incapsulamento [Snyder86]. In altre parole, una sottoclasse dipende dall'implementazione dettagli della sua superclasse per la sua funzione corretta.

Per quanto riguarda se si deve utilizzare l'ereditarietà o la composizione, come molte persone già detto, dipende se il vostro CsvFile è-un file, nel senso di java.util.File.