Ich lese über übliche Codegerüche in Martin Fowlers Refactoring-Buch . In diesem Zusammenhang habe ich mich über ein Muster gewundert, das ich in einer Codebasis sehe, und ob man es objektiv als Anti-Muster betrachten kann.
Das Muster ist eines, bei dem ein Objekt als Argument an eine oder mehrere Methoden übergeben wird, die alle den Zustand des Objekts ändern, von denen jedoch keine das Objekt zurückgeben. Es basiert also auf der Referenzübergabe von (in diesem Fall) C # /. NET.
var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);
Ich finde, dass (insbesondere wenn Methoden nicht entsprechend benannt sind) ich solche Methoden untersuchen muss, um zu verstehen, ob sich der Zustand des Objekts geändert hat. Dadurch wird das Codeverständnis komplexer, da ich mehrere Ebenen des Aufrufstapels nachverfolgen muss.
Ich möchte vorschlagen, einen solchen Code zu verbessern, um ein anderes (geklontes) Objekt mit dem neuen Status zurückzugeben, oder alles, was zum Ändern des Objekts am Aufrufstandort erforderlich ist.
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);
Mir scheint, dass das erste Muster anhand der Annahmen gewählt wird
- dass es weniger Arbeit ist oder weniger Codezeilen erfordert
- dass es erlaubt uns , das Objekt sowohl Veränderung, und einige andere Information zurückgeben
- dass es effizienter ist, da wir weniger Instanzen von haben
Thing
.
Ich illustriere eine Alternative, aber um sie vorzuschlagen, muss man Argumente gegen die ursprüngliche Lösung haben. Was, wenn überhaupt, kann dafür argumentiert werden, dass die ursprüngliche Lösung ein Anti-Pattern ist?
Und was stimmt mit meiner alternativen Lösung nicht?