Шаблоны проектирования: Фабрика

Ответить
ya
^-^
Сообщения: 2673
Зарегистрирован: 16 дек 2021, 19:56

Шаблоны проектирования: Фабрика

Сообщение ya »

Код: Выделить всё

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>

// Базовый класс
class Base {
public:
    virtual void speak() const = 0;
    virtual ~Base() = default;
};

// Производные классы
class ClassA : public Base {
public:
    void speak() const override {
        std::cout << "ClassA\n";
    }
};

class ClassB : public Base {
public:
    void speak() const override {
        std::cout << "ClassB\n";
    }
};

// Фабрика
class Factory {
public:
    using Creator = std::shared_ptr<Base>(*)();

    static std::shared_ptr<Base> create(const std::string& name) {
        auto it = getMap().find(name);
        if (it != getMap().end()) {
            return it->second();
        }
        return nullptr; // или выбросить исключение
    }

    static void registerClass(const std::string& name, Creator creator) {
        getMap()[name] = creator;
    }

private:
    static std::unordered_map<std::string, Creator>& getMap() {
        static std::unordered_map<std::string, Creator> map;
        return map;
    }
};

// функции для создания объектов
std::shared_ptr<Base> createClassA() { return std::make_shared<ClassA>(); }
std::shared_ptr<Base> createClassB() { return std::make_shared<ClassB>(); }

int main() {
    // Регистрация классов в фабрике
    Factory::registerClass("A", createClassA);
    Factory::registerClass("B", createClassB);

    // Вектор строк
    std::vector<std::string> classNames = {"A", "B", "A"};

    // Создание объектов по строкам
    for (const auto& name : classNames) {
        auto obj = Factory::create(name);
        if (obj) {
            obj->speak(); // вызов метода для проверки
        } else {
            std::cout << "Unknown class: " << name << "\n";
        }
    }

    return 0;
}
Ответить