Fornisce un'implementazione predefinita di fallback per le buone pratiche dei bambini?

2

Ho il seguente codice in PHP:

abstract class AlgorithmOnArray {

    public function runOn($array) {
        $this->setup(); 
        foreach ($array as $item) {
           $this->processItem();
        }
        $this->cleanup(); 
    }

    public abstract function processItem();

    public function cleanup() { }
    public function setup() { }
}

La mia domanda riguarda questa nozione che ho qui di avere metodi vuoti ma implementati per cleanup e setup . L'idea qui è che mentre normalmente li avrei come astratti, voglio anche classi che estendono la classe AlgorithmOnArray per poter eseguire il fallback su un'implementazione predefinita.

La domanda qui è se questa sia considerata una cosa ragionevole da fare o dovrei dire rigorosamente che questi metodi devono anche essere astratti per forzare gli algoritmi figli ad implementarli?

    
posta apokryfos 04.10.2017 - 14:54
fonte

1 risposta

4

Ci sono due principali ragioni per implementare funzioni nella classe base, come setup() e cleanup() .

Il primo è ridurre il codice duplicato, incluso il codice NO-OP, come qui. Se non è necessario che una sottoclasse implementa setup() o cleanup() , allora sarà comune per gli sviluppatori semplicemente inserire una copia identica delle funzioni come mostrato qui. È meglio per la classe base farlo e lasciare le sottoclassi per fare il loro lavoro. Di conseguenza, le sottoclassi saranno più facili da scrivere e più pulite. (Non è difficile trovare sottoclassi che non necessitino di queste due funzioni.)

Il secondo è quello di consentire futuri miglioramenti alla classe base. Supponiamo che tu aggiunga una funzione alla classe base che ha bisogno di un po 'di installazione e pulizia - il threading, forse. Se sto scrivendo una sottoclasse che non ha bisogno di setup() e cleanup() , allora li lascerò fuori e le nuove versioni di threading della classe base verranno eseguite, come previsto. Se io faccio ne scrivo uno, allora lo scriverò in questo modo:

class MyAlgo extends AlgorithmOnArray {
  public function setup() {
    parent::setup();
    // my setup stuff
  }
}

Quando la classe base aggiunge la funzione di threading, la mia non interromperà l'applicazione aggirando la versione base. I doc di classe dovrebbero incoraggiare questo modello poiché gli sviluppatori a volte sono pigri e ometteranno la chiamata alla classe genitore se sanno che è un no-op. Se è dichiarato abstract , loro devono ometterlo.

    
risposta data 04.10.2017 - 19:11
fonte

Leggi altre domande sui tag