Как ответить
Паттерны проектирования — это не готовые решения, а проверенные шаблоны для типовых проблем в коде. Они дают общий язык для команды и избавляют от изобретения велосипедов. Главное — не применять их ради паттерна, а решать конкретную задачу.
Возьмём пример из реальной практики. Допустим, у нас есть сервис доставки, где нужно логировать все действия пользователя: создание заказа, оплату, отмену. Если размазать логирование по каждому методу, получится каша — дублирование кода, сложность добавления новых каналов (например, отправить лог в Kafka или в файл).
Здесь подходит паттерн Наблюдатель (Observer). Мы создаём событие (например, OrderCreated), подписываем на него обработчики: один пишет в БД, другой отправляет в метрики, третий — в аудит-лог. Когда заказ создаётся, сервис просто публикует событие, а подписчики сами решают, что делать.
// Пример на псевдокоде
class OrderService {
private eventBus: EventBus;
createOrder(data: OrderData): Order {
const order = new Order(data);
// бизнес-логика
this.eventBus.publish(new OrderCreatedEvent(order));
return order;
}
}
class AuditLogger implements Observer {
handle(event: OrderCreatedEvent): void {
// запись в аудит-лог
db.insert('audit', { type: 'order_created', data: event.order });
}
}
class MetricsCollector implements Observer {
handle(event: OrderCreatedEvent): void {
metrics.increment('orders.created');
}
}Плюсы такого подхода:
- Код становится слабо связанным — сервис заказов не знает про логирование и метрики.
- Добавление нового обработчика (например, отправка уведомления в Telegram) не требует изменения существующих классов.
- Легко тестировать — можно подменить EventBus моком.
Но важно помнить: Observer не нужен, если у вас всего один подписчик. Тогда проще вызвать метод напрямую. Паттерн оправдан, когда количество подписчиков растёт или они меняются динамически.
В итоге: паттерны — это инструмент, а не цель. Их стоит использовать, когда чувствуешь, что код начинает «пахнуть» — дублирование, жёсткая связность, сложность расширения. И всегда можно начать с простого решения, а паттерн внедрить рефакторингом, когда появятся реальные потребности.