Антипаттерны

Антипаттерны (anti-patterns), также известные как ловушки (pitfalls) – это классы наиболее часто внедряемых плохих решений проблем. Они изучаются в случае, когда их хотят избежать в будущем, и некоторые отдельные случаи их могут быть распознаны при изучении неработающих систем.

Термин антипаттерн построен на основе термина pattern – шаблон проектирования. То есть, антипаттерны – это как бы противоположность шаблонам, представляющим хорошие методы программирования.

Далее будет приведён список некоторых наиболее распространённых антипаттернов, разбитый на категории. Для каждого элемента списка указывается название и короткое определение. Также для некоторых элементов будет дан своеобразный «рецепт лечения», указывающий, как устранить антипаттерн.

Антипаттерны в программировании.

– Ненужная сложность (Accidental complexity) – внесение ненужной сложности в решение. Ненужная сложность не обусловлена действительной сложностью решаемой проблемы, а искусственно внесена при разработке архитектуры и дизайна ПО.

– Действие на расстоянии (Action at a distance) – неожиданное взаимодействие между широко разделёнными частями системы. Антипаттерн может проявиться при использовании в программе глобальных переменных.

– Слепая вера (Blind faith) – недостаточная проверка корректности исправления ошибки или результата работы подпрограммы. Альтернативой антипаттерну является разработка через тестирование и, в частности, модульные тесты.

– Лодочный якорь (Boat anchor) – сохранение более не используемой части системы. Чтобы уменьшить влияние данного антипаттерна, рекомендуется устаревшие компоненты системы выносить в отдельные библиотеки, дабы не захламлять основной набор классов и методов.

– Активное ожидание (Busy spin) – потребление процессорного времени во время ожидания события, обычно при помощи постоянно повторяемой проверки, вместо того, чтобы использовать систему сообщений.

– Кэширование ошибки (Caching failure) – забывать сбросить флаг ошибки после её обработки. Согласно своему названию, антипаттерн обычно возникает в системах с кэшированием. Один из способов устранения – полная очистка кэша в случае возникновения ошибки.

– Проверка типа вместо интерфейса (Checking type instead of interface) – проверка того, что объект имеет специфический тип в то время, когда требуется только определённый интерфейс.

– Кодирование путём исключения (Coding by exception) – добавление нового кода для поддержки каждого специального распознанного случая.

– Таинственный код (Cryptic code) – использование аббревиатур вместо мнемонических имён.

– Жёсткое кодирование (Hard code) – внедрение предположений об окружении системы в слишком большом количестве точек её реализации. Примером является явная запись имени и пути к файлу в коде. Для устранения антипаттерна следует вместо явных значений использовать именованные константы или параметры из конфигурационных файлов.

– Мягкое кодирование (Soft code) – патологическая боязнь жёсткого кодирования, приводящая к тому, что настраивается всё что угодно, при этом конфигурирование системы само по себе превращается в программирование.

– Поток лавы (Lava flow) – сохранение нежелательного (излишнего или низкокачественного) кода по причине того, что его удаление слишком дорого или будет иметь непредсказуемые последствия.

– Магические числа (Magic numbers) – включение чисел в алгоритмы без объяснений. Для устранения антипаттерна следует использовать именованные константы, причём имя должно отражать смысл константы (см. антипаттерн Таинственный код).

– Процедурный код (Procedural code) – ситуация, когда другая парадигма программирования является более подходящей для решения задачи.

– Спагетти-код (Spaghetti code) – системы, чья структура редко понятна, особенно потому что структура кода используется неправильно. Антипаттерн обычно проявляется в методах большого размера (20 строк кода и более). Для устранения антипаттерна выполняют выделение фрагментов кода в отдельные функции.

– Мыльный пузырь (Soap bubble) – класс, инициализированный мусором, максимально долго притворяется, что содержит какие-то данные.

Антипаттерны в объектно-ориентированном программировании.

– Базовый класс-утилита (Base Bean) – наследование функциональности из класса-утилиты вместо делегирования к нему.

– Вызов предка (Call Super) – для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы класса-предка. Вместо данного антипаттерна следует использовать паттерн Шаблонный метод.

– Божественный объект (God object) – концентрация слишком большого количества функций в одиночной части дизайна (классе). Любой класс должен иметь единственное назначение, которое можно описать несколькими словами. Большие классы следует разбить на мелкие, возможно с применением агрегирования, делегирования и наследования.

– Объектная клоака (Object cesspool) – антипод шаблона Пул объектов. Антипаттерн возникает тогда, когда объекты, возвращаемые в пул, не приводятся в своё первоначальное состояние.

– Полтергейст (Poltergeist) – объекты, чьё единственное предназначение – передавать информацию другим объектам. Антипаттерн проявляется в виде короткоживущих объектов, лишённых состояния. Эти объекты часто используются для инициализации других, более устойчивых объектов. Устранение антипаттерна заключается в переносе функций в объекты- «долгожители».

– Проблема йо-йо (Yo-yo problem) – структура (например: наследования) которая тяжело понятна вследствие избыточной фрагментации.

– Синглетонизм (Singletonitis) – избыточное использование шаблона Одиночка.

Антипаттерны в разработке ПО.

– Большой комок грязи (Big ball of mud) – система с нераспознаваемой структурой.

– Бензиновая фабрика (Gas factory) – необязательная сложность дизайна.

– Затычка на ввод данных (Input kludge) – забывчивость в спецификации и выполнении поддержки возможного неверного ввода. Антипаттерн устраняется продуманным алгоритмом проверки (валидации) пользовательского ввода.

– Раздувание интерфейса (Interface bloat) – изготовление интерфейса очень мощным и очень трудным для осуществления. Альтернативой этому антипаттерну служит использование таких шаблонов, как Адаптер или Посетитель.

– Магическая кнопка (Magic pushbutton) – выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, в системах типа Delphi это написание прикладной логики в обработчиках нажатий на кнопку.

– Дымоход (Stovepipe system) – редко поддерживаемая сборка плохо связанных компонентов.

– Гонки (Race hazard) – ошибка в определении последовательности различных порядков событий.

Методологические антипаттерны.

– Программирование методом копирования-вставки (Copy and paste programming) – копирование (и лёгкая модификация) существующего кода вместо создания общих решений. Симптом этого антипаттерна: после внесения изменений программа в некоторых случаях ведёт себя также, как и раньше. Для устранения антипаттерна требуется выделить повторяющийся код в отдельный метод.

– Дефакторинг (De-Factoring) – процесс уничтожения функциональности и замены её документацией.

– Золотой молоток (Golden hammer) – сильная уверенность в том, что любимое решение универсально применимо. Название происходит от английской поговорки «когда в руках молоток, все проблемы кажутся гвоздями».

– Фактор невероятности (Improbability factor) – предположение о невозможности того, что сработает известная ошибка.

– Преждевременная оптимизация (Premature optimization) – оптимизация на основе недостаточной информации.

– Изобретение колеса (Reinventing the wheel) – ошибка адаптации существующего решения.

– Изобретение квадратного колеса (Reinventing the square wheel) – создание плохого решения, когда существует хорошее.


Литература

1. Влиссидес, Д. Применение шаблонов проектирования. Дополнительные штрихи. / Д. Влиссидес. – М.: Издат. дом «Вильямс», 2003. – 144 с.

2. Гамма, Э. Приёмы объектно-ориентированного проектирования. Паттерны проектирования. / Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес. – Спб.: Питер, 2013. – 368 с.: ил.

3. Мартин, Р. С. Принципы, паттерны и методики гибкой разработки на языке C#. / Р. С. Мартин, М. Мартин. – Спб.: ООО «Издательство «Символ-плюс», 2011. – 768 с.

4. Нильссон, Дж. Применение DDD и шаблонов проектирования. Проблемно-ориентированное проектирование приложений с примерами на C# и.NET. / Дж. Нильссон. – М.: Издат. дом «Вильямс», 2008. – 560 с.

5. Цвалина, К. Инфраструктура программных проектов: соглашения, идиомы и шаблоны для многократно используемых библиотек.NET. / К. Цвалина, Б. Адамс. – М.: Издат. дом «Вильямс», 2011. – 416 с.

6. Фаулер, М. Архитектура корпоративных программных приложений. / М. Фаулер. – М.: Издат. дом «Вильямс», 2011. – 544 с.

7. Фаулер, М. Рефакторинг. Улучшение существующего кода. / М. Фаулер. – Спб.: ООО «Издательство «Символ-плюс», 2013. – 432 с.


[1] Алгоритмы не рассматриваются как шаблоны, так как они решают задачи вычисления, а не проектирования.

[2] Команда авторов этой книги известна под названием «Банда четырёх» (Gang of Four – GoF).

[3] Под термином «клиент» здесь и далее подразумевается некое программное обеспечение (в частном случае – класс, компонент), использующее библиотеки кода, интерфейсы, классы.

[4] В шаблоне Декоратор, как и во многих других шаблонах, вместо общего интерфейса допустимо использование общего абстрактного класса (и наоборот).

[5] В статье https://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.html рассматривается использование типа dynamic для реализации варианта шаблона Посетитель.

[6] Шаблон Состояние часто называют динамической версией шаблона Стратегия.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: