Come inserire il codice in un metodo in una classe derivata [duplicato]

0

Ho una classe base con un metodo chiamato Update :

Start Update

    Code block 1 (An If statement)

    Code block 2 (Setting a variable based on the If result)

    Code block 3 (A switch which is setting something)

End Update

L'ordine in cui viene eseguito il codice è importante in modo che non possano essere spostati.

Ho anche una classe derivata che ha bisogno di un po 'più di codice. Questo codice deve comunque essere compreso tra i blocchi di codice 1 e 2. Quindi, quando dovrei riscrivere l'intera cosa, sarebbe qualcosa del genere:

Start Update

    Code block 1 (An If statement)

    Code block 4 (An extra calculation based on the If result)

    Code block 2 (Setting a variable based on the If result)

    Code block 3 (A switch which is setting something)

End Update

Sto cercando dei modi per riutilizzare i blocchi di codice da 1 a 3 e anche inserire il blocco di codice 4.

La cosa migliore che mi è venuta in mente è un metodo chiamato Extra nella mia classe base e il metodo Update ha il seguente aspetto:

Start Update

    Code block 1 (An If statement)

    Call Extra

    Code block 2 (Setting a variable based on the If result)

    Code block 3 (A switch which is setting something)

End Update

Nella classe base il metodo Extra sarebbe vuoto poiché non ha alcun uso qui. La classe derivata avrebbe anche il metodo Extra , ma in quel metodo si chiamerebbe:

Start Extra

    Code block 4 (An extra calculation based on the If result)

End Extra
    
posta Krowi 30.01.2018 - 17:43
fonte

4 risposte

4

Ecco un approccio alternativo da prendere in considerazione.

Rendi i blocchi 1, 2 e 3 in metodi (protetti) sulla classe base. Fai in modo che la classe base 'Aggiornamento chiami questi tre metodi.

Aggiungi il blocco 4 come metodo (privato) sulla classe derivata. Rendi chiamata la classe derivata 'Aggiorna tutti e quattro i metodi nell'ordine richiesto.

Hai un po 'di contraddizione tra il principio DRY qui e il principio Open / Closed. In realtà, non dovresti hackerare nella classe base per aggiungere funzionalità a quella derivata. Ma rendere il codice pulito, mantenibile e leggibile è più importante dell'ossessione dei vari principi SOLID.

    
risposta data 30.01.2018 - 17:54
fonte
0

Comprendo che la tua domanda riguarda lo stile , non tanto le possibilità tecniche.

Dai commenti nel tuo esempio di codice, vorrei dare nomi ai tuoi blocchi (puoi sicuramente fare meglio di me, sapendo di cosa si tratta veramente):

  • FindUpdateSituation
  • SetGenericData
  • SetCaseSpecificData

Qualunque cosa tu chiami i blocchi, avrà sicuramente senso rifattarli in singoli metodi.

Ora la domanda è "dove si adattano meglio le azioni aggiuntive che abbiamo chiamato Block4?" E questo ha bisogno di analisi, dove vedo (almeno) tre possibili risultati:

Versione A:

Dopo aver riflettuto, si trova che per la propria classe base e tutte le classi derivate, l'aggiornamento è ancora un processo in 3 fasi costituito dai blocchi sopra menzionati, e che Block4 imposta solo alcuni dati generici e si adatta a quella parte. Quindi sovrascrivi il metodo SetGenericData , anticipando la nuova azione prima di chiamare l'implementazione di base.

Versione B:

Lo trovi da un punto di vista astratto, il metodo Update avrebbe sempre dovuto essere un processo in 4 fasi e avrebbe dovuto avere un blocco SetSpecialVariables , che solo (a causa dell'implementazione intelligente della tua classe base ) è successo a essere vuoto lì. Quindi introdurre la chiamata SetSpecialVariables nell'implementazione di base, aggiungere un metodo vuoto e quello appropriato nella classe derivata.

Versione C:

Si scopre che è solo una coincidenza che i metodi Update della classe base e della classe derivata abbiano alcuni elementi in comune. Quindi sovrascrivi il metodo Update nella sottoclasse, utilizzando i metodi di blocco individuale refactored se i loro nomi (non la loro implementazione) descrivono ciò di cui la sottoclasse necessita.

    
risposta data 02.02.2018 - 15:24
fonte
-1

Penso che l'approccio che hai trovato sia valido ed è vicino al modello di progettazione del metodo del modello.

puoi cercare il modello di progettazione per ulteriori informazioni e vedere se corrisponde ai tuoi requisiti

Edit per rendere chiara la risposta, diciamo che hai un alogritmo di base per una soluzione generica che consiste in alcuni passaggi:

begin Solution call step 1 call step 2 call step 3 call step 4 end solution

e la soluzione deve essere personalizzata in determinati scenari aggiungendo parti extra di codice tra le fasi conosciute. un modo per farlo è quello di fare come ha detto Simon B : 1- rendere i passaggi conosciuti protetti nella classe genitore 2- creare un metodo che contenga il codice aggiuntivo necessario nella classe figlio 2- definire un metodo di soluzione nella classe figlio e chiamare i passi noti della classe genitore e inserire la chiamata nel codice aggiuntivo nella posizione corretta.

un rischio che hai qui è che qualsiasi classe che eredita la tua classe base avrà la possibilità di modificare la tua soluzione definendo il loro metodo di soluzione e facendo quello che vuole o semplicemente cambiando l'ordine della chiamata dei passaggi.

ciò che penso che tu possa fare è definire i seguenti metodi no-op protetti nella classe base: preStep1 postStep1 preStep2 postStep2 preStep3 postStep3 preStep4 postStep4

e quindi modificare il metodo di soluzione in modo che assomigli:

begin Solution call preStep 1 call step 1 call postStep 1 call preStep 2 call step 2 call postStep 2 call preStep 3 call step 3 call postStep 3 call preStep 4 call step 4 call postStep 4 end solution

e quindi nella classe figlio, puoi modificare qualsiasi di preStep * o postStep * secondo necessità per inserire il tuo codice nella posizione corretta.

Inoltre, se vuoi assicurarti che il flusso generale della soluzione non cambi (step1 - > step2 - > step3 - > step4) allora puoi fare il metodo della soluzione nella classe genitore finale .

questo è il principio open-closed, dal momento che in futuro se si desidera definire un'altra classe figlio con un codice diverso da inserire -let si dice prima del punto 4- quindi è sufficiente estendere la classe genitore e sovrascrivere il metodo pre-passo4. quindi, hai aggiunto un nuovo codice nel mezzo della soluzione di base ma l'unica modifica è la dichiarazione della nuova classe figlia.

e credo che molti framework esistenti utilizzino questo modello di progettazione e chiamino questi metodi extra hook di LifeCycle che lo sviluppatore può utilizzare per eseguire codice extra in specifici punti del tempo nel ciclo di vita.

    
risposta data 30.01.2018 - 23:41
fonte
-2

L'impostazione del metodo della classe base con virtuale ti consentirà di eseguire l'override e di reimplementarli nella classe derivata.

    
risposta data 31.01.2018 - 03:24
fonte

Leggi altre domande sui tag