Di recente ho apportato alcune importanti rifattorizzazioni al mio codice. Una delle cose principali che ho cercato di fare è stata quella di dividere le mie classi in oggetti dati e oggetti worker. Questo è stato ispirato, tra le altre cose, da questa sezione di Clean Code :
ibridi
Questa confusione a volte porta a sfortunate strutture dati ibride che sono metà oggetto e metà struttura dati. Hanno funzioni che fanno cose significative e hanno anche variabili pubbliche o accessori e mutatori pubblici che, a tutti gli effetti, rendono pubbliche le variabili private, tentando altre funzioni esterne di usare quelle variabili come un programma procedurale userebbe struttura dati.
Tali ibridi rendono difficile l'aggiunta di nuove funzioni ma anche l'aggiunta di nuove strutture dati. Sono i peggiori di entrambi i mondi. Evita di crearli. Sono indicativi di un disegno confuso i cui autori non sono sicuri - o peggio, ignoranti - se hanno bisogno di protezione da funzioni o tipi.
Recentemente stavo guardando il codice di uno dei miei oggetti worker (che succede per implementare il modello visitatore ) e ho visto questo:
@Override
public void visit(MarketTrade trade) {
this.data.handleTrade(trade);
updateRun(trade);
}
private void updateRun(MarketTrade newTrade) {
if(this.data.getLastAggressor() != newTrade.getAggressor()) {
this.data.setRunLength(0);
this.data.setLastAggressor(newTrade.getAggressor());
}
this.data.setRunLength(this.data.getRunLength() + newTrade.getLots());
}
Mi sono subito detto "invidia delle funzionalità! Questa logica dovrebbe essere nella Dataclasse - in particolare nel handleTrademetodo. handleTradeE updateRundovrebbe sempre accadere insieme". Ma poi ho pensato "la classe di dati è solo una publicstruttura di dati, se comincio a farlo, allora arriverà un oggetto ibrido!"
Cosa c'è di meglio e perché? Come decidi quale fare?