Какие знаете паттерны проектирования?cplus-76

Классификация паттернов

1. Порождающие паттерны

Singleton

class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
    // Удаляем копирование и присваивание
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
private:
    Singleton() = default;
};

Применение: Логирование, доступ к глобальным ресурсам
Проблемы: Потокобезопасность в C++11+ решена через magic statics

Factory Method

class Creator {
public:
    virtual ```Creator() = default;
    virtual std::unique_ptr<Product> create() const = 0;
};

class ConcreteCreator : public Creator {
public:
    std::unique_ptr<Product> create() const override {
        return std::make_unique<ConcreteProduct>();
    }
};

Применение: Плагины, кросс-платформенные UI элементы

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

Adapter

class LegacySystem {
public:
    void oldMethod() {/*...*/}
};

class NewInterface {
public:
    virtual void newMethod() = 0;
};

class Adapter : public NewInterface {
    LegacySystem legacy;
public:
    void newMethod() override { legacy.oldMethod(); }
};

Применение: Интеграция старого кода с новой системой

Composite

class Component {
public:
    virtual void operation() = 0;
    virtual void add(Component*) {}
    virtual void remove(Component*) {}
};

class Leaf : public Component {
    void operation() override {/*...*/}
};

class Composite : public Component {
    std::vector<Component*> children;
public:
    void operation() override {
        for (auto child : children) child->operation();
    }
    void add(Component* c) override { children.push_back(c); }
};

Применение: GUI, файловые системы

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

Observer

class Observer {
public:
    virtual void update(const std::string& data) = 0;
};

class Subject {
    std::vector<Observer*> observers;
public:
    void attach(Observer* o) { observers.push_back(o); }
    void notify(const std::string& data) {
        for (auto o : observers) o->update(data);
    }
};

Применение: Event systems, MVC

Strategy

class SortingStrategy {
public:
    virtual void sort(std::vector<int>&) const = 0;
};

class QuickSort : public SortingStrategy {
    void sort(std::vector<int>& v) const override {/*...*/}
};

class Context {
    std::unique_ptr<SortingStrategy> strategy;
public:
    void setStrategy(std::unique_ptr<SortingStrategy> s) { strategy = std::move(s); }
    void execute(std::vector<int>& v) { strategy->sort(v); }
};

Применение: Алгоритмы, которые могут меняться в рантайме

Современные C++ реализации

  1. RAII - идиома управления ресурсами
  2. Type Erasure - std::function, std::any
  3. CRTP (Curiously Recurring Template Pattern)
template <typename T>
class Base {
    void interface() { static_cast<T*>(this)->implementation(); }
};

class Derived : public Base<Derived> {
    void implementation() {/*...*/}
};

Антипаттерны в C++

  1. God Object - класс, который делает всё
  2. Singleton Abuse - избыточное использование
  3. Premature Optimization - оптимизация без профилирования

Резюмируем

Ключевые паттерны для C++ разработчика:

  1. RAII - основа управления ресурсами
  2. Factory/Abstract Factory - гибкое создание объектов
  3. Observer - обработка событий
  4. Strategy - заменяемые алгоритмы
  5. Adapter - интеграция legacy кода

Современный C++ добавляет:

  • Шаблонные решения (CRTP)
  • Функциональные подходы (std::function)
  • Move-семантику для оптимизации

Выбор паттерна должен определяться конкретной задачей, а не желанием применить "красивый" паттерн. В 80% случаев достаточно простых решений без сложных иерархий.