Антипаттерны проектирования: Poltergeists
«Я точно не знаю, что делает этот класс, но я уверен, что это важно!»
У паттернов проектирования — типовых решений, есть антиподы — типовые ошибки в проектировании. О паттернах проектирования написано достаточно книг, о антипаттернах — единицы. Вашему вниманию представлен вольный перевод статьи с сайта SourceMaking, описывающий один из таких антипаттернов (всего на сайте в разделе Software Development Antipatterns их представлено 14).
Наименование: Poltergeists (полтергейсты)
Другие наименования: Gypsy (цыган), Proliferation of Classes (рост количества классов), Big DoIt Controller Class
Масштаб: приложение
Рефакторинг: Ghostbusting (охота за привидениями)
Причина появления: непонимание концепций ООП, лень продумать архитектуру классов
Примечание: автор перевода ни в коем случае не претендует на звание гуру проектирования и поэтому просит не воспринимать статью с оттенком нравоучения. Главной целью статьи является более глубое понимание в сути вопроса и, возможно, выяснение, насколько описываемая ситуация жизненна.
Рассматриваемый антипаттерн под именем «Цыгане» был впервые представлен Майклом Акройдом (Michael Akroyd) на конференции Object World West в 1996 году. Акройд нашел поведение этого антипаттерна схожим с кочевой жизнью цыган, которые внезапно появляются и затем также внезапно исчезают. Чтобы передать в названии антипаттерна больше информации о его сути мы выбрали другое наименование: «Полтергейсты». Эти «беспокойные призраки» ведут свою — обособленную ночную жизнь. Этот термин лучше представляет концепцию «заглянуть, чтобы что-то сделать» данного антипаттерна и в то же время сохраняет метафору «вот они здесь а вот их уже нет» изначального наименования.
Среди LISP-программистов (как и среди прочих), бывают разработчики, которые получают удовольствие от максимального использования «побочных эффектов» ряда функций языка программирования для выполнения ключевых задач в их системе неявным образом. Анализ и понимание таких систем практически невозможен и любая попытка повторного использования зачастую становится бессмысленной.
Ровно как применение «побочных эффектов» является некорректным использованием языковых средств, также и появление классов-полтергейстов является результатом неправильного использования концепций проектирования.
Полтергейсты — это классы с ограниченной ответственностью и ролью в системе. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении.
Данный антипаттерн типичен в ситуациях, когда проектировщики знакомы с процессом моделирования но не имеют достаточного опыта в создании объектно-ориентированных архитектур. В их архитектуре возможно идентифицировать один или более классов-полтергейстов, которые появляются на время для инициации какого-либо действия в другом, более постоянном (с большим временем жизни) классе. Акройд называет эти классы «Цыганские вагоны». Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности. Обычно они очевидны, так как их имена часто заканчиваются на "_manager", "_controller".
Виновником появления антипаттерна «полтергейст» обычно является архитектор-новичок, который не в полной мере понимает концепции объектно-ориентированного проектирования. Классы-полтергейсты являются плохими архитектурными решениями по трем ключевым причинам:
Проблема полтергейстов решается удалением их из иерархии классов. Выполняемые ими «функции» должны быть замещены. Обычно это довольно просто сделать путем внесения тривиальных корректировок в архитектуру.
Ключ в решении — перенос управляющих действий полтергейста-контроллера (которые инкапсулированы нем) в классы, методы которых вызывает полтергейст.
Для более ясного понимания паттерна, рассмотрим пример на рисунке.
Мы видим, что класс Peach Canner Controller является «полтергейстом» потому что:
В данном примере, если мы удалим класс-полтергейст, то оставшиеся классы потеряют возможность взаимодействовать, а также не останется никакого порядка выполнения процессов. Поэтому нам необходимо разместить возможность взаимодействия в оставшейся иерархии. Заметьте, что определенные операции добавлены в каждый процесс таким образом, что каждый класс в отдельности осуществляет взаимодействие и обрабатывает результаты.
«80%-е решение», обсуждаемое в антипаттерне Blob выглядит очень похожим на антипаттерн «полтергейст». Представленный класс «координатор» еще управляет всей или большей функциональностью системы и, как правило, обладает многими свойствами полтергейста.
Антипаттерн возникает тогда, когда разработчики проектируют также, как они реализуют систему (обычно — «by the seat of their pants»), а также может возникнуть как результат упущений в построении архитектуры системы.
Как и в случае с большинством антипаттернов проектирования, оба уровня — архитектурный и управленческий играют ключевую роль в предупреждении и последующей борьбе с ними. Появление антипаттерна зачастую признается именно с архитектурной точки зрения, и посредством эффективного управления стоит учитывать эту точку зрения сразу.
Менеджеры должны заботиться о том, чтобы объектно-ориентированные архитектуры оценивались квалифицированными архитекторами на самом раннем этапе их создания и регулярно в последующем. Это позволит избежать ошибок новичков, подобных этому антипаттерну. Лучше оплатить цену хорошей архитектуры заранее.
У паттернов проектирования — типовых решений, есть антиподы — типовые ошибки в проектировании. О паттернах проектирования написано достаточно книг, о антипаттернах — единицы. Вашему вниманию представлен вольный перевод статьи с сайта 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»), а также может возникнуть как результат упущений в построении архитектуры системы.
Как и в случае с большинством антипаттернов проектирования, оба уровня — архитектурный и управленческий играют ключевую роль в предупреждении и последующей борьбе с ними. Появление антипаттерна зачастую признается именно с архитектурной точки зрения, и посредством эффективного управления стоит учитывать эту точку зрения сразу.
Менеджеры должны заботиться о том, чтобы объектно-ориентированные архитектуры оценивались квалифицированными архитекторами на самом раннем этапе их создания и регулярно в последующем. Это позволит избежать ошибок новичков, подобных этому антипаттерну. Лучше оплатить цену хорошей архитектуры заранее.