Iniezione delle dipendenze: cosa appartiene al costruttore?

6

Sto valutando le mie attuali pratiche PHP nel tentativo di scrivere più codice testabile. In generale, sto cercando le opinioni su quali tipi di azioni appartengono al costruttore. Devo limitare le cose all'iniezione di dipendenza? Se ho alcuni dati da compilare, dovrebbe accadere tramite una factory piuttosto che come argomenti del costruttore? (Qui, sto pensando alla mia classe User che prende un ID utente e popola i dati utente dal database durante la costruzione, che ovviamente ha bisogno di cambiare in qualche modo.)

Ho sentito dire che i metodi di "inizializzazione" sono cattivi, ma sono sicuro che dipende da cosa si sta facendo esattamente durante l'inizializzazione.

A rischio di diventare troppo specifico, porterò anche un esempio più dettagliato sulla mia domanda.

Per un progetto precedente, ho creato una classe FormField (che gestiva l'impostazione del valore del campo, la convalida e l'output come HTML) e una classe Model per contenere questi campi e fare un po 'di magia per facilitare il lavoro con i campi. FormField aveva alcune sottoclassi predefinite, ad es. FormText ( <input type="text"> ) e FormSelect ( <select> ). Il modello sarebbe sottoclasse in modo tale che una specifica implementazione (ad esempio un Widget) avesse i propri campi, come un nome e una data di produzione:

class Widget extends Model {
    public function __construct( $data = null ) {
        $this->name = new FormField('length=20&label=Name:');
        $this->manufactured = new FormDate;

        parent::__construct( $data ); // set above fields using incoming array
    }
}

Ora, questo viola alcune regole che ho letto, come "evitare new nel costruttore", ma ai miei occhi questo non sembra impossibile da testare. Queste sono proprietà dell'oggetto, non del generatore di dati della scatola nera che legge da una fonte esterna. I test unitari si sarebbero progressivamente sviluppati per qualsiasi test delle funzionalità specifiche dei widget, quindi potevo essere sicuro che i campi di base di Base funzionassero correttamente durante il test del widget.

In teoria potrei fornire al modello un FieldFactory () che potrebbe fornire oggetti di campo personalizzati, ma non credo che otterrei alcun risultato da questo approccio. Si tratta di una cattiva ipotesi?

    
posta Annika Backstrom 30.12.2010 - 23:57
fonte

1 risposta

1

Molte delle "regole" che si sentono sull'uso delle Fabbriche sono utili per rendere il codice più facilmente modificabile in futuro, non per renderlo testabile ora. Dai un'occhiata ai parametri che stai inviando al costruttore di FormField: 'length = 20 & label = Name:'.

Tale argomento ora è effettivamente 'hardcoded', & 'Sul lato client'.

Questo significa che se hai 10 altri widget, ognuno di questi 10 duplicherà quello "nuovo". Se in seguito decidi che vuoi cambiare l'etichetta da 'Nome' a qualcos'altro, o per aumentare la lunghezza a 25, devi tornare indietro e cambiare il codice in 10 punti, manchi 1 e hai un bug che potrebbe mostrare come un problema di layout strano.

Usando una fabbrica per chiamarla nuova, consente a quelle 10 chiamate a tutti di chiamare un metodo di fabbrica, e nel caso che ho appena descritto, solo il metodo factory dovrebbe cambiare.

    
risposta data 31.12.2010 - 23:21
fonte

Leggi altre domande sui tag