Информационные списки

Антипаттерн

Материал из Википедии — свободной энциклопедии
Это старая версия этой страницы, сохранённая Mercury (обсуждение | вклад) в 17:49, 5 декабря 2019 (Организационные антипаттерны). Она может серьёзно отличаться от текущей версии.
Перейти к навигации Перейти к поиску

Антипаттерн (англ. anti-pattern) — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным[1]. В отличие от шаблона проектирования, рассмотрение антипаттерна включает в себя как неправильное решение проблемы с его признаками и последствиями, так и выход из ситуации[2].

Термин происходит из информатики, из книги «Банды четырёх» «Шаблоны проектирования», которая заложила примеры практики хорошего программирования. Авторы назвали эти хорошие методы «паттернами», и противоположными им являются «антипаттерны». Частью хорошей практикой программирования является избегание антипаттернов. До появления термина все проблемы назывались ловушки (pitfalls). Таким образом, антипаттерны — это самые распространённые ловушки, но не все ловушки будут антипаттернами.

Антипаттерны концептуально похожи на паттерны в том, что они документируют повторяющиеся решения общих проблем. Они известны как антипаттерны, потому что их использование (или злоупотребления) даёт негативные последствия[3].

Концепция также прекрасно подходит к машиностроению. Несмотря на то, что термин нечасто используется вне программной инженерии, концепция является универсальной.

Антипаттерн и паттерн ошибки

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

В отличие от паттернов ошибок, антипаттерны относятся к уровню проектирования, а не кодирования.

Антипаттерны являются паттернами проектирования, паттерны ошибок представляют собой паттерны некорректного поведения программ, коррелирующего с ошибками программирования[4].

История

С развитием ИТ-индустрии масштабы программных проектов и затраты ресурсов на них стремительно росли, что порождало большое количество проблем, что вставали перед программистами. Большинство этих проблем были типичными и встречались практически в каждом крупном проекте. В начале 90-х годов приобрели значительную популярность каталоги шаблонов проектирования (англ. design patterns) — элегантных и проверенных на практике способов решения типичных проблем. Паттерны и на сегодняшний день являются мощными и чрезвычайно популярны, однако многие разработчики, используя популярные паттерны в ситуациях, к которым они не приспособлены, делали программы крайне неэффективными, порождали гораздо больше проблем, чем было в проекте перед использованием паттерна. Кроме того, у ИТ-инженеров, как и у работников любой сферы деятельности, можно выделить типичные ошибки, обусловленные недостаточной базой знаний или отсутствием опыта у программиста, сжатыми сроками сдачи проекта, финансовыми ограничениями и прочим.

Впервые термин «Антипаттерн» в смысле формальной модели типичного неудачного решения используется в 1996 году Майклом Эйкройдом (англ. Michael Akroyd) на конференции «Object World West Conference», посвященной аспектам объектно-ориентированного программирования.[5] В своей презентации «Антипаттерны: предотвращение неправильного использования объектов» Эйкройд обращал внимание на вредные, но частые программные конструкции, в частности, те, что противоречат принципам ООП. К тому же, для каждой такой конструкции он предлагал эффективную замену.

Термин (в смысле: «плохая идея») встречался и до Эйкройда, но не публиковался и особой популярностью не пользовался. И все же приписывать авторство одному человеку не стоит. Как считает Уильям Браун, автор книги «Антипаттерны: рефакторинг приложений, архитектур и проектов», антипаттерн — это этап эволюции понятия паттерна проектирования, расширения их модели.

Классификация

Уильям Браун выделяет антипаттерны с трёх точек зрения: разработчика, архитектора и менеджера:

  • Антипаттерны разработки (development antipatterns)
  • Архитектурные антипаттерны (architectural antipatterns)
  • Организационные антипаттерны (managerial antipatterns)

Нейл и Лаплантэ приводят четвёртый тип[6][7]:

  • Антипаттерны среды (environmental antipatterns)

Кроме того, антипаттерны были описаны для отдельных информационных технологий, таких как[7]:

Антипаттерны разработки

Технические проблемы и решения, с которыми имеют дело программисты[7]:

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

  • Базовый класс-утилита (BaseBean[13]): Наследование функциональности из класса-утилиты вместо делегирования к нему.
  • Anemic Domain Model[англ.][13] — боязнь размещать логику в объектах предметной области.
  • Вызов предка[англ.] (Call super): Для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы класса-предка.
  • Ошибка пустого подкласса (Empty subclass failure): Создание класса (в Perl), который не проходит «проверку пустоты подкласса» («Empty Subclass Test») из-за различного поведения по сравнению с классом, который наследуется от него без изменений.
  • Божественный объект (God object): Концентрация слишком большого количества функций в одной части системы (классе).
  • Объектная клоака (Object cesspool): Переиспользование объектов, находящихся в непригодном для переиспользования состоянии.
  • Полтергейст[англ.] (Poltergeist[14]): Объекты, чьё единственное предназначение — передавать информацию другим объектам.
  • Проблема йо-йо[англ.] (Yo-yo problem): Чрезмерная размытость сильно связанного кода (например, выполняемого по порядку) по иерархии классов.
  • Одиночество (Singletonitis): Неуместное использование паттерна одиночка.
  • Френд-зона (Friend zone): Неуместное использование дружественных классов и дружественных функций в языке C++.
  • Каша из интерфейсов (Interface soup[15]): Объединение нескольких интерфейсов, разделенных согласно принципу изоляции интерфейсов (Interface segregation), в один.
  • Висящие концы: Интерфейс, большинство методов которого бессмысленны и реализуются «пустышками».
  • Заглушка (Stub): Попытка «натянуть» на объект уже имеющийся малоподходящий по смыслу интерфейс, вместо создания нового.

Антипаттерны в кодировании

  • Ненужная сложность[англ.] (Accidental complexity): Внесение ненужной сложности в решение.
  • Действие на расстоянии[англ.] (Action at a distance): Неожиданное взаимодействие между широко разделёнными частями системы.
  • Накопить и запустить (Accumulate and fire): Установка параметров подпрограмм в наборе глобальных переменных.
  • Слепая вера[англ.] (Blind faith): Недостаточная проверка корректности исправления ошибки или результата работы подпрограммы.
  • Лодочный якорь[англ.] (Boat anchor)[14]: Сохранение более не используемой части системы.
  • Активное ожидание[англ.] (Busy spin, busy waiting): Потребление ресурсов ЦПУ (процессорного времени) во время ожидания события, обычно при помощи постоянно повторяемой проверки, вместо того, чтобы использовать асинхронное программирование (к примеру, систему сообщений или событий).
  • Кэширование ошибки[англ.] (Caching failure): Забывать сбросить флаг ошибки после её обработки.
  • Воняющий подгузник (The Diaper Pattern Stinks): Сброс флага ошибки без её обработки или передачи вышестоящему обработчику.
  • Проверка типа вместо интерфейса (Checking type instead of membership, Checking type instead of interface): Проверка того, что объект имеет специфический тип в то время, когда требуется только определённый интерфейс.
  • Инерция кода (Code momentum): Сверхограничение части системы путём постоянного подразумевания её поведения в других частях системы.
  • Кодирование путём исключения[англ.] (Coding by exception): Добавление нового кода для поддержки каждого специального распознанного случая.
  • Таинственный код (Cryptic code): Использование аббревиатур вместо мнемоничных имён.
  • Жёсткое кодирование (Hard code): Внедрение предположений об окружении системы в слишком большом количестве точек её реализации.
  • Мягкое кодирование (Soft code): Патологическая боязнь жёсткого кодирования, приводящая к тому, что настраивается всё что угодно, при этом конфигурирование системы само по себе превращается в программирование.
  • Поток лавы[англ.] (Lava flow)[14]: Сохранение нежелательного (излишнего или низкокачественного) кода по причине того, что его удаление слишком дорого или будет иметь непредсказуемые последствия.
  • Волшебные числа (Magic numbers): Использование числовых констант без объяснения их смысла.
  • Процедурный код (Procedural code): Когда другая парадигма является более подходящей.
  • Спагетти-код (Spaghetti code, иногда «макароны»)[14]: Код с чрезмерно запутанным порядком выполнения.
  • Лазанья-код[англ.] (Lasagnia code, или «лук» (onion)): Использование неоправданно большого количества уровней абстракции.
  • Равиоли-код (Ravioli code, или «пельмени»): Объекты настолько «склеены» между собой, что практически не допускают рефакторинга.
  • Мыльный пузырь (Soap bubble): Объект, инициализированый мусором, максимально долго притворяется, что содержит какие-то данные.
  • Мьютексный ад (Mutex hell): Внедрение слишком большого количества объектов синхронизации между потоками.
  • (Мета-)шаблонный рак (Template cancer): Повсеместное использование шаблонов (в основном C++), в том числе там, где их использование не оправдано. Это уменьшает понимание и сопровождение кода и замедляет компиляцию.

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

  • Паттерн проектирования: само по себе использование паттернов считается анти-паттерном — знаком того, что система не воплощает достаточный уровень абстракции[16].
  • Программирование методом копирования-вставки (Copy and paste programming)[14]: Копирование (и лёгкая модификация) существующего кода вместо создания общих решений.
  • Дефакторинг (De-Factoring): Процесс уничтожения функциональности и замены её документацией.
  • Золотой молоток (Golden hammer[14]): Сильная уверенность в том, что любимое решение универсально применимо. Название происходит от поговорки «когда в руках молоток, все проблемы кажутся гвоздями».
  • Фактор невероятности[англ.] (Improbability factor): Предположение о невозможности того, что сработает известная ошибка.
  • Преждевременная оптимизация (Premature optimization): Оптимизация на основе недостаточной информации.
  • Программирование методом подбора (Programming by permutation): Подход к разработке программного обеспечения небольшими изменениями.
  • Изобретение колеса/велосипеда (Reinventing the wheel[14]): Создание с нуля, вместо использования готового решения.
  • Изобретение квадратного колеса (Reinventing the square wheel): Создание плохого решения, когда существует хорошее известное решение.
  • Самоуничтожение (Self-destruction): Фатальная ошибка либо нестандартное поведение программы, приводящая к отказу в обслуживании, возникшая вследствие другой менее серьёзной ошибки. Например, при возникновении ошибки, приложение начинает очень быстро и много писать в лог, вследствие чего заканчивается место на жёстком диске быстрее, чем это обнаружит мониторинг.
  • Два тоннеля: Вынесение новой функциональности в отдельное приложение вместо расширения уже имеющегося. Чаще всего применяется, когда по каким-либо причинам (в основном, при нехватке времени либо нежелании менеджмента) внесение изменений в уже имеющийся код требует больших затрат, чем создание нового. При этом у клиента в конечном итоге работают два приложения, запускаясь одновременно либо попеременно друг из друга.
  • Коммит-убийца (Commit assasin): Внесение отдельных изменений в систему контроля версий без проверки влияния их на другие части программы. Как правило, после подобных коммитов работа коллектива парализуется на время исправления проблем в местах, которые ранее работали безошибочно.

Антипаттерны управления конфигурацией

  • Ад зависимостей (Dependency hell, на платформе Microsoft Windows также называется «DLL hell», «DLL-ад»): Разрастание графа взаимных зависимостей программных продуктов и библиотек, приводящее к сложности установки новых и удаления старых продуктов. В сложных случаях различные установленные программные продукты требуют наличия разных версий одной и той же библиотеки. В наиболее сложных случаях один продукт может косвенно потребовать сразу две версии одной и той же библиотеки.

Разные

  • Дым и зеркала (Smoke and mirrors[14]): Демонстрация того, как будут выглядеть ненаписанные функции (название происходит от двух излюбленных способов, которыми фокусники скрывают свои секреты).
  • Раздувание ПО (Software bloat): Разрешение последующим версиям системы требовать всё больше и больше ресурсов.
  • Функции для галочки: Превращение программы в конгломерат плохо реализованных и не связанных между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть).

Архитектурные антипаттерны

Типичные проблемы, связанные со структурой системы[7]:

  • Инверсия абстракции (Abstraction inversion): Сокрытие части функциональности от внешнего использования, в надежде на то, что никто не будет его использовать
  • Неопределённая точка зрения (Ambiguous viewpoint[14]): Представление модели без спецификации её точки рассмотрения.
  • Большой комок грязи (Big ball of mud): Система с нераспознаваемой структурой.
  • Блоб (Blob[14]): см. Божественный объект (God object).
  • Бензиновая фабрика (Gas factory): Необязательная сложность дизайна.
  • Затычка на ввод данных (Input kludge[14]): Забывчивость в спецификации и выполнении поддержки возможного неверного ввода.
  • Раздувание интерфейса (Interface bloat): Разработка интерфейса очень мощным и очень сложным для реализации.
  • Волшебная кнопка (Magic pushbutton): Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, в системах типа Delphi это написание прикладной логики в обработчиках нажатий на кнопку.
  • Перестыковка (Re-Coupling): Процесс внедрения ненужной зависимости.
  • Дымоход (Stovepipe System[14]): Редко поддерживаемая сборка плохо связанных компонентов.
  • Состояние гонки (Race hazard, Race condition): непредвидение возможности наступления событий в порядке, отличном от ожидаемого.
  • Мышиная возня[источник не указан 4236 дней]: Неоправданное создание множества мелких и абстрактных классов для решения одной конкретной задачи более высокого уровня.
  • Членовредительство (Mutilation): Излишнее «затачивание» объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.
  • Сохранение или смерть (Save or die): Сохранение изменений в конфигурации на жесткий диск лишь при завершении приложения; приводит к тому, что в случае отказа в программе эти данные будут утеряны

Организационные антипаттерны

Проблемы, с которыми встречаются менеджеры (или группы менеджеров)[7]:

Нейл и Лапланте приводят следующие антипаттерны[6]:

  • Заочный менеджер (Absentee Manager): любой менеджер, который занимается уклончивым поведением или невидим в течение длительного времени - либо прячется в помещении, либо вдали от офиса;
  • Иметь только молоток (All You Have Is A Hammer): однонаправленное управление, где одни и те же приемы используются на всех подчиненных и во всех ситуациях. Иногда также известный как «One-Trick Pony»;
  • Дикий менеджер (Cage Match Negotiator): любой менеджер, который упрям не по разуму и использует подход к управлению «Победа любой ценой» или «Я прав, а вы нет». У них часто есть кофейная кружка с «Правилами управления» - «Правило №1: Босс всегда прав. Правило №2: Если босс не прав, см. Правило №1»;
  • Доппельгангер (Doppelganger): менеджер или коллега, с которым легко работать в один момент, а в другой он может быть неразумным;
  • Бесплодные прыжки (Fruitless Hoops): вы совершаете бесплодные прыжки, когда менеджеры продолжают запрашивать бесконечные данные у вас, прежде чем принять решение. Каждый раз, когда вы их предоставляете, они хотят больше, и вы не знаете, почему;
  • Золотой ребёнок (Golden Child): «Золотой ребенок» существует в ситуациях, когда менеджер или человек, занимающий руководящую должность, предоставляет особую ответственность, возможность, признание или вознаграждение члену своей команды на основе личных взаимоотношений с человеком и вопреки его действительным действиям. Пока всех раздражает «Золотое дитя», настоящая проблема заключается в менеджере;
  • Безглавая курица (Headless Chicken): менеджер без фокуса и плана, который никогда ничего не заканчивает;
  • Лидер не менеджер (Leader Not Manager): менеджер, а не лидер подчеркивает важность эффективного руководства со стороны руководителей, менеджеров и руководителей;
  • Менеджер попугай (Managerial Cloning): менеджеры среднего звена имеющие тенденцию со временем вести себя как их начальники;
  • Менеджер не лидер (Manager Not Leader): менеджер, хорошо владеющий административными и управленческими обязанностями, но не обладающий лидерскими способностями;
  • Злоупотребление метриками (Metric Abuse): неправильное использование метрик, либо из-за некомпетентности, либо из-за умышленного манипулирования;
  • Классный чувак (Mr. Nice Guy): менеджер, который сосредотачивается на том, чтобы быть другом каждого, в конечном итоге разочаровывает всех и не справляется со своими обязанностями;
  • Управление грибами (Mushroom Management): ситуация, в которой руководство не может эффективно общаться с персоналом. По сути, информация намеренно скрывается, чтобы все были «Толстыми, глупыми и счастливыми». Название связано с аналогией: шампиньоны выращивают в темноте и в навозе;
  • Полирование тарелок (Plate Spinning): менеджер скрывает свою неэффективность заставляя работников заниматься трудоёмкой и бесполезной работой;
  • Герой пролетариата (Proletariat Hero): каждый человек считается идеалом, когда на самом деле он - опора, используемая для маскировки несоответствий управления. Форма трудовой дисциплины как средство «мотивации» персонала, которое дает повод руководству повысить ожидания производства ... получить больше с меньшими затратами;
  • Звёздный выскочка (Rising Upstart): суперзвезды, которые не могут ждать своего времени необходимого для обучения и поиска своего места. Иногда это может быть из-за невежества, они не знают, чего не знают, а иногда из-за нетерпения, они знают то, чего не знают другие. Такой выскочка представляет настоящий вызов для всех, кроме самых опытных менеджеров;
  • Дорога в никуда (Road to Nowhere): Отсутствие плана вызывает замешательство и кризис руководства;
  • Безхребетный руководитель (Spineless Executive): любой менеджер, который не имеет смелости вступить в необходимую конфронтацию или справиться со сложной ситуацией. Вместо этого он полностью избегает конфронтации или ситуации или просит вас сообщить ему плохие новости;
  • Трёхглавый рыцарь (Three-Headed Knight): нерешительный менеджер;
  • Абсолютный инструмент (Ultimate Weapon): их коллеги или организация могут положиться на выдающихся сотрудников настолько, что они станут проводником всего;
  • Тёплое тело (Warm Bodies): управленческая ситуация, в которой работник, который едва соответствует минимальным ожиданиям работы и, таким образом, перемещается от проекта к проекту или от команды к команде. Дефектный человек называется «Теплым телом», хотя настоящая проблема заключается в менеджере. Этот антипаттерн является противоположностью «Звёздного выскочки» в отношении навыков и потенциала.

Антипаттерны обстановки

Проблемы, вызванные доминирующей в организации структурой и социальной моделью, являющейся результатом действующей в организации общественной политики[17][7][6][18]:

См. также

Примечания

  1. Budgen, D. Software design. — Addison-Wesley, 2003. — ISBN 0-201-72219-4.
  2. Brown, 1998, Chapter 2.
  3. Smith C. U., 2000.
  4. 1 2 Аллен Э., 2003, с. 65—66.
  5. http://c2.com/cgi/wiki?AntiPattern. Cunningham & Cunningham, Inc..
  6. 1 2 3 Neill, Laplante, 2005.
  7. 1 2 3 4 5 6 Settas, 2011.
  8. Miroslav Kis. Information security antipatterns in software requirements engineering. In Proceedings of the 9th Conference on Pattern Language of Programs (Plop), 2002.
  9. John Long. Software reuse antipatterns. In ACM SIGSOFT Software Engineering Notes, volume26, page 4, July 2001.
  10. Paula Kotze, Karen Renaud, and Judy van Biljona. Don’t do this — pitfalls in using anti-patterns in teaching human-computer interaction principles. Computers and Education, 50(3):979-1008, April 2008
  11. J. Krai and M. Zemlicka. The most important service-oriented antipatterns. In proceedings of the International Conference on Software Engineering Advances (ICSEA), 2007.
  12. P.A. Laplante, R.R. Hoffman, and G. Klein. Antipatterns in the creation of intelligent systems. IEEE Intelligent Systems, 22:91-95, 2007.
  13. 1 2 Rajiv Ramnath, Cheyney Loffing. Beginning IOS Programming For Dummies. — John Wiley & Sons, 2014-04-14. — С. 105. — 470 с. — ISBN 9781118799277.
  14. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 William J. Brown. AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis. — Wiley, 1998-04-03. — 156 с. — ISBN 0−471−19713−0.
  15. Gary McLean Hall. Adaptive Code via C#: Agile coding with design patterns and SOLID principles. — Microsoft Press, 2014. — С. 267-268. — ISBN 978-0735683204.
  16. Revenge of the Nerds. — «In the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.»
  17. В оригинале: socio-political forces
  18. Phillip Laplante The Burning Bag of Dung—and Other Environmental Antipatterns ACM Queue November 30, 2004 Volume 2, issue 7

Литература

Ссылки