Inietti classi specifiche o no

2

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?

    
posta Jeroen De Dauw 11.10.2013 - 16:30
fonte

1 risposta

2

È una buona idea inserire SQLiteFieldSqlBuilder e SQLiteIndexSqlBuilder specificatamente in SQLiteTableBuilder. Se decidi di consentire implementazioni alternative (ad es. Per il mocking), puoi più facilmente ridefinire SQLiteIndexSqlBuilder e SQLiteFieldSqlBuilder nelle interfacce quando necessario.

L'inserimento delle implementazioni FieldSqlBuilder e IndexSqlBuilder in un SQLiteTableBuilder non è una buona idea, poiché non rappresenta correttamente le sue dipendenze. La situazione in cui si inietterebbero implementazioni di interfacce generali come FieldSqlBuilder e IndexSqlBuilder sarebbe per una classe generale TableSqlBuilder che funziona per entrambi i builder di campi / indici SQLite e MySQL . Questo è un approccio perfettamente valido e raccomandabile, a condizione che la logica all'interno di TableSqlBuilder possa essere generalizzata per entrambi i casi.

    
risposta data 11.10.2013 - 17:19
fonte