Ho un'interfaccia TableSqlBuilder che ha un metodo getCreateTableSql. Questa interfaccia è utilizzata in qualche altra classe come segue:
function createTable( $tableDefinition ) {
$sql = $this->tableSqlBuilder->getCreateTableSql( $tableDefinition );
$this->db->execute( $sql );
}
L'interfaccia TableSqlBuilder ha implementazioni multiple, come SQLiteTableSqlBuilder e MySQLTableSqlBuilder.
SQLiteTableSqlBuilder ha originariamente creato tutto lo stesso SQL e ha avuto metodi per creare SQL per un indice o per un campo. Ha scoperto che la funzionalità di questi metodi era necessaria da sola in altri punti, quindi è stata suddivisa in SQLiteFieldSqlBuilder e SQLiteIndexSqlBuilder. Queste classi sono istanziate da SQLiteTableSqlBuilder - non vengono quindi iniettate, e SQLiteTableSqlBuilder dipende da queste classi concrete.
Non sono sicuro se questo debba essere modificato per fare in modo che questi builder di SQL e di campo vengano iniettati. Da un lato questo dà più flessibilità. Permette anche di deridere questo comportamento nei test. Inoltre, l'associazione e la flessibilità sono attualmente le stesse di prima che il codice venisse suddiviso in nuove classi.
Se si utilizza l'approccio di iniezione, i tipi accettati potrebbero essere FieldSqlBuilder e IndexSqlBuilder, entrambe le interfacce implementate dalle attuali classi concrete. Ciò significa tuttavia che si può tranquillamente finire con MySqlIndexBuilder in un SQLiteTableBuilder, che è chiaramente da evitare. Potrebbe anche solo digitare un suggerimento contro la classe concreta, fingendo che si tratti di un'interfaccia, che elimina la dipendenza a patto che la costruzione avvenga al di fuori della tabella sql builder.
Pensi che questi collaboratori dovrebbero essere iniettati, o è un'eccezione valida dove è meglio non andare fino in fondo?