Libro di rifattorizzazione di Martin Fowler: l'istruzione switch utilizza i dati di altri oggetti, perché è così male? Si cerca una spiegazione più profonda.

6

Nell'esempio di codice sotto l'oggetto Rental utilizza i campi Movie per eseguire un'istruzione switch. Martin dice: questa è una cattiva idea, ma non fornisce una spiegazione più profonda del perché?

Ovviamente, si può dire che questo significa un sacco di accoppiamento tra film e noleggio, o che il film è mal incapsulato, ma queste sono solo parole (quasi prive di significato), ancora una volta, non spiegano il perché? Non vanno alla radice della domanda, per così dire. Non forniscono molta comprensione.

Cosa mi piacerebbe sapere se esiste un principio di progettazione più profondo e generale per cui avere un passaggio a Rental è una cattiva idea?

In altre parole, come fa Martin a sapere che l'istruzione switch è sull'oggetto sbagliato? Da dove prende questa intuizione? Qual è il suo processo di pensiero?

    
posta jhegedus 26.01.2014 - 05:37
fonte

5 risposte

18

Che cosa accade quando Movie ha aggiunto un nuovo tipo ad esso come Movie.DISCOUNT ?

Of course, you can say that this means a lot of coupling between Movie and Rental, or that Movie is badly encapsulated but those are just (almost meaningless) words, again,

Sono parole profondamente significative. Significa che quando cambi Movie , ora puoi cambiare anche Rental dato che sono strettamente accoppiati. Peggio ancora, in un linguaggio come Java non c'è nulla che ti dica che questa istruzione switch deve essere modificata (sebbene la maggior parte degli IDE lo faccia, per essere onesti). Quindi se non modifichi l'istruzione switch, ora hai un bug che sta dando alle persone l'affitto gratuito dei film.

L'obiettivo principale della progettazione del programma (e del refactoring dell'estensione) sta ottimizzando il codice attorno alla domanda "cosa succede quando questo cambia?". Questo è il processo mentale che ti aiuterà a capire molte delle motivazioni del libro.

    
risposta data 26.01.2014 - 22:55
fonte
3

Ci sono due problemi:

  1. Poiché priceCode fa parte della classe Movie , è probabile che lo switch si trovi all'interno della classe Movie . Che localizza il lavoro in switch nella classe che definisce cosa è priceCode . Se la classe Movie dovesse decidere di restituire codici diversi, allora è nella posizione migliore per modificare lo switch.

  2. Probabilmente lo switch non è l'unica cosa nella classe Movie che dipende da priceCode . Ciò suggerirebbe di creare classi derivate della classe Movie , una per priceCode . Ognuno avrebbe la propria versione sostituita di getCharge . Questo metodo sottoposto a override non solo avrebbe gli algoritmi separati che sono attualmente in case , ma potrebbe anche dipendere da dati specifici per le singole classi derivate.

risposta data 26.01.2014 - 05:54
fonte
2

Posso solo essere d'accordo con questo se PriceCode è un altro oggetto. In questo caso, sarebbe più appropriato fare lo switch come PriceCode.REGULAR e non Movie.REGULAR per esempio. Quindi Martin starebbe parlando di Movie con costanti definite su PriceCode, che sembra un cattivo design.

O forse la sua idea è di pensare a classi con un accoppiamento molto basso, ad esempio, vuoi che Rental lavori con un'altra classe compatibile con Movie ma questo è qualcos'altro (ad esempio, vuoi noleggiare un CD invece di un film ).

Probabilmente sta parlando della seconda opzione.

    
risposta data 26.01.2014 - 05:47
fonte
2

Il concetto centrale di OO è incapsulare le operazioni vicino ai dati. L'idea di Fowler è che il film debba decidere da solo quanto vale (potrebbe essere attraverso l'ereditarietà in più film?).

Non condivido completamente l'idea di Fowler:

  1. Ci sono altri modi per affrontarlo. Cosa succede se la "politica di noleggio" è un oggetto in sé? Il film dovrebbe rappresentare i dati più puri sul film, e non come una società di noleggio consideri un film come un oggetto affittabile.
  2. Questo non funziona nelle applicazioni aziendali: i dati vengono serializzati, trasformati, sezionati, divisi, uniti ... garantendo che l'idea di Fowler sia difficile.
  3. Qual è l'unità di incapsulamento? È meglio considerare l'affitto come un composito? Questo composito possiede questi elementi di dati delle politiche di noleggio e film e offre un servizio che sarebbe l'unico punto di decisione.

Molte volte, le idee di Fowler sono generalmente più adatte per insegnare come costruire piccole applicazioni. Questi principi dovrebbero a loro volta aiutare a costruire idee chiare sulla creazione di applicazioni più grandi che contengono materiali compositi.

    
risposta data 27.01.2014 - 21:43
fonte
1

Perché affidarsi alle proprietà (o ai campi) di un'altra classe per rendere un calcolo una cattiva idea? La risposta è inerente al titolo del libro: refactoring. Se vengono apportate modifiche a tale classe, l'ambito e il significato dei dati possono cambiare. Se viene creato un nuovo tipo di film / codice prezzo, anche questo codice deve essere regolato.

Che indica il problema più preciso: fare affidamento su un enum / tipo in un'altra classe. Se Noleggio ha utilizzato una classe di affittuari con un'età e ha offerto sconti in base all'età, non sarebbe un tale problema. È improbabile che l'età cambi. Se, d'altra parte, la nostra ipotetica classe di affittuari avesse un Affittuario.Tipo (aziendale, familiare, individuale, minorenne, anziano), sarebbe molto più probabile che si modificasse, rompendo così l'affitto.

    
risposta data 27.01.2014 - 16:57
fonte

Leggi altre domande sui tag