Если вам достался проект, в котором копаться — всё равно что распутывать спагетти в боксерских перчатках, вы, скорее всего, столкнулись с антипаттернами. К этим практикам сначала прибегают как к быстрым решениям, но затем они превращаются в повторяющиеся ночные кошмары. Представьте себе магическую кнопку деплоя, которая ломает всё в 2 часа ночи — а дежурите вы.
Антипаттерны проникают активнее всего, когда команды разработки ставят скорость выше структуры. То, что начинается как невинная короткая дорога, может перерасти в полноценного алгоритмического монстра, подрывая производительность и поддерживаемость. Джоэль Спольски говорит, что «читать код сложнее, чем его писать». А читать такой код попросту больно.
Хорошая новость: вы не застряли в этом. Независимо от того, управляете ли вы кодом внутри компании или работаете с партнёрами по разработке ПО, главное — выявить эти проблемы вовремя. Давайте рассмотрим самые распространённые антипаттерны в программировании, от Спагетти-кода до «Лодочных якорей», с примерами реального кода. Вы научитесь замечать «запашки» на ранней стадии и проводить рефакторинг до того, как ваш продукт станет «Большим комком грязи» (Big Ball of Mud).
Что такое антипаттерны в программировании?
Антипаттерны — это повторяющиеся плохие практики кодирования, которые на первый взгляд кажутся полезными, но в конечном итоге приводят к техническому долгу, багам и раздутым кодовым базам. Они часто появляются из-за спешки в разработке, отсутствия планирования или неправильного применения лучших практик. Эти практики усложняют масштабирование, отладку и обслуживание вашего ПО.
Антипаттерны — словно мины на пути разработки. Сначала эти «быстрые решения» кажутся умными. Но затем они потихоньку добавляют сложность, пока код не становится хрупким. Мёртвый код, Стрельба дробью (Shotgun Surgery) и программирование методом copy-paste — некоторые из основных подозреваемых.
Антипаттерны процветают, когда разработчики закрывают глаза на принципы программной инженерии. Пропуск код-ревью, выбор неправильных паттернов проектирования или некорректное использование принципа разделения интерфейсов может вызвать хаос в кодовой базе.
«Хорошие программисты пишут код, который может понять человек».
— Мартин Фаулер, Refactoring
Линус Торвальдс предупреждал о раздутых архитектурных решениях. Когда только один экземпляр класса обрабатывает UI, логику и обращения к базе данных, нарушается принцип единой ответственности, и возникает God object. Это архитектурный беспорядок, от которого не упасёт ни один язык программирования.
Избегать антипаттернов — значит учиться на неудачах и следовать проверенным рекомендациям. Принципы SOLID — это дорожная карта по созданию масштабируемого и поддерживаемого ПО. Мартин Фаулер и Роберт С. Мартин показали, что хороший код не только пишется, но и переписывается, рефакторится и неустанно упрощается.
Распространённые антипаттерны в программировании
Антипаттерны, такие как Спагетти-код или God Class, проникают незаметно, часто маскируясь под умные короткие пути. Со временем они добавляют технический долг, приводят к появлению дурно пахнущего кода (“code smells”) и подрывают даже самые многообещающие проекты разработки ПО. Давайте рассмотрим десять самых опасных антипаттернов, с реальными примерами, последствиями и способами их устранения.
Спагетти-код
Спагетти-код — один из самых заметных антипаттернов в программировании. Он возникает, когда код пишется в спешке и без чёткого архитектурного плана. Нет модульности и структуры — просто функции, вызывающие другие функции в разных местах, часто сваленные в один класс с множеством обязанностей. Ранние работы Кента Бека по Extreme Programming подчёркивали важность простоты не просто так: беспорядочный код наращивает технический долг быстрее, чем вы успеете произнести «рефакторинг».
Классический реальный пример — ранние версии OpenSSL. До своей масштабной чистки в 2014 году основные функции находились в одном огромном файле, заполненном глубоко вложенной логикой и устаревшим кодом, который был вперемешку с блоками переиспользуемых, но слабо связанных между собой методов. Вот упрощённый фрагмент:
if (!s->quiet_shutdown && !(s->shutdown & SSL_SENT_SHUTDOWN)) {
ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
}
if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
s->shutdown |= SSL_SENT_SHUTDOWN;
}
Этот код сложен и ему не хватает структуры, пригодной для тестирования. Любое изменение может привести к непредсказуемым последствиям в других методах. Такой код буквально «воняет». Рефакторинг этого беспорядка в несколько классов с чёткими интерфейсами — эффективное решение.
Спагетти-код не только нарушает поддерживаемость, но и подрывает настрой команды. И тут нет никакой серебряной пули, которая всё исправит. Только дисциплинированный, итеративный подход и отказ от применения одного решения ко всем проблемам.
God Object
Один объект, чтобы править всем — и разрушить всё с его помощью.
God Class — один из самых опасных антипаттернов в программировании. Он появляется, когда один класс накапливает слишком много логики: бизнес-правила, обработку данных, поведение интерфейса и даже доступ к базе данных. Это приводит к нарушению принципа единой ответственности, создаёт сильно связанные компоненты и разрушает возможность тестирования.
Возьмём классический пример из устаревшей CRM-системы на GitHub. Этот раздувшийся объект управляет ID пользователей, обработкой платежей, генерацией электронных писем и логированием — всё это в одном файле. Вот упрощённый пример:
public class UserManager {
public void createUser(String userId) { /* ... */ }
public void chargeUser(String userId) { /* ... */ }
public void sendEmail(String userId) { /* ... */ }
public void logUserActivity(String userId) { /* ... */ }
}
Пытаться изолировать юнит-тестирование для одного метода здесь практически невозможно. В результате приходится писать мок-объекты для других классов, которые God Object неправомерно контролирует. Как итог — хрупкий код накапливает технический долг, а команда разработчиков постоянно работает в режиме тушения пожаров. Мартин Фаулер в книге Refactoring предупреждает, что этот паттерн не только неэффективен, но и крайне контрпродуктивен.
Худшее здесь то, что часто такие объекты остаются в коде надолго — как застывшая лава, которую страшно трогать. Их слишком рискованно удалить, и они слишком важны, чтобы их игнорировать. Исправить их непросто, да, но оставить их в коде — значит ускорить разрушение разработки быстрее, чем это сделает любой дедлайн.
3. Программирование методом Copy-Paste
И снова дежа вю. Один и тот же блок кода с одинаковыми именами, скопированный в несколько файлов, как цифровая сыпь.
Программирование через copy-paste — один из самых заметных антипаттернов в программировании, и под давлением сроков эта хворь поражает даже опытные команды. Может показаться, что он ускоряет процесс, но со временем это порождает одни и те же баги снова и снова, усложняет обслуживание и гарантирует несогласованность.
Этот антипаттерн часто появляется в больших проектах разработки ПО с плохим планированием. Например, в одном проекте с открытым исходным кодом разработчики дублировали одну и ту же логику проверки платежей в нескольких классах. Вот упрощённый пример, вдохновлённый реальным кодом:
if not transaction_id.startswith("txn_") or len(transaction_id) < 10:
return False
# та же логика повторяется в другом месте с незначительными изменениями
Каждый экземпляр имел небольшие отличия. Когда требования изменялись, разработчики должны были искать и обновлять логику в нескольких местах. Неудивительно, что какие-то копии упустили — это привело к ошибкам и скрытым исправлениям, которые ломали продакшн. Джоэль Спольски предупреждал в книге Joel on Software, что хотя такая дубликация и кажется соблазнительной, зачастую она приводит к хаосу.
Это не просто дурной тон — это дублирование кода, которое препятствует модульности и нарушает основные принципы DRY. Исправьте это, абстрагируя общие методы в повторно используемые компоненты. Когда разработчики копируют и вставляют код в программу, они не ускоряют процесс разработки — они создают минное поле для будущих разработчиков.
4. Золотой молоток
Когда у вас есть только молоток, любая проблема кажется гвоздём.
Антипаттерн Золотой молоток (Golden Hammer) возникает, когда разработчики полагаются на одно знакомое средство или решение — независимо от того, подходит ли оно. Это часто бывает в условиях сжатых циклов разработки или в командах, которым не хватает архитектурных ориентиров. Результат? Чрезмерное использование неподходящей абстракции, что приводит к раздутому исходному коду и хрупкости систем.
Классический пример исходит из реальной корпоративной системы, где команда использовала хранимые процедуры для всего, включая бизнес-логику, валидацию данных и оркестрацию рабочих процессов. Вот упрощённый фрагмент:
-- Нецелевое использование хранимой процедуры для несвязанной функциональности
CREATE PROCEDURE ProcessOrder
AS
BEGIN
EXEC ValidateCustomer;
EXEC UpdateInventory;
EXEC SendConfirmationEmail;
END
Вместо того чтобы распределить обязанности между классами и методами приложения, предназначенными для каждой задачи, команда полагалась полностью на базу данных для обработки всей функциональности. Такое чрезмерное использование хранимых процедур создало узкие места в производительности, нарушило поддерживаемость и загнало систему в негибкую архитектуру, плохо совместимую с современными практиками.
Фред Брукс предупреждал в своей книге The Mythical Man-Month, что попытка применить одно и то же решение ко всем проблемам — это быстрый путь к неудаче. В данном случае команда «изобретала велосипед», и не в лучшем виде.
Зрелость архитектурного подхода проявляется в умении выбирать нужные инструменты, а не в слепом следовании привычным.
5. Стрельба дробью
Вы просто меняете цвет кнопки — и вдруг вам нужно обновить 15 файлов в 8 папках.
Стрельба дробью — один из самых раздражающих антипаттернов в программировании. Она возникает, когда небольшое изменение в логике или интерфейсе требует правок в десятках классов, методов или файлов. Обычно это следствие плохого разделения функциональности в процессе разработки.
Пример из реальной практики можно найти в кодовой базе JHipster. В старых версиях добавление функциональности в роли пользователей означало обновление нескольких слоёв: классов, конфигураций JSON, guard’ов маршрутов и сервисов. Вот упрощённый пример:
if (user.role === 'admin') {
// access allowed
} else {
return false;
}
Эта логика была скопирована в несколько компонентов, вместо того чтобы быть централизованной в повторно используемом сервисе. Каждое изменение ролей заставляло разработчиков проходиться по всей кодовой базе и вручную править однотипную логику. Такая фрагментация создаёт хрупкую систему, где «исправление» приводит к появлению новых ошибок.
Книга The Pragmatic Programmer предупреждает об этих архитектурных ловушках. Она пропагандирует консолидацию и умную абстракцию для решения повторяющихся проблем. Это также классический случай так называемого bike-shedding, когда команды спорят о деталях реализации, игнорируя структурные проблемы.
Стрельба дробью пожирает время и распространяет технический долг по кодовой базе, подобно вирусу.
6. Лавовый поток
Никто уже и не помнит, что делает тот старый метод, но все боятся его трогать — вдруг сломает полсистемы.
Лавовый поток (Lava Flow) — это один из самых коварных антипаттернов. Он относится к оставшемуся коду или логике, которые были частью прошлых функций, но теперь их никто не понимает и не поддерживает. Эти «горячие пути» со временем затвердевают, становясь неподъёмным балластом, которые тянут систему вниз.
Реальный пример приходит из старых систем управления миссиями NASA, где десятилетний устаревший C-код продолжал работать в продакшене. Вот упрощённый фрагмент:
if (strcmp(user_id, "test") == 0) {
legacyLogTransaction(transaction_id);
// Неизвестное назначение, нет документации
}
Никто не мог объяснить, что произойдёт, если удалить этот блок. Это классический Лавовый поток. Он порождает избыточное количество неиспользуемых методов, мёртвой логики и хрупких точек интеграции. Разработчики избегают их, предпочитая обойти их в коде (похоже на то, как если бы вы убирались вокруг спящей злой собаки — лишь бы не разбудить). Но обход лавы приводит к появлению ещё большего количества дублирования и переусложнения.
По словам Мартина Фаулера в Refactoring, накопление замороженной логики — это симптом слабого тестирования и плохой документации. Единственный способ решить это — храбростью, тщательным тестовым покрытием и чисткой в рамках спринтов, встроенных в план разработки.
7. Мёртвый код
Он компилируется. Он поставляется. Но его никогда не используют.
Мёртвый код — один из самых обманчиво безобидных антипаттернов. Это логика, которая скрывается в кодовой базе задолго после того, как она перестала быть актуальной. Это могут быть старые методы, неиспользуемые классы или закомментированные эксперименты, и этот хлам тормозит разработку и сбивает с толку тех, кто пытается в нём разобраться.
Реальный пример исходит из CMS Drupal, где разработчики нашли сотни недоступных строк кода, оставшихся от устаревших модулей. Вот упрощённый фрагмент:
// Устаревшая после миграции на новую систему пользователей
function getLegacyUserId($username) {
return $userIdMapping[$username] ?? null;
}
Эта функция не вызывалась годами, но она оставалась, засоряя автокомплит и порождая карго-культ программирования, когда джуниор разработчики копировали её, не зная, что она устарела. Без строгих практик код-ревью эти остатки понемногу увеличивают сложность системы и замедляют её работу.
Согласно книге Design Patterns Гаммы и соавторов, ключ к масштабируемости — «бережная» (lean) архитектура. Очистка мёртвого кода помогает устранить путаницу, предотвратить распространённые сбои и уменьшить скрытые зависимости. Удаляйте без жалости, документируйте без пощады. Если код не поддерживает текущую функциональность, его не должно быть в вашем приложении.
Совет: Мёртвый код отличается от «Лодочных якорей». Он когда-то был активен, но теперь никогда не выполняется или был заменён, но всё ещё существует в кодовой базе. Мёртвый код добавляет путаницу и может привести к ошибкам, если кто-то случайно снова его вызовет.
8. Лодочный якорь
Он до сих пор в репозитории. Никто им не пользуется. Но никто не решается его удалить.
Антипаттерн Лодочный якорь (Boat Anchor) описывает файл, модуль или инструмент, который был создан — обычно с большими затратами — но никогда не использовался. Он всё ещё находится в кодовой базе, потому что никто не знает, безопасно ли его удалять, или, что ещё хуже, потому что «вдруг когда-нибудь пригодится». Этот технический балласт часто соседствует с God Class или заброшенным паттерном Синглтон (Singleton).
Классический пример приходит из массово форкнутой старой Java ERP-системы. Проект включал класс ReportEngine, предназначенный для генерации динамических PDF-документов для записей клиентов. Этот класс так и не был завершён, но оставался в основной ветке в течение нескольких лет. Вот упрощённый фрагмент:
public class ReportEngine {
public void generateReport(String userId, TransactionId txn) {
// TODO: Implement logic
}
}
Несмотря на отсутствие реализации, класс сохранялся, на него ссылались в документации, и он стал примером “mushroom management” — управления по принципу «держи в неведении и корми чепухой». Это оставляло новых разработчиков в недоумении и заставляло провлять чрезмерную осторожность.
Вы увидите эти якоря на The Daily WTF как материал для технического стендапа. Они часто соседствуют с неиспользуемыми классами, недокументированными методами и хрупкими предположениями. Чтобы безопасно удалить их, вам потребуется надёжная документация и немного смелости — пока накопившийся вес не потопил всю архитектуру.
Совет: Лодочные якоря отличаются от Мёртвого кода. Это код, файлы, библиотеки или системы, которые включены в проект, возможно даже развернуты, но на самом деле никогда не используются. Лодочные якоря добавляют избыточность и приводят к когнитивному перегрузу.
9. Магическая кнопка
Один клик. Ноль видимости. Огромные последствия.
Антипаттерн Магическая кнопка возникает, когда одно действие в интерфейсе вызывает сложную и непрозрачную цепочку процессов в бэкенде. Кнопка может называться «Deploy», «Process» или «Sync», но за ней скрывается запутанная сеть методов, классов и побочных эффектов, которые пользователь (и часто разработчики) не видят. Она кажется мощной — пока не ломается.
В одном известном примере, размещённом на Stack Overflow, в банковской платформе была кнопка «Reconcile Transactions» в административной панели. После одного нажатия она молча изменяла идентификаторы транзакций, очищала логи и сбрасывала флаги в несвязанных модулях. Вот упрощённый вызов на сервере:
@app.route('/admin/reconcile')
def reconcile():
reconcile_transactions()
sync_ledger()
delete_user_logs()
notify_auditor()
Код не предоставлял обратной связи, логирования или отката. Один клик мог — и однажны действительно привёл — к потере всей истории пользователей. Это примеры скрытой архитектурной сложности, часто встроенные в God Class или паттерн Синглтон, который стал слишком мощным.
Кремниевая долина высмеяла этот троп в «Nucleus», продукте, который сначала казался идеальным, пока вдруг не перестал работать. Когда разработчики не могут отследить, что вызвало действие кнопки, они оказываются в аду зависимостей, пытаясь с помощью логов понять, что произошло.
Прозрачность и отслеживаемость — это антиподы. Каждое действие должно быть прозрачным, отслеживаемым и при необходимости — отменяемым.
10. Большой комок грязи
Он работает. Никто не знает, как. И никто не хочет в это лезть.
Большой комок грязи — это разросшаяся, лишённая структуры масса кода, где всё — классы, функции, модули — переплетено между собой. Он растёт, когда команды забивают на архитектуру ради скорости, пока система не становится нетестируемой, нерасширяемой и практически неисправимой. В чём основная причина? Отсутствие разделения обязанностей, отсутствие плана и, как правило, огромный God Class в центре.
Хорошо известный пример можно найти в старой версии WordPress, где ключевая логика конфигурации, шаблоны отображения и бизнес-правила были все собраны в одном файле functions.php. Со временем разработчики добавили логику для валидации ID пользователя, регистрации транзакционных ID и даже создание шаблонов для писем — всё в одном файле. Вот упрощённый фрагмент:
function processTransaction($userId, $transactionId) {
updateUserProfile($userId);
logTransaction($transactionId);
sendConfirmationEmail($userId);
}
Здесь нет абстракции или связности. Просто набор процедур, сваленных в один монолит. Новые разработчики, попавшие в такую систему, сразу столкнутся с когнитивной перегрузкой.
В сериале Halt and Catch Fire есть прекрасная иллюстрация этого: легаси код, который как-то «работает», но ломается, как только вы пытаетесь что-то изменить. Добавьте немного copy-paste программирования, и получите классическую Stovepipe System (изолированную систему) — узкую и хрупкую.
Единственное реальное решение — это безжалостный рефакторинг, разделение слоёв и команда, готовая влезть в этот код с головой.
Как выявить и исправить антипаттерны
Плохие паттерны — как капканы, раскиданные по кодовой базе. Независимо от того, сталкиваетесь ли вы с раздувшимися классами, дублированными методами или загадочными путями кода, активируемыми случайным ID транзакции, первый шаг — это заметить проблему. Вот практический чек-лист для выявления проблем и проверенные стратегии рефакторинга, пока они не превратили проект в сплошной хаос.
Чек-лист для предотвращения антипаттернов:
Требует ли небольшое изменение правок в нескольких файлах или компонентах? Это признак сильной связанности (tight coupling) и слабой декомпозиции.
Есть ли у вас классы, которые обрабатывают UI, бизнес-логику и доступ к данным? Вероятно, это нарушение принципа единой ответственности (Single Responsibility Principle, SRP).
Копируется ли один и тот же блок кода в несколько файлов? Это знак того, что нужно рефакторить в повторно используемые функции или классы.
Есть ли методы или модули в кодовой базе, которые никогда не используются? Это Мёртвый код, который добавляет беспорядок и риск.
Используется ли один и тот же паттерн проектирования или инструмент везде, даже если не подходит? Проверьте на наличие синдрома Золотого молотка — неправильное использование знакомых инструментов.
Вызывают ли кнопки или команды длинную цепочку скрытых, невидимых действий? Это указывает на настройку Магической кнопки — слишком много скрытой логики.
Есть ли файлы или модули, которые оставили «на всякий случай», но которые так никто и не использует? Это могут быть Лодочные якоря — технический балласт, который следует удалить.
Есть ли старый код, который никто не понимает, но все боятся удалить? Это, вероятно, Лавовый поток — унаследованная логика, которую никто не хочет трогать.
Кажется ли, что части системы изолированы и трудно интегрируемы с другими? Это может быть антипаттерн «Дымоход» (Stovepipe System), разработанный без общих стандартов.
В проекте отсутствует чёткая структура папок или модулей? Вы, вероятно, работаете внутри Большого комка грязи.
Как избавляться от антипаттернов: стратегии рефакторинга, которые действительно работают
Что делать, когда антипаттерн уже в коде — три подхода к спасению проекта.
1. Применяйте принципы SOLID
Принципы SOLID дают разработчикам практическую основу для построения поддерживаемого и масштабируемого кода. Следуя этим принципам, вы снижаете риск появления антипаттернов, таких как God Class или Стрельба дробью. Например, принцип единой ответственности (Single Responsibility Principle) рекомендует разделять методы, которые обрабатывают разные задачи, чтобы класс не превращался в мешанину из несвязанных обязанностей. Нарушение этих принципов часто приводит к хрупким системам, напоминающим классический Спагетти-код.
2. Используйте правильные паттерны проектирования
Паттерны проектирования, такие как Фабричный метод, Синглтон и Наблюдатель, являются проверенными решениями для распространённых архитектурных проблем — но только если они применяются правильно. Разработчики часто попадают в антипаттерны, потому что автоматически тянутся к знакомым паттернам, даже если они не подходят. Вместо того чтобы слепо использовать паттерн Синглтон, остановитесь и оцените: должен ли этот объект вообще быть Синглтоном с глобальным состоянием? Умное использование этих методов поддерживает лучшую абстракцию, гибкость и модульный дизайн без излишнего проектирования.
3. Используйте инструменты анализа кода
Инструменты, такие как SonarQube, ESLint или статический анализатор IntelliJ, помогают своевременно выявить запахи кода — признаки архитектурных и логических проблем. Они помечают сложные методы, неиспользуемые переменные и сильно связанные классы, которые могут указывать на скрытый антипаттерн. Это экономит время разработчиков на ручной проверке кода и и снижают ступор перед большим рефакторингом. Автоматизированные инструменты также помогают выявлять повторяющиеся структуры, что способствует удалению технического долга до того, как он накопится.
Как антипаттерны ломают проекты: 3 кейса из жизни
Антипаттерны — это не просто теория — они ежедневно появляются в продакшене. От классов, переплетённых в круг зависимостей, до поспешных деплоев с ошибками, эти реальные истории показывают, чем заканчивается равнодушие к архитектуре. Вот три предостерегающих примера, когда разработчики, завязшие в техдолге и уязвимой архитектуре, узнали на собственном опыте, что не нужно делать.
Кейс 1: Борьба со Спагетти-кодом в легаси системах
Одна крупная финансовая организация столкнулась с проблемами из-за Спагетти-кода: их кодовая база превратилась в хаотичную паутину классов и методов. Сложность мешала добавлению новой функциональности. Риск багов резко вырос. Чтобы решить проблему, команда разработчиков внедрила строгий процесс рефакторинга кода. Они использовали модульный дизайн и следовали принципам SOLID. Этот подход улучшил поддерживаемость кода и уменьшил хрупкость системы.
Кейс 2: Рефакторинг God Object
В одной легаси системе класс под названием ApplicationManager чрезмерно раздулся и стал охватывать различные функциональности, от аутентификации пользователей до обработки данных. Эта централизация привела к тому, что код стал неудобным для поддержки и развития. Команда разработчиков использовала архитектурные принципы SOLID, чтобы разбить ApplicationManager на специализированные классы, каждый из которых выполнял конкретные обязанности. Этот модульный подход улучшил читаемость и поддерживаемость кода, а также позволил разработчикам внедрять новые функции с меньшим количеством багов.
Кейс 3: Борьба с техническим долгом в монолитной системе
Один из проектов компании столкнулся с резким ростом затрат на обслуживание из-за технического долга в своём монолитном приложении. Сложность системы замедляла разработку новых фич и увеличивала количество дефектов. Для исправления ситуации они начали использовать стратегию непрерывного рефакторинга, постепенно улучшая качество кода и снижая зависимости. Очистка кода улучшила производительность системы и и подняла командный дух.
Когда антипаттерн — не враг: допустимые компромиссы
Безжалостное искоренение антипаттернов может быть столь же плохим, как и их использование. Не все «плохие» паттерны опасны. Когда вам нужна скорость и прототипирование, можно ослабить строгие требования к лучшим практикам.
Иногда Copy-Paste программирование работает
В условиях быстрого развития — при системах, критичных к производительности, или при быстром прототипировании — copy-paste программирование может быть обоснованным решением. Когда важна каждая наносекунда, вызов функции может стоить слишком дорого. Иногда лучше продублировать методы, чем заставлять их абстрагироваться. Да, это плохо для поддержки — но оправдано ради скорости. Как говорится в Joel on Software, правильный ответ в программировании часто: ”It depends” (Зависит от обстоятельств).
God Class может быть полезен
На ранних этапах прототипирования God Class, который объединяет множество обязанностей, может предложить скорость и простоту. Когда команда мала, а требования меняются, создание модульных классов может замедлить итерацию. Вместо этого один управляющий объект может быстро связывать UI, логику и хранилище. Ключевое здесь — признать это сокращение как временное. Как только направление продукта стабилизируется, рефакторинг в более чистую архитектуру становится обязательным. Без чётких границ рефакторинг позже становится сложным, что повышает риски vendor lock-in и превращает архитектуру в бетон.
Антипаттерны — не приговор, если распознать их вовремя
Антипаттерны могут начинаться с малого, но они масштабируются быстрее, чем ваши лог-файлы. Если их не устранить, они превратят код в хрупкий монолит и замедлят всю систему. Раннее выявление таких проблем помогает командам избежать лишнего технического долга и вернуть контроль над растущими системами.
Умные команды не ждут наступления катастроф. Они выявляют «плохие запахи» во время код-ревью, обеспечивают архитектурную согласованность и следуют таким практикам, как SOLID. Будь то разработка новых фич или исправление багов, такие инструменты, как CI/CD пайплайны, и ресурсы, такие как Stack Overflow, помогают поддерживать кодовую базу чистой и управляемой.
Если вы хотите глубже понять, как на качество архитектуры влияет системный анализ, а также научиться строить процессы без типичных ошибок, обратите внимание на открытые уроки:
9 июня, 20:00 — Как системному аналитику не допустить Spaghetti Code и других проблем в архитектуре
Разбор антипаттернов, причины их возникновения и проверенные методы профилактики и рефакторинга для повышения поддерживаемости проектов.17 июня, 20:00 — Внедрение новой функции системным аналитиком на примере услуги на Госуслугах
Практический разбор всего цикла работы с требованиями — от сбора и моделирования бизнес-процессов до проектирования интерфейсов и интеграции.
Больше открытых уроков по разработке смотрите в календаре мероприятий.
Комментарии (9)
Tzimie
28.05.2025 16:37Иногда лучше иметь три похожих но простых и чистых метода, полученных copy paste, чем иметь один переусложненный с кучей if
ImagineTables
28.05.2025 16:37Ох, не знаю. Как по мне, DRY — один из немногих принципов, нарушать который (почти) всегда себе дороже. Почему «почти» — ну, иногда хочется форкнуть логику, чтобы развивать её в разных направлениях. Формально нарушение, а по сути — промежуточный этап эволюции. Кстати, хе-хе, в статье это, вроде бы, подпадает под «лодочный якорь». А мои коллеги, не выкупавшие подобную предусмотрительность, называли такие штуки ругательным словом YAGNI, чем страшно бесили.
В данном конкретном случае я бы предположил, что налицо дефицит выразительных средств языка и требуется обобщение какими-то иными средствами — например, шаблонами или препроцессором. Но, конечно, это надо на конкретных примерах смотреть.
titan_pc
28.05.2025 16:37Фаулер и Боб писали свои книжки когда на свете не было СМЭВ и ГОсуслуг которые интегрируются чеинз СМЭВ. И они 1С в глаза не видели просто. Где на одну кнопку "Провести и закрыть" повешано 10000 операций над системой потому что пользователям лень нажимать 10000 кнопок.
guryanov
Ну вот всеми тут любимый DDD - это как раз стрельба дробью получается? Добавил поле - надо его добавить в базу, в dto для базы, мапперы из базы в сущности, в сущность, в контракт, в маппер из сущности в json. Да ещё и логику обработки этого поля надо вписать в сервис и репозиторий. Все это в разных файлах и разных пакетах.
summerwind
Не надо путать "стрельбу дробью" и обычную сквозную трассировку одной доменной идеи через предусмотренные слои. Причем, локализованную bounded context-ом.
Вот где настоящая "стрельба дробью", это где прокидывают поля из БД чуть ли не напрямую до UI "as-is". По сути, тогда мы делаем структуру таблиц БД публичным контрактом сразу для всех частей системы. И любая правка этой структуры будет размазываться дробью по проекту. Так что, по сути DDD, наоборот, лечит эту проблему.
ImagineTables
Какое прелестное сочетание в одном предложении DDD и пачки грязных технических деталей.