Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПИАПС / knigaVAPO_v2.doc
Скачиваний:
357
Добавлен:
17.04.2018
Размер:
35.96 Mб
Скачать

5.12. Антипаттерны (anti-patterns)

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

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

Частью хорошей практики программированиясчитается программирование без антипаттернов. У программистов, как и у работников любой сферы деятельности, можно выделить типичные ошибки, обусловленные недостаточной базой знаний или отсутствием опыта, сжатыми сроками сдачи проекта, финансовыми ограничениями и прочим [20].

Некоторые различаемые антипаттерны в программировании

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

  • Дым и зеркала (Smoke and mirrors): Демонстрация того, как будут выглядеть ненаписанные функции (название происходит от двух излюбленных способов, которыми фокусники скрывают свои секреты)

  • Раздувание ПО(Software bloat): Разрешение последующим версиям системы требовать всё больше и больше ресурсов

  • Функции для галочки: Превращение программы в конгломерат плохо реализованных и не связанных между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть)

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

  • Инверсия абстракции (Abstraction inversion): Сокрытие части функциональности от внешнего использования, в надежде на то, что никто не будет его использовать

  • Неопределённая точка зрения (Ambiguous viewpoint): Представление модели без спецификации её точки рассмотрения

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

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

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

  • Раздувание интерфейса (Interface bloat): Разработка интерфейса очень мощным и очень сложным для реализации

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

  • Перестыковка (Re-Coupling): Процесс внедрения ненужной зависимости

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

  • Состояние гонки (Race hazard, Race condition): непредвидение возможности наступления событий в порядке, отличном от ожидаемого

  • Мышиная возня: Неоправданное создание множества мелких и абстракных классов для решения одной конкретной задачи более высокого уровня

  • Висящие концы: Интерфейс, большинство методов которого бессмысленны и реализуются "пустышками"

  • Золушкина туфелька: Попытка "натянуть" на объект уже имеющийся малоподходящий по смыслу интерфейс, вместо создания нового.

  • Членовредительство (Mutilation): Излишнее "затачивание" объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.

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

  • Базовый класс-утилита (BaseBean): Наследование функциональности из класса-утилиты вместо делегирования к нему

  • Вызов предка (CallSuper): Для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы класса-предка

  • Ошибка пустого подкласса (Empty subclass failure): Создание класса (в Perl), который не проходит «проверку пустоты подкласса» («Empty Subclass Test») из-за различного поведения по сравнению с классом, который наследуется от него без изменений

  • Божественный объект (God object): Концентрация слишком большого количества функций в одной части системы (классе)

  • Объектная клоака (Object cesspool): Переиспользование объектов, находящихся в непригодном для переиспользования состоянии

  • Полтергейст (Poltergeist): Объекты, чьё единственное предназначение — передавать информацию другим объектам

  • Проблема йо-йо (Yo-yo problem): Чрезмерная размытость сильно связанного кода (например, выполняемого по порядку) по иерархии классов

  • Одиночество (Singletonitis): Неуместное использование паттерна одиночка

  • Приватизация (Privatisation): Сокрытие функциональности в приватной секции (private), что затрудняет его расширение в классах-потомках

  • Френд-зона (Friend zone): Неуместное использование дружественных классов и дружественных функций в языке с++

  • Каша из интерфейсов (Interface soup): Объединение нескольких интерфейсов, разделенных согласно принципу изоляции интерфейсов (Interface segregation), в один.

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

  • Ненужная сложность (Accidental complexity): Внесение ненужной сложности в решение

  • Действие на расстоянии (Action at a distance): Неожиданное взаимодействие между широко разделёнными частями системы

  • Накопить и запустить (Accumulate and fire): Установка параметров подпрограмм в наборе глобальных переменных

  • Слепая вера (Blind faith): Недостаточная проверка корректности исправления ошибки или результата работы подпрограммы

  • Лодочный якорь (Boat anchor): Сохранение более не используемой части системы

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

  • Кэширование ошибки (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): Сохранение нежелательного (излишнего или низкокачественного) кода по причине того, что его удаление слишком дорого или будет иметь непредсказуемые последствия

  • Волшебные числа (Magic numbers): Включение в алгоритмы чисел без объяснений их смысла

  • Процедурный код (Procedural code): Когда другая парадигма является более подходящей

  • Спагетти-код (Spaghetti code, иногда «макароны»): Код с чрезмерно запутанным порядком выполнения

  • Лазанья-код (Lasagnia code, или "лук" (onion)): Использование неоправданно большого количества уровней абстракции

  • Равиоли-код (Ravioli code, или "пельмени"): Объекты настолько "склеены" между собой, что практически не допускают рефакторинга

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

  • Мютексный ад (Mutex hell): Внедрение слишком большого количества объектов синхронизации между потоками

  • Сохранение или смерть (Save or die): Сохранение изменений конфигурации на жесткий диск лишь при завершении приложения; приводит к тому, что в случае отказа в программе эти данные будут утеряны

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

  • Программирование методом копирования-вставки (Copy and paste programming): Копирование (и лёгкая модификация) существующего кода вместо создания общих решений

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

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

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

  • Изобретение колеса/велосипеда (Reinventing the wheel): Создание с нуля, вместо использования готового решения

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

  • Самоуничтожение (Self-destruction): Фатальная ошибка либо нестандартное поведение программы, приводящая к отказу в обслуживании, возникшая вследствие другой менее серьёзной ошибки. Например, при возникновении ошибки, приложение начинает очень быстро и много писать в лог, вследствие чего заканчивается место на жёстком диске быстрее, чем это обнаружит мониторинг.

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

  • Коммит-убийца (Commit assasin): Внесение отдельных изменений в систему контроля версий без проверки влияния их на другие части системы. Как правило, после подобных коммитов работа коллектива парализуется на время исправления проблем в местах, которые ранее работали безошибочно.

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

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

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

  • Аналитический паралич (Analysis paralysis): неоправданно большие затраты на анализ и проектирование. Часто приводит к закрытию проекта до начала его реализации;

  • Дойная корова (Cash cow): когда при наличии продукта, приносящего выгоду без существенных вложений не вкладываются средства в развитие и разработку новых продуктов;

  • Продолжительное устаревание (Continuous obsolescence): выделение непропорционально больших усилий на портирование системы в новые окружения;

  • Сваливание расходов (Cost migration): перенос расходов на проект к уязвимому отделу или бизнес-партнёру;

  • Ползущий улучшизм (Creeping featurism): добавление новых улучшений в ущерб суммарному качеству системы;

  • Разработка комитетом (Design by committee): разработка проекта без централизованного управления, либо при некомпетентном руководстве;

  • Неуёмная преданность (Escalation of commitment): продолжение реализации решения после того, как доказана его ошибочность;

  • Я тебе это говорил (I told you so): игнорирование мнения эксперта

  • Управление основанное на числах (Management by numbers): излишнее внимание к численным показателям, либо имеющим очень косвенное отношение к управляемой системе, либо сложным для получения;

  • Драконовские меры (Management by perkele): неоправданно жесткий стиль управления;

  • Управление грибами (Mushroom management): недостаточное информирование работников о выполняемой работе;

  • Расползание рамок (Scope creep): потеря контроля над разрастанием проекта;

  • Замыкание на продавце (Vendor lock-in): жёсткая привязка к поставщику;

  • Тёплое тело (Warm body): человек, чей вклад в проект под сомнением;

  • Единственный знающий человек (Single head of knowledge, SHOK): когда жизненно важными для проекта сведениями или навыками обладает только один человек в команде; с его уходом работа останавливается;

  • Рыцарь на белом коне (Knight in shining armor, KISA): когда на сцене появляется человек, который пытается починить всё, не сообщая никому, что он сделал и почему.

Шуточные антипаттерны

  • Паблик Морозов: Класс-потомок, созданный в соответствии с этим антипаттерном, выдает по запросу все данные класса-предка, независимо от степени их сокрытия. Название данного антипаттерна — это каламбур, основанный на созвучии ключевого слова public (паблик), часто означающего открытый доступ к методам и полям класса в объектно-ориентированных языках программирования, и имени пионера-героя Павлика Морозова, выдавшего, по утверждению советской пропаганды, следственным органам своего отца, имевшего преступные связи с кулаками.

Соседние файлы в папке ПИАПС