Estou lendo sobre cheiros de códigos comuns no livro de Refatoração de Martin Fowler . Nesse contexto, eu estava pensando em um padrão que estou vendo em uma base de código, e se alguém poderia objetivamente considerá-lo um anti-padrão.
O padrão é aquele em que um objeto é passado como argumento para um ou mais métodos, todos os quais alteram o estado do objeto, mas nenhum deles retorna o objeto. Portanto, ele conta com o passe por natureza de referência (neste caso) C # / .NET.
var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);
Descobri que (especialmente quando os métodos não são nomeados adequadamente), preciso investigar esses métodos para entender se o estado do objeto foi alterado. Isso torna a compreensão do código mais complexa, pois preciso rastrear vários níveis da pilha de chamadas.
Eu gostaria de propor a melhoria desse código para retornar outro objeto (clonado) com o novo estado ou qualquer coisa necessária para alterar o objeto no site de chamada.
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);
Para mim, parece que o primeiro padrão é escolhido nas suposições
- que é menos trabalhoso ou requer menos linhas de código
- que nos permite mudar o objeto e retornar alguma outra informação
- que é mais eficiente, pois temos menos instâncias de
Thing
.
Ilustro uma alternativa, mas para propor, é preciso ter argumentos contra a solução original. Quais argumentos, se houver, podem ser apresentados para afirmar que a solução original é um antipadrão?
E o que há de errado com minha solução alternativa?