Quale modello di progettazione per cambiare interfaccia?

0

Scusate ragazzi, avrei dovuto chiarire il fatto che il metodo modificato è astratto in Father . Quindi, se la firma del metodo cambia, anche tutte le sue implementazioni in SonX devono cambiare (almeno la firma, sebbene l'implementazione possa rimanere ferma).

Ora la domanda dovrebbe essere posta come segue: Supponiamo che io abbia la classe astratta Father e tre (o più) della sua classe di bambini Son1 , Son2 e Son3 . Ora devo cambiare un metodo, in altre parole, aggiungere un argomento a un metodo astratto di Father . Tuttavia, dovrò modificare tutti i metodi implementati (il metodo astratto modificato in Father ) in SonX , che costa troppo. La modifica alla firma del metodo in SonX è essenziale perché i client interagiscono con SonX e i client invocano la nuova versione del metodo.

Quindi la mia domanda è: esiste un modello di progettazione adatto a una situazione del genere in cui le interfacce cambieranno?

Grazie.

    
posta qingjinlyc 19.12.2014 - 02:39
fonte

2 risposte

4

Il fatto che sia necessario apportare una modifica all'interfaccia di una superclasse, ma anche non avere una necessità simile di cambiare le sottoclassi, mi suggerisce che si ha un errore di progettazione di qualche tipo. Le sottoclassi appariranno, almeno in alcuni casi, non sostituibili per la loro classe base, altrimenti avrebbero bisogno di cambiare anche.

Può darsi che la tua struttura di ereditarietà sia errata in quanto esiste una classe base non ancora identificata che tutto il padre e il figlio devono ereditare invece di essere discendenti diretti. Quindi solo padre potrebbe implementare il metodo che deve cambiare. Se c'è un comportamento in comune potrebbe appartenere alla classe base, o potrebbe essere meglio se SonX avesse un oggetto Padre a cui delegare.

    
risposta data 20.12.2014 - 19:46
fonte
2

Credo che molte persone implementino l'ereditarietà troppo velocemente. Usandolo come strumento per ridurre il codice. Questo non è lo scopo dell'eredità. Usato in questo modo, avrai sempre questi problemi perché l'ereditarietà non è implementata correttamente.

Sulle basi, le eredità spiegano una relazione tra 2 classi. La relazione è chiamata una relazione "IS A". Nel tuo caso, SonX come descrivi, non è conforme a questa relazione. Non è un padre. Lasciami spiegare ...

I principi base SOLID di cui in particolare attiro la tua attenzione sulla parte L (< a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle"> LSP per il principio di sostituzione di Liskov ). Dichiara che qualsiasi classe di figlio dovrebbe essere in grado di sostituire direttamente il suo genitore. Se non può farlo, non è conforme all'eredità corretta.

Ti trovi a infrangere questa regola ogni volta che sovrascrivi direttamente i metodi padre nelle classi figlie. I metodi principali dovrebbero essere overloaded utilizzando il polimorfismo aggiungendo un altro metodo con lo stesso nome con parametri diversi, non sovrascritto direttamente . Ad esempio ...

La classe del Padre ha un metodo Foo. Pertanto, ereditando questa classe dal Figlio, stai dicendo che il Figlio è un Padre. Pertanto, anche Son dovrebbe avere il metodo Foo.

Se dichiari il metodo Foo come virtuale in padre, così può essere sovrascritto direttamente in Son e quindi sovrascriverlo, quindi Son non è più conforme alla relazione IS A. Poiché il metodo Foo in Son fa qualcosa di diverso da come era stato originariamente definito in padre.

Tuttavia, se sovraccarichi Foo nella classe Son e gli dai una firma diversa per permetterle di fare il suo lavoro. Quindi, tecnicamente, Son può ancora fare tutte le cose che il Padre può fare insieme a qualche suo extra nel overload Foo. Questo perché il Foo originale ereditato dal Padre, è ancora intatto e pienamente funzionante.

Se davvero devi avere un modello di progettazione per disaccoppiare le astrazioni (che è anche una buona pratica in generale), esiste un modello di design chiamato il pattern del bridge e il pattern Visitor tra gli altri (come raccomandato nei commenti di Christopher e Jordao). Ma io incoraggio strongmente un pieno funzionamento (nel senso che hai fatto alcuni esempi di ciascuno nel codice reale quindi non è una comprensione teorica di tutti i principi SOLIDI.

Suggerirei anche un modello più semplice. Introduci oggetto parametro . In genere si applica se hai metodi con molti parametri (personalmente mi sento più di 3 o 4), dove fai una lezione e la passi invece.

Non dimenticare inoltre che puoi ereditare ed estendere le interfacce e le classi astratte e quindi ereditare da quelle classi o interfacce figlio. Ma il pattern del bridge è probabilmente una scelta migliore a causa del disaccoppiamento che offre.

Spero che questo aiuti.

    
risposta data 20.12.2014 - 13:39
fonte

Leggi altre domande sui tag