← Назад к вопросам

Какие паттерны проектирования знаешь и когда их применяешь в C++?

2.0 Middle🔥 161 комментариев
#ООП и проектирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Паттерны проектирования в C++

Паттерны проектирования — это проверенные решения типичных задач разработки. В C++ их применение требует особой аккуратности из-за низкоуровневой природы языка.

Структурные паттерны

Singleton — гарантирует единственный экземпляр класса. Используется для глобальных конфигураций, логгеров, пулов соединений:

class Logger {
public:
    static Logger& getInstance() {
        static Logger instance;
        return instance;
    }
private:
    Logger() = default;
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
};

Factory — создаёт объекты без указания конкретных классов. Полезен при работе с полиморфными типами:

class Connection {
public:
    virtual ~Connection() = default;
    virtual void connect() = 0;
};

class PostgreSQL : public Connection {
public:
    void connect() override { /* ... */ }
};

class ConnectionFactory {
public:
    static std::unique_ptr<Connection> create(const std::string& type) {
        if (type == "postgres") return std::make_unique<PostgreSQL>();
        throw std::invalid_argument("Unknown connection type");
    }
};

Adapter — преобразует интерфейс одного класса к другому. Часто используется при интеграции с legacy-кодом или внешними библиотеками.

Поведенческие паттерны

Observer — уведомляет несколько объектов об изменении состояния. Критичен для event-driven архитектур:

class EventBus {
    std::map<std::string, std::vector<std::function<void()>>> listeners;
    
public:
    void subscribe(const std::string& event, std::function<void()> handler) {
        listeners[event].push_back(handler);
    }
    
    void emit(const std::string& event) {
        for (auto& handler : listeners[event]) {
            handler();
        }
    }
};

Strategy — инкапсулирует алгоритмы в отдельные классы. Применяется для выбора алгоритма сортировки, сжатия, сериализации в runtime.

Command — инкапсулирует запрос как объект. Используется в системах с отложенным выполнением, undo/redo, планировщиках задач:

class Command {
public:
    virtual ~Command() = default;
    virtual void execute() = 0;
};

class TaskScheduler {
    std::queue<std::shared_ptr<Command>> tasks;
public:
    void schedule(std::shared_ptr<Command> cmd) {
        tasks.push(cmd);
    }
};

Практическое применение

  • Threading: Использую Monitor Object и Active Object для синхронизации
  • Memory Management: RAII как основной паттерн управления ресурсами
  • Network: Builder для конфигурации сокетов, Chain of Responsibility для обработки пакетов
  • Database: Repository для абстракции доступа к БД, Unit of Work для транзакций

Ключевой момент — правильный выбор паттерна зависит от контекста. Переприменение паттернов ведёт к усложнению кода. Лучше начать с простого решения и рефакторить при необходимости.