Помимо паттернов проектирования, которые предлагают проверенные решения типичных задач, существуют антипаттерны — распространённые ошибки в архитектуре и коде. Они приводят к усложнению поддержки, росту зависимости, нарушению принципов SOLID и деградации кода.
Антипаттерн — это повторяющаяся неудачная практика, которая кажется удобным решением, но на деле создаёт больше проблем, чем решает.
| Антипаттерн | Описание | Последствия |
|---|---|---|
| God Object | Один класс выполняет слишком много функций и хранит всю бизнес-логику системы. | Нарушение SRP, сложность тестирования и изменений. |
| Spaghetti Code | Запутанный, плохо структурированный код без модульности и понятной архитектуры. | Ошибки, невозможность повторного использования, зависимость от деталей реализации. |
| Copy-Paste Programming | Повторение одного и того же кода вместо его вынесения в отдельный модуль. | Дублирование логики, рост багов и сложности сопровождения. |
| Golden Hammer | Использование одного знакомого инструмента для всех задач, независимо от контекста. | Неоптимальные решения, низкая производительность, нарушение принципа KISS. |
| Lava Flow | Ненужный код, оставшийся в проекте из-за страха его удалить. | Снижение читаемости, рост технического долга. |
| Hard Coding | Жёсткое встраивание значений (например, путей, паролей, конфигурации) прямо в код. | Проблемы при изменении, переносе и тестировании приложения. |
| Circular Dependency | Два или более модуля зависят друг от друга напрямую. | Нарушение модульности, невозможность переиспользования, потенциальные ошибки при компиляции. |
| Magic Numbers | Использование числовых или строковых литералов без пояснения их смысла. | Потеря понимания кода, сложность поддержки. |
| Shotgun Surgery | Любое изменение требует правок в десятках мест. | Рост времени разработки и ошибок, нарушение инкапсуляции. |
| Singleton Obsession | Чрезмерное использование Singleton даже там, где это не нужно. | Скрытые зависимости, проблемы с тестированием, глобальное состояние. |
catch-блоки скрывают ошибки и усложняют диагностику.// ❌ Плохой пример: один класс управляет всем
public class ApplicationManager
{
public void ConnectToDatabase() { /* ... */ }
public void AuthenticateUser() { /* ... */ }
public void RenderUI() { /* ... */ }
public void ProcessPayments() { /* ... */ }
public void SendEmail() { /* ... */ }
// ...
}
// ✅ Исправленный вариант: разделяем ответственность
public class DatabaseService { public void Connect() { /* ... */ } }
public class AuthService { public void Login() { /* ... */ } }
public class PaymentProcessor { public void Process() { /* ... */ } }
public class MailService { public void Send() { /* ... */ } }
Антипаттерны — не просто ошибки, а симптомы неправильных решений. Их важно знать, чтобы распознавать и устранять ещё на стадии проектирования. Как и с паттернами, ключ — понимание контекста: иногда «запрещённая» практика уместна, но осознанно и с контролем последствий.