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?