Design del componente: ottenere la coesione corretta

1

Attualmente ho un set di componenti denominato DataValues, ValueParsers, ValueFormatters e ValueValidators. Il primo definisce una classe base astratta DataValue e contiene un intero carico di implementazioni. Gli altri 3 componenti definiscono ciascuno un'interfaccia simile al loro nome (meno la "s"), e contengono anche una serie di implementazioni di questi. Questi 3 dipendono da DataValues. Non ci sono ulteriori dipendenze.

In altre parole, ogni componente attualmente contiene un'intera gerarchia ereditaria. Recentemente ho rivisto l'EP16 di Cleaners, di Robert C. Martin, in cui sottolinea che questo è uno degli errori più comuni nel design dei pacchetti. Questo mi ha fatto capire che questa cosa esatta sta succedendo per i pacchetti qui descritti.

La domanda quindi è come migliorare al meglio il design attuale del componente. Fortunatamente nessuno di questi componenti ha ancora visto la loro prima versione, quindi le cose possono ancora essere spostate e i confini possono ancora essere ridefiniti. I rilasci per questi sono però all'orizzonte, quindi è meglio che lo prenda subito.

Quello che sto pensando di fare ora è creare un nuovo componente per contenere la classe astratta e le interfacce citate per tutti questi componenti. Contiene anche le eccezioni di questi componenti e forse alcune implementazioni banali delle interfacce.

Questo nuovo componente sarebbe quindi necessario a tutti quelli attuali e a tutti quelli che ne hanno bisogno. Poi di nuovo, in questa categoria successiva, ci sarà un numero di componenti che possono semplicemente dipendere dal nuovo e liberarsi della loro attuale dipendenza da quelli molto più concreti e instabili che contengono tutte le implementazioni dell'interfaccia.

Questo è ottimo per il principio delle dipendenze stabili e ugualmente piacevole per il principio di equivalenza del rilascio di riutilizzo. Sta comunque andando male quando si tratta della chiusura comune e dei principi di riutilizzo comune. Concretamente questo significa che i componenti che hanno bisogno dell'interfaccia ValueParsers ma non si preoccupano di ValueValidators ne dipenderanno comunque come è nello stesso pacchetto. Possono quindi esserne influenzati senza una buona ragione. Poi di nuovo, considerando quanto sia astratto / stabile questo nuovo componente, non vedo davvero che questo causi molti problemi.

Sto cercando idee su come disegnare meglio i confini dei componenti e le preoccupazioni o i suggerimenti sull'alternativa che ho descritto.

    
posta Jeroen De Dauw 15.07.2013 - 02:12
fonte

1 risposta

0

Dopo aver discusso questo con i colleghi e aver ricevuto una serie di consigli da Robert C Marin in persona, ho optato per il seguente approccio soddisfacente:

Un componente detiene le interfacce per DataValues, ValueParssers, ValueValidators e ValueFormatters. Questo componente contiene anche tali eccezioni e implementazioni di queste interfacce che sono sia banali che generali.

Un secondo componente contiene le implementazioni generali ma più complesse di queste interfacce.

Rendere solo questa suddivisione elimina già la maggior parte dei problemi che abbiamo attualmente. Il primo componente è molto astratto e stabile ed è richiesto da molti altri componenti. Il secondo componente è concreto e instabile ed è necessario solo da alcuni componenti.

Ulteriori scissioni di questo secondo componente potrebbero verificarsi in un secondo momento. E non tutte le nuove classi concrete che derivano da quelle interfacce finiranno per esserlo, alcune potrebbero entrare in nuovi o altri componenti esistenti.

    
risposta data 24.07.2013 - 23:37
fonte