Pull to refresh

Антипаттерны проектирования: Poltergeists

Reading time 5 min
Views 35K
Original author: Alexander Shvets
«Я точно не знаю, что делает этот класс, но я уверен, что это важно!»

У паттернов проектирования — типовых решений, есть антиподы — типовые ошибки в проектировании. О паттернах проектирования написано достаточно книг, о антипаттернах — единицы. Вашему вниманию представлен вольный перевод статьи с сайта SourceMaking, описывающий один из таких антипаттернов (всего на сайте в разделе Software Development Antipatterns их представлено 14).

Наименование: Poltergeists (полтергейсты)
Другие наименования: Gypsy (цыган), Proliferation of Classes (рост количества классов), Big DoIt Controller Class
Масштаб: приложение
Рефакторинг: Ghostbusting (охота за привидениями)
Причина появления: непонимание концепций ООП, лень продумать архитектуру классов

Примечание: автор перевода ни в коем случае не претендует на звание гуру проектирования и поэтому просит не воспринимать статью с оттенком нравоучения. Главной целью статьи является более глубое понимание в сути вопроса и, возможно, выяснение, насколько описываемая ситуация жизненна.

История вопроса


Рассматриваемый антипаттерн под именем «Цыгане» был впервые представлен Майклом Акройдом (Michael Akroyd) на конференции Object World West в 1996 году. Акройд нашел поведение этого антипаттерна схожим с кочевой жизнью цыган, которые внезапно появляются и затем также внезапно исчезают. Чтобы передать в названии антипаттерна больше информации о его сути мы выбрали другое наименование: «Полтергейсты». Эти «беспокойные призраки» ведут свою — обособленную ночную жизнь. Этот термин лучше представляет концепцию «заглянуть, чтобы что-то сделать» данного антипаттерна и в то же время сохраняет метафору «вот они здесь а вот их уже нет» изначального наименования.

Среди LISP-программистов (как и среди прочих), бывают разработчики, которые получают удовольствие от максимального использования «побочных эффектов» ряда функций языка программирования для выполнения ключевых задач в их системе неявным образом. Анализ и понимание таких систем практически невозможен и любая попытка повторного использования зачастую становится бессмысленной.

Ровно как применение «побочных эффектов» является некорректным использованием языковых средств, также и появление классов-полтергейстов является результатом неправильного использования концепций проектирования.

Описание


Полтергейсты — это классы с ограниченной ответственностью и ролью в системе. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении.

Данный антипаттерн типичен в ситуациях, когда проектировщики знакомы с процессом моделирования но не имеют достаточного опыта в создании объектно-ориентированных архитектур. В их архитектуре возможно идентифицировать один или более классов-полтергейстов, которые появляются на время для инициации какого-либо действия в другом, более постоянном (с большим временем жизни) классе. Акройд называет эти классы «Цыганские вагоны». Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности. Обычно они очевидны, так как их имена часто заканчиваются на "_manager", "_controller".

Виновником появления антипаттерна «полтергейст» обычно является архитектор-новичок, который не в полной мере понимает концепции объектно-ориентированного проектирования. Классы-полтергейсты являются плохими архитектурными решениями по трем ключевым причинам:
  • они необязательны и поэтому бесполезно тратят ресурсы каждый раз, когда они «появляются»;
  • они неэффективны, потому что используют избыточные пути навигации (navigation paths);
  • они мешают правильному объектно-ориентированному проектированию, так как без необходимости загружают модель объектов.

Признаки появления и последствия антипаттерна


  • Избыточные пути навигации.
  • Временные ассоциации (прим.: здесь и далее под «ассоциацией» принимается отношение связи из UML).
  • Классы без состояния (содержащие только методы и константы).
  • Временные объекты и классы (с непродолжительным временем жизни).
  • Классы с единственным методом, который предназначен только для создания или вызова других классов посредством временной ассоциации.
  • Классы с именами методов в стиле «управления», такие как start_process_alpha.

Типичные причины


  • Отсутствие объектно-ориентированной архитектуры (архитектор не понимает объектно-ориентированной парадигмы).
  • Неправильный выбор пути решения задачи. Вразрез с популярным мнением, объектно-ориентированный подход не обязательно единственно-правильное решение для всех задач. Как гласит один плакат: «Не существует правильного способа сделать ошибку». Для рассматриваемой проблемы это значит, что если объектно-ориентированный подход не является правильным выбором, то не существует правильного пути для его реализации.
  • Предположения об архитектуре приложения на этапе анализа требований (до объектно-ориентированного анализа) могут также вести к проблемам на подобии этого антипаттерна.

Рефакторинг


Проблема полтергейстов решается удалением их из иерархии классов. Выполняемые ими «функции» должны быть замещены. Обычно это довольно просто сделать путем внесения тривиальных корректировок в архитектуру.

Ключ в решении — перенос управляющих действий полтергейста-контроллера (которые инкапсулированы нем) в классы, методы которых вызывает полтергейст.

Пример

Для более ясного понимания паттерна, рассмотрим пример на рисунке.

Мы видим, что класс Peach Canner Controller является «полтергейстом» потому что:
  • имеет избыточные пути навигации ко всем другим классам в рассматриваемой системе;
  • все его ассоциации танзитивны;
  • он не имеет состояния;
  • является временным классом, который существует только для того, чтобы вызывать другие классы посредством временных ассоциаций.

В данном примере, если мы удалим класс-полтергейст, то оставшиеся классы потеряют возможность взаимодействовать, а также не останется никакого порядка выполнения процессов. Поэтому нам необходимо разместить возможность взаимодействия в оставшейся иерархии. Заметьте, что определенные операции добавлены в каждый процесс таким образом, что каждый класс в отдельности осуществляет взаимодействие и обрабатывает результаты.

Связанные решения


«80%-е решение», обсуждаемое в антипаттерне Blob выглядит очень похожим на антипаттерн «полтергейст». Представленный класс «координатор» еще управляет всей или большей функциональностью системы и, как правило, обладает многими свойствами полтергейста.

Применимость к другим масштабам и уровням системы


Антипаттерн возникает тогда, когда разработчики проектируют также, как они реализуют систему (обычно — «by the seat of their pants»), а также может возникнуть как результат упущений в построении архитектуры системы.

Как и в случае с большинством антипаттернов проектирования, оба уровня — архитектурный и управленческий играют ключевую роль в предупреждении и последующей борьбе с ними. Появление антипаттерна зачастую признается именно с архитектурной точки зрения, и посредством эффективного управления стоит учитывать эту точку зрения сразу.

Менеджеры должны заботиться о том, чтобы объектно-ориентированные архитектуры оценивались квалифицированными архитекторами на самом раннем этапе их создания и регулярно в последующем. Это позволит избежать ошибок новичков, подобных этому антипаттерну. Лучше оплатить цену хорошей архитектуры заранее.
Tags:
Hubs:
+17
Comments 21
Comments Comments 21

Articles