Je lis des odeurs de code communes dans le livre Refactoring de Martin Fowler . Dans ce contexte, je me posais des questions sur un modèle que je vois dans une base de code, et si l'on pouvait objectivement le considérer comme un anti-modèle.
Le modèle est celui où un objet est passé en argument à une ou plusieurs méthodes, qui modifient toutes l'état de l'objet, mais aucune ne renvoie l'objet. Il s'appuie donc sur la nature pass by reference de (dans ce cas) C # /. NET.
var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);
Je trouve que (en particulier lorsque les méthodes ne sont pas nommées de manière appropriée), je dois examiner ces méthodes pour comprendre si l'état de l'objet a changé. Cela rend la compréhension du code plus complexe, car j'ai besoin de suivre plusieurs niveaux de la pile d'appels.
Je voudrais proposer d'améliorer ce code pour retourner un autre objet (cloné) avec le nouvel état, ou tout ce qui est nécessaire pour changer l'objet sur le site d'appel.
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);
Il me semble que le premier modèle est choisi sur les hypothèses
- que c'est moins de travail, ou nécessite moins de lignes de code
- qu'il nous permet à la fois de changer l'objet et de renvoyer une autre information
- qu'il est plus efficace car nous avons moins d'instances de
Thing
.
J'illustre une alternative, mais pour la proposer, il faut avoir des arguments contre la solution originale. Quels arguments, le cas échéant, peuvent être avancés pour démontrer que la solution originale est un anti-modèle?
Et qu'est-ce qui ne va pas, le cas échéant, avec ma solution alternative?