Le classi figlio cambiano solo alcune "opzioni": qual è l'approccio migliore?

0

Attualmente sto implementando funzionalità in Symfony (PHP - non che dovrebbe fare alcuna differenza quale lingua sto usando) dove ho circa quattro controller che fanno quasi esattamente la stessa cosa. L'unica differenza tra loro è che usano oggetti entità e oggetti modulo diversi.

Ho già rifattorizzato tutte le funzionalità comuni in una classe genitore astratta. Poi ho due metodi astratti chiamati getEntityInstance e getFormInstance , che restituiscono solo le istanze oggetto appropriate.

Le istanze entità e modulo restituite avrebbero entrambe interfacce comuni, chiamate rispettivamente AbstractQuery e AbstractForm .

Ad esempio, diciamo che ho le seguenti due classi.

abstract class AbstractQueryController {
    abstract protected function getEntityInstance();

    abstract protected function getFormInstance(AbstractQuery $query);

    public function queryAction(Request $request) {
        //Do some stuff
        $form = $this->getFormInstance($this->getEntityInstance());
        //Do something with $form
    }
}

class SomeRandomController extends AbstractQueryController() {
    protected function getEntityInstance() {
        return new SomeRandomQuery();
    } 

    protected function getFormInstance(AbstractQuery $query) {
        return new SomeRandomForm($query);
    }
}

Ora questo approccio funziona, ma sembra sbagliato. Quale modello di progettazione o altro concetto dovrebbe essere applicato qui per rendere il codice "più pulito"? Il problema è che, con ogni nuovo controller che estende AbstractQueryController , sto fondamentalmente facendo cuocere la "configurazione" (se è possibile chiamarla così) nella classe figlio, che sembra non corretta.

    
posta iLikeBreakfast 25.10.2015 - 11:55
fonte

1 risposta

1

Dipende da cosa vuoi fare esattamente, il che è un po 'poco chiaro dal tuo esempio.

Tuttavia ci sono alcuni problemi con il tuo design, come il fatto che Controller è direttamente responsabile della creazione degli oggetti necessari. Questo porta ad un accoppiamento molto stretto, molto difficile da testare il codice e altri problemi.

Vorrei iniziare a ridefinire il tuo esempio spostando la creazione di Query e Form istanze nelle fabbriche e poi iniettare queste fabbriche nel tuo controller.

Puoi avere diverse fabbriche, ognuna delle quali produce un'istanza diversa di Query e Form classi (nota che queste classi dovrebbero implementare l'interfaccia comune, QueryInterface e / o FormInterface ) e creare un contenitore IoC che essere responsabile di inserire la fabbrica corretta nel controller (o metodo concreto) in base all'input dell'utente, che si tratti di analisi dell'URL o di altro.

Se la logica corrente per sospendere il risultato del metodo getFormInstance è sempre la stessa, implementando correttamente le fabbriche e il contenitore IoC come modello strategico, si potrebbe avere un solo controller che gestisce tutte le richieste e non bisogno di avere più di loro.

Il tipo di ritorno di getFormInstance sarebbe quindi un'interfaccia che%% specifico diForm implementerebbe e utilizzando l'interfaccia invece di classi specifiche ti garantirebbe il comportamento dalla definizione dell'interfaccia.

    
risposta data 25.10.2015 - 12:15
fonte

Leggi altre domande sui tag