Я читаю об общих запахах кода в книге Рефакторинга Мартина Фаулера . В этом контексте мне было интересно узнать о паттерне, который я вижу в кодовой базе, и можно ли объективно рассматривать его как анти-паттерн.
Это шаблон, в котором объект передается в качестве аргумента одному или нескольким методам, каждый из которых изменяет состояние объекта, но ни один из которых не возвращает объект. Таким образом, он полагается на передачу по ссылочной природе (в данном случае) C # /. NET.
var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);
Я обнаружил, что (особенно когда методы не названы соответствующим образом) мне нужно изучить такие методы, чтобы понять, изменилось ли состояние объекта. Это усложняет понимание кода, так как мне нужно отслеживать несколько уровней стека вызовов.
Я хотел бы предложить улучшить такой код, чтобы он возвращал другой (клонированный) объект с новым состоянием или все, что необходимо для изменения объекта на сайте вызова.
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);
Мне кажется, первый шаблон выбран на предположениях
- что это меньше работы, или требует меньше строк кода
- что это позволяет нам как изменить объект, так и вернуть некоторую другую часть информации
- что это более эффективно, так как у нас меньше случаев
Thing
.
Я иллюстрирую альтернативу, но чтобы предложить ее, нужно иметь аргументы против первоначального решения. Какие, если таковые имеются, аргументы могут быть приведены, чтобы доказать, что исходное решение является анти-паттерном?
А что, если вообще что-то не так с моим альтернативным решением?