Sto leggendo degli odori di codice comuni nel libro Refactoring di Martin Fowler . In quel contesto, mi chiedevo uno schema che sto vedendo in una base di codice e se uno potesse obiettivamente considerarlo un anti-schema.
Il modello è quello in cui un oggetto viene passato come argomento a uno o più metodi, tutti i quali cambiano lo stato dell'oggetto, ma nessuno dei quali restituisce l'oggetto. Quindi si basa sul passaggio per natura di riferimento di (in questo caso) C # /. NET.
var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);
Trovo che (specialmente quando i metodi non sono nominati in modo appropriato) ho bisogno di esaminare tali metodi per capire se lo stato dell'oggetto è cambiato. Rende la comprensione del codice più complessa, poiché devo tenere traccia di più livelli dello stack di chiamate.
Vorrei proporre di migliorare tale codice per restituire un altro oggetto (clonato) con il nuovo stato, o tutto ciò che è necessario per modificare l'oggetto nel sito di chiamata.
var something1 = new Thing();
// ...
// Let's return a new instance of Thing
var something2 = Foo(something1);
// Let's use out param to 'return' other info about the operation
int result;
var something3 = Bar(something2, out result);
// If necessary, let's capture and make explicit complex changes
var changes = Baz(something3)
something3.Apply(changes);
A me sembra che il primo modello sia stato scelto in base alle ipotesi
- che è meno lavoro o richiede meno righe di codice
- che ci consente sia di cambiare l'oggetto, sia di restituire qualche altra informazione
- che è più efficiente poiché abbiamo meno casi di
Thing
.
Illustro un'alternativa, ma per proporlo bisogna avere argomenti contro la soluzione originale. Quali eventuali argomenti possono essere fatti per sostenere che la soluzione originale è un anti-pattern?
E cosa c'è di sbagliato nella mia soluzione alternativa?