Advertisement
Guest User

Untitled

a guest
Apr 16th, 2014
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.48 KB | None | 0 0
  1. # Анти-паттерны
  2.  
  3. Анти-паттерны (anti-patterns), также известные как ловушки (pitfalls) — это классы наиболее часто внедряемых плохих решений проблем. Они изучаются, как категория, в случае когда их хотят избежать в будущем, и некоторые отдельные случаи их могут быть распознаны при изучении неработающих систем.
  4.  
  5. Термин происходит из информатики, из книги «Банды четырёх» Шаблоны проектирования, которая заложила примеры практики хорошего программирования. Авторы назвали эти хорошие методы «шаблонами проектирования», и противоположными им являются «анти-паттерны». Частью хорошей практики программирования является избегание анти-паттернов.
  6.  
  7. Анти-паттерны можно разделить на группы, в соответствии с этапами разработки ПО.
  8.  
  9. ## Анти-паттерны в управлении разработкой ПО
  10.  
  11. **Дым и зеркала** (Smoke and mirrors) — демонстрация того, как будут выглядеть ненаписанные функции (название происходит от двух излюбленных способов, которыми фокусники скрывают свои секреты).
  12.  
  13. **Раздувание ПО** (Software bloat) — программа, которая требует непропорционально большой объём дискового пространства и оперативной памяти для своих функциональных возможностей[2][3]; программа с ненужными и несущественными возможностями и свойствами («gimmicks» (англ.), «bells and whistles» (англ.), дословно: «бубенчики и свистульки»), которые потребляют огромное количество дискового пространства и оперативной памяти.
  14.  
  15. Сайт Switched Downloadsquad опубликовал в 2008 году примеры наихудших программ в категории «elephantware», то есть «раздутых программ, которые заставляют новейшие персональные компьютеры загружаться подобно Pentium 2 с 64 MB оперативной памяти»[12]. Были названы следующие программы:
  16. - Acrobat Reader
  17. - iTunes
  18. - RealPlayer
  19. - Internet Explorer
  20. - Microsoft Outlook[12].
  21.  
  22. **Функции для галочки** — превращение программы в конгломерат плохо реализованных и не связанных между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть).
  23.  
  24. ## Анти-паттерны в проектировании ПО
  25.  
  26. **Божественный объект (God Object)**
  27.  
  28. > «Мне нужен такой-то функционал. — Используй MegaCoreObject! — И ещё, мне нужен и… — Я же сказал, используй MegaCoreObject!»
  29.  
  30. Анти-паттерн, который довольно часто встречается у ООП разработчиков. Такой объект берет на себя слишком много функций и/или хранит в себе практически все данные. В итоге мы имеем непереносимый код, в котором, к тому же, сложно разобраться. Так же, подобный код довольно сложно поддерживать, учитывая, что вся система зависит практически только от него. Причинами являются — некомпетентность разработчика, взятие одним разработчиком большой части работы (особенно, когда размер работы «превышает» уровень опыта этого разработчика). Бороться с таким подходом надо — разбивать задачи на подзадачи, с возможностью решения этих подзадач различными разработчиками.
  31.  
  32. **Волшебная кнопка (Magic pushbutton)** — выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, в системах типа Delphi это написание прикладной логики в обработчиках нажатий на кнопку.
  33.  
  34. **Золушкина туфелька** — попытка "натянуть" на объект уже имеющийся малоподходящий по смыслу интерфейс, вместо создания нового.
  35.  
  36. **Членовредительство (Mutilation)** — излишнее "затачивание" объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.
  37.  
  38. **Раздувание интерфейса (Interface bloat)** — изготовление интерфейса очень мощным и очень трудным для осуществления.
  39.  
  40. **Большой комок грязи (Big ball of mud)** — система с нераспознаваемой структурой.
  41.  
  42. **Базовый класс-утилита (BaseBean)** — наследование функциональности из класса-утилиты вместо делегирования к нему.
  43.  
  44. **Объектная клоака (Object cesspool)** — переиспользование объектов, находящихся в непригодном для переиспользования состоянии.
  45.  
  46. **Полтергейст (Poltergeist)** — объекты, чьё единственное предназначение — передавать информацию другим объектам.
  47.  
  48. **Проблема йо-йо (Yo-yo problem)** — чрезмерная размытость сильно связанного кода (например, выполняемого по порядку) по иерархии классов.
  49.  
  50. **Одиночество (Singletonitis)** — неуместное использование паттерна одиночка.
  51.  
  52. **Приватизация (Privatisation)** — сокрытие функциональности в приватной секции (private), что затрудняет его расширение в классах-потомках.
  53.  
  54. **Френд-зона (Friend zone)** — Неуместное использование дружественных классов и дружественных функций в языке с++.
  55.  
  56. ## Анти-паттерны в программировании
  57. **«Брось, можно писать не только одну функцию!» или Спагетти-код (Spaghetti code)**
  58.  
  59. Спагетти-код — слабо структурированная и плохо спроектированная система, запутанная и очень сложная для понимания. Такой код так же очень часто содержит в себе множество примеров анти-паттерна программирования копи-пастом. Подобный код в будущем не сможет разобрать даже его автор. В ООП спагетти-код может быть представлен в виде небольшого количества объектов с огромными, по размеру кода, методами. Причинами являются — разработка по принципу «Да ну, оно же работает! Целых пять тысяч строк!», малоэффективные code review, недостаток опыта в ООП разработке, удалённая работа отдельных программистов. Ипользовать спагетти-код повторно невозможно и нежелательно. Если в вашем проекте начинает возникать спагетти-код, а вам как раз надо расширить функционал, который он реализует — не ленитесь, рефакторьте спагетти полностью или напишите эту часть заново! Проиграв немного времени сейчас — вы получите огромный плюс в будущем. Или наоборот — проиграете, если оставите спагетти-код в проекте.
  60.  
  61. **«Что за 42?» или Магические числа (Magic numbers)**
  62.  
  63. Магическое число — константа, использованная в коде для чего либо (чаще всего — идентификации данных), само число не несёт никакого смысла без соответствующего комментария. Числа не несут абсолютно никакой семантики. Когда в коде вашего проекта начинаются появлятся числа, значение которых не является очевидным — это очень плохо. Программист, который не является автором такого кода, с трудностями сможет объяснить как это работает. Со временем и автор кода, с присутствием магических чисел, не сможет объяснить что-либо. Числа затрудняют понимание кода и его рефакторинг. Главными причинами этой ошибки — спешка при разработке, отсутствие практики программирования. Данный анти-паттерн надо пресекать на корню, оговаривая использование числовых констант перед началом разработки.
  64.  
  65. **«Что значит d:\proj\tests.dat?» или Жёсткое кодирование (Hard code)**
  66.  
  67. Жёсткое кодирование — внедрение различных данных об окружении в реализацию. Например — различные пути к файлам, имена процессов, устройств и так далее. Этот анти-паттерн тесно связан с магическими числами, частенько они переплетаются. Захардкодить — жёстко прописать значение каких-либо данных в коде. Главная опасность, исходящая от этого анти-паттерна — непереносимость. В системе разработчика код будет исправно работать до перемещения или переименования файлов, изменения конфигурации устройств. На любой другой системе код может вовсе не заработать сразу же. Как правило, программист практически сразу забывает где и что он захардкодил, даже если делает это в целях отладки кода. Это делает выявление и локализацию данного анти-паттерна очень сложной. С этим надо бороться — оговорив запрет на жёсткое кодирование перед началом разработки и проводя тщательные code review.
  68.  
  69. **Мягкое кодирование (Soft code)**
  70.  
  71. Мягкое кодирование — параноидальная боязнь жёсткого кодирования. Это приводит к тому, что незахардкожено и настраивается абсолютно всё, что делает конфигурацию невероятно сложной и непрозрачной. Этот анти-паттерн является вторым концом палки о жёстком кодировании и поэтому тоже является опасным. Во-первых, при разработке много ресурсов уходит на реализацию возможности настроек абсолютно всего. Во-вторых, развёртывание такой системы повлечет так же дополнительные затраты. Перед началом решения определённой задачи следует определить, что должно быть настариваемым, а что является постоянным для различных систем или может быть настроено автоматически.
  72.  
  73. **Ненужная сложность (Accidental complexity)**
  74.  
  75. Простыми словами — это заумность решения. Ненужная сложность может быть внесена в решение любой задачи. Это могут быть как и ненужные проверки, части кода, продуцированные мягким кодированием, отсутствие какой-либо оптимизации. Это приводит к усложнению понимания кода, понижению скорости работы. Причинами являются — отсутствие или некачественность рефакторинга, некомпетентность программиста. Бороться довольно просто — следует проводить тщательные code review, эффективный рефакторинг.
  76.  
  77. **Лодочный якорь (Boat anchor)**
  78.  
  79. Этот анти-паттерн означает сохранение неиспользуемых частей системы, которые остались после оптимизации или рефакторинга. Часто, после рефакторинга когда, который является результатом анти-паттерна, некоторые части кода остаются в системе, хотя они уже больше не используются. Так же некоторые части кода могут быть оставлены «на будущее», авось придётся ещё их использовать. Такой код только усложняет системы, не неся абсолютно никакой практической ценности. Эффективным методом борьбы с лодочными якорями является рефакторинг кода для их устранения, а так же процесс планирования разработки, с целью предотвращения возникновения якорей.
  80.  
  81. **«От твоего кода дурно пахнет» или Поток лавы (Lava flow)**
  82.  
  83. На каком либо этапе разработки вы можете осознать, что некоторая часть кода очень давно не менялась и вообще недокументирована, или такому коду сопутствует комментарий вида "// Не знаю, как оно работает, но оно работает. Не удалять и не менять!". Если ничего не предпринимать, то такой код и останется в проекте. Но и рефакторить, разбирать его довольно сложно, особенно ели его автор уже не работает над проектом. Проще предусмотреть возникновение такого мёртвого кода, при разработке надо руководствоваться тем, что код в будущем возможно будет немного оптимизирован или дописан, но никак не переписан полностью. Главными причинами возникновения потоков лавы являются — написание больших частей проекта одним программистом, отсутствие code review, ошибки в проектировании архитектуры.
  84.  
  85. **«А если i+1?» или Программирование перебором (Programming by permutation)**
  86.  
  87. Многие начинающие программисты пытаются решать некоторые задачи методом перебора — не брутфорсом решения, а именно подбором параметров, порядка вызова функций и так далее. Все эти игры с +1, -1 к параметрам и подобные штучки устраняют только симптомы, и не дают понимания сути происходящего. А если программист не понимает происходящего, то он не сможет предусмотреть все варианты развития событий и обязательно о чём-то забудет. Он потратит время на подбор работающего для него решения и позднее потратит время для переделки этого решения. Все подобные подобранные решения вылазят боком и хорошо ещё — если в процессе разработки или отладки. К подобному ни в коем случае нельзя привыкать, достигая успеха на небольших задачках. Если программист не может решать задачи другим путём — он некомпетентен и ему не следует доверять разработку — вам же будет хуже.
  88.  
  89. **«Как это вы передали строку вместо числа?!» или Слепая вера (Blind faith)**
  90.  
  91. Этот анти-паттерн — недостаточная проверка корректности входных данных, исправления ошибки или результатов работы кода. Очень часто программист думает, что его код всегда будет в идеальных условиях, никогда не выдаст ошибки и не получит неверных входных данных или, ещё чего, данных неверного типа. Но все лгут ©, поэтому нельзя доверять никакому коду, даже собственному. Но и не следует доводить это недоверие до паранойи, то есть приходить к анти-паттерну ненужной сложности. Просто следует помнить про проверку входных данных и возможные проблемы у чужого кода, который используете вы.
  92.  
  93.  
  94. ## Методологические анти-паттерны
  95. **Золотой молоток (Golden hammer)**
  96.  
  97. Золотой молоток — уверенность в полной универсальности любого решения. На практике, это — применение одного решения (чаще всего какого-либо одного паттерна проектирования) для всех возможных и невозможных задач. Проблема в том, что многие программисты «используют» данный анти-паттерн не подозревая о собственной некомпетентности — они считают, что знают паттерн проектирования и успешно его используют — всё хорошо. Причиной среди новичков является лень к изучению чего-то нового — новичок пытается решить все задачи единственным методом, который он освоил. Но к сожалению, это встречается и среди профессионалов — программист очень любит использовать какой-либо паттерн и начинает делать это везде. С этим надо бороться — для каждой задачи имеется не одно, а несколько, красивых и оптимальных решений — именно к поиску таких решений и сводится эффективная разработка. И только такая разработка позволит создать эффективную систему.
  98.  
  99. **Программирование копи-пастом (Copy and Paste Programming)**
  100.  
  101. Данный анти-паттерн является, наверное, самым древним в программировании. Когда от программиста требуется написание двух схожих функций, самым «простым» решением является написание одной функции, её копирование и внесение некоторых изменений в копию. Какие проблемы это сулит? Во-первых, ухудшается переносимость кода — если потребуется подобный функционал в другом проекте, то надо будет искать все места, где программист накопипастил и переносить их по отдельности. Во-вторых, понижается качество кода — часто программист забывает вносить требуемые изменения в скопированный код. В-третьих, усложняется поддержка кода — так, как если в изначальном варианте был баг, который в будущем надо будет исправить, то этот баг попал во все то, что, опять-таки, накопипастил программист. Это приводит так же к возникновению различных множественных исправлений, которые будут возникать по мере нахождения бага в разных частях кода, для одного единственного бага. В-четвертых, code review значительно усложняется, так как кода становится больше, без видимой значительной выгоды и роста производительности труда. Главными причинами возникновения подобных ошибок являются — отсутствие мыслей про будущее разработки (программисты не продумывают свои действия), недостаток опыта (программисты берут готовые примеры и модифицируют, адаптируя под свои нужды). Решение же, является очень простым — создание общих решений и их использование. Об этом следует думать ещё при разработке решений небольших задач — возможно, что нам потребуется решить эту задачу где-нибудь ещё, или решить эту же задачу, но в другой интепретации.
  102.  
  103. **Фактор невероятности (Improbability factor)** — предположение о невозможности того, что сработает известная ошибка.
  104.  
  105. **Преждевременная оптимизация (Premature optimization)** — оптимизация на основе недостаточной информации.
  106.  
  107. **Изобретение колеса (Reinventing the wheel)**
  108.  
  109. Смысл этого анти-паттерна в том, что программист разрабатывает собственное решение для задачи, для которой уже существуют решения, очень часто лучшие чем придуманное программистом. Разработчик считает себя наилучшим, поэтому для каждой задачи пытается придумать собственное решение, не смотря на опыт его предшественников. Чаще всего это приводит лишь к потере времени и понижению эффективности работы программиста — так как решение может быть найдено далеко неоптимальное или вообще ненайденное. Полностью же отбрасывать возможность самостоятельного решения нельзя, так как это прямой дорогой к приведет к программированию копипастом. Разработчик должен ориентироваться в задачах, которые могут предстать перед ним, чтобы грамотно их решить — используя готовые решение или изобретая собственные. Очень часто причиной этого анти-паттерна является банальная нехватка времени. А время — это деньги.
  110.  
  111. **Изобретение квадратного колеса (Reinventing the square wheel)**
  112.  
  113. Этот анти-паттерн очень тесно связан с простым изобретением колеса — это создание своего плохого решения, при существовании лучшего. Этот анти-паттерн вдвойне забирает время — так как, во-первых, время тратится на изобретение и реализацию собственного решения, во-вторых, время тратится при рефакторинге таких решений и замене их оптимальными. Программист должен быть осведомлен о существовании различных решений для определённых кругов задач, ориентироваться в их преимуществах и недостатках.
  114.  
  115. **Паблик Морозов** — класс-потомок, созданный в соответствии с этим антипаттерном, выдает по запросу все данные класса-предка, независимо от степени их сокрытия. Название данного анти-паттерна — это каламбур, основанный на созвучии ключевого слова public (паблик), часто означающего открытый доступ к методам и полям класса в объектно-ориентированных языках программирования, и имени пионера-героя Павлика Морозова, известного тем, что он выдал своего отца-кулака, занимавшегося вредительством будучи на руководящей должности в советской системе. Источником данного определения является блог пропагандистской направленности.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement