Недавно во время обзора кода я наткнулся на код, написанный новым коллегой, который содержит шаблон с запахом. Я подозреваю, что решения моего коллеги основаны на правилах, предложенных известной Книгой Чистого Кодекса (и, возможно, другими подобными книгами).
Насколько я понимаю, конструктор класса несет полную ответственность за создание допустимого объекта и что его основная задача заключается в назначении (частных) свойств объекта. Конечно, может случиться так, что значения необязательных свойств могут быть установлены методами, отличными от конструктора класса, но такие ситуации довольно редки (хотя и не обязательно ошибочны при условии, что остальная часть класса учитывает необязательность такого свойства). Это важно, потому что это позволяет гарантировать, что объект всегда находится в допустимом состоянии.
Однако в коде, с которым я столкнулся, большинство значений свойств фактически устанавливаются другими методами, чем конструктор. Значения, полученные в результате вычислений, присваиваются свойствам, которые будут использоваться внутри нескольких закрытых методов по всему классу. По-видимому, автор использует свойства класса, как если бы они были глобальными переменными, которые должны быть доступны по всему классу, вместо параметризации этих значений для функций, которые в них нуждаются. Кроме того, методы класса должны вызываться в определенном порядке, потому что класс не будет делать иначе.
Я подозреваю, что этот код был вдохновлен советом, чтобы методы были короткими (<= 5 строк кода), чтобы избежать больших списков параметров (<3 параметра), и что конструкторы не должны выполнять работу (например, выполнять какие-то вычисления) это важно для законности объекта).
Теперь, конечно, я могу привести аргументы против этого паттерна, если смогу доказать, что все виды неопределенных ошибок потенциально могут возникать, когда методы не вызываются в определенном порядке. Тем не менее, я предсказываю, что ответом на это будет добавление проверок, которые проверяют, что свойства должны быть установлены после вызова методов, которым необходимо установить эти свойства.
Тем не менее, я бы предпочел полностью изменить код, чтобы класс превратился в реальный объект, а не в серию методов, которые должны вызываться (процедурно) в определенном порядке.
Я чувствую, что код, с которым я столкнулся, пахнет. На самом деле, я считаю, что существует довольно четкое различие в том, когда сохранять значение в свойстве класса, а когда помещать его в параметр для использования другим методом - я не очень верю, что они могут быть альтернативами друг другу. , Я ищу слова для этого различия.