Sto leggendo degli odori di codice comuni in il libro di rifattorizzazione di Martin Fowler . In quel contesto, mi stavo chiedendo di un pattern che sto vedendo in una base di codice, e anche se uno potrebbe oggettivamente considerarlo un anti-pattern.
Il pattern è uno in cui un oggetto viene passato come argomento a uno o più metodi, i quali cambiano tutti 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 denominati 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é ho bisogno di tracciare più livelli dello stack di chiamate.
Mi piacerebbe proporre di migliorare tale codice per restituire un altro oggetto (clonato) con il nuovo stato, o tutto ciò che è necessario per cambiare l'oggetto sul 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 scelto nelle ipotesi
- che è meno lavoro o richiede meno righe di codice
- che ci consente sia di modificare l'oggetto, e restituire qualche altra informazione
- che è più efficiente poiché abbiamo meno istanze di
Thing
.
Illustro un'alternativa, ma per proporla, è necessario avere argomenti contro la soluzione originale. Quali sono le argomentazioni che possono essere fatte per dimostrare che la soluzione originale è un anti-pattern?
E cosa, se non altro, è sbagliato con la mia soluzione alternativa?