Quando abbiamo una gerarchia di oggetti che è puramente un'eredità di semantica e non di comportamenti, allora inevitabilmente dobbiamo scrivere "instanceof" o "if/else" ovunque per eseguire il controllo del tipo di esecuzione.Quando "if else"/"instance of" sono inevitabili, come possiamo migliorare il design oltre all'utilizzo del pattern visitor?
E.g.
Se ho una gerarchia di oggetti che ha
Class Function
Class Average extends Function
Class Sum extends Function
Class Max extends Function
Se c'è un metodo chiamato calcolare() in queste classi, quindi non abbiamo problemi, possiamo solo prendere il vantaggio del polimorfismo e questo disegno soddisfa l'LSP.
Tuttavia, se per qualche ragione non vogliamo aggiungere questo metodo calculate() a questa gerarchia, questi oggetti sono oggetti stateless puramente semplici che rappresentano solo la semantica.
allora siamo costretti a scrivere il seguente codice ovunque:
if (function instanceof Average)
//perform average
else if(function instanceof Sum)
//perform sum
else if(function instanceof Max)
//perform max
Il codice di cui sopra indica una cattiva progettazione, perché si scrive il codice in tutto il mondo e questo disegno è fragile ed è difficile da cambiare in seguito. Suppongo che se le funzioni numeriche sono limitate e il calcolo della funzione si trovano in un singolo punto questo forse è ok dipende dalla complessità.
Quello che ho saputo finora è che per risolvere l'approccio di cui sopra, l'unico modo possibile è quello di implementare un modello di visitatore, c'è un altro modo per risolvere il progetto di cui sopra oltre all'utilizzo del modello di visitatore?
Un problema che posso vedere dal modello di visitatore è che il metodo di accettazione del modello di visitatore non restituisce valore, questo non è conveniente a volte se il metodo accept() non soddisfa completamente il requisito.
per quanto riguarda il modello di strategia: http://en.wikipedia.org/wiki/Strategy_pattern? –
non credo che la strategia funzioni, per favore controlla i miei commenti sotto – grumpynerd
hmmm okay. Ma se quei blocchi if-elseif-else sono ovunque nel tuo progetto, potrebbe funzionare per ridefinire questo blocco in un metodo di utilità separato –