#include <iostream>
#include <memory>

// ==================== Abstract Product: Button ====================
class Button {
public:
    virtual ~Button() = default;
    virtual void paint() = 0;   // Paint the button
    virtual void click() = 0;   // Button click behavior
};

// ==================== Abstract Product: CheckBox ====================
class CheckBox {
public:
    virtual ~CheckBox() = default;
    virtual void paint() = 0;   // Paint the checkbox
    virtual void toggle() = 0;  // Toggle checked state
};

// ==================== Concrete Products: Windows Style ====================
class WinButton : public Button {
public:
    void paint() override {
        std::cout << "WinButton: Paint Windows-style button" << std::endl;
    }
    void click() override {
        std::cout << "WinButton: Windows button clicked" << std::endl;
    }
};

class WinCheckBox : public CheckBox {
public:
    void paint() override {
        std::cout << "WinCheckBox: Paint Windows-style checkbox" << std::endl;
    }
    void toggle() override {
        std::cout << "WinCheckBox: Windows checkbox state toggled" << std::endl;
    }
};

// ==================== Concrete Products: macOS Style ====================
class MacButton : public Button {
public:
    void paint() override {
        std::cout << "MacButton: Paint macOS-style button" << std::endl;
    }
    void click() override {
        std::cout << "MacButton: macOS button clicked" << std::endl;
    }
};

class MacCheckBox : public CheckBox {
public:
    void paint() override {
        std::cout << "MacCheckBox: Paint macOS-style checkbox" << std::endl;
    }
    void toggle() override {
        std::cout << "MacCheckBox: macOS checkbox state toggled" << std::endl;
    }
};

// ==================== Abstract Factory: UI Factory ====================
class GUIFactory {
public:
    virtual ~GUIFactory() = default;
    virtual std::unique_ptr<Button> createButton() = 0;
    virtual std::unique_ptr<CheckBox> createCheckBox() = 0;
};

// ==================== Concrete Factory: Windows Factory ====================
class WinFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<WinButton>();
    }
    std::unique_ptr<CheckBox> createCheckBox() override {
        return std::make_unique<WinCheckBox>();
    }
};

// ==================== Concrete Factory: macOS Factory ====================
class MacFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<MacButton>();
    }
    std::unique_ptr<CheckBox> createCheckBox() override {
        return std::make_unique<MacCheckBox>();
    }
};

// ==================== Client Code ====================
// Client only depends on abstract products (Button/CheckBox) and abstract factory (GUIFactory)
void clientCode(GUIFactory& factory) {
    auto button = factory.createButton();
    auto checkBox = factory.createCheckBox();

    button->paint();
    button->click();
    checkBox->paint();
    checkBox->toggle();
}

// ==================== Main Function ====================
int main() {
    std::cout << "=== Abstract Factory Pattern Demo ===" << std::endl;

    std::cout << "\n--- Using Windows Style ---" << std::endl;
    WinFactory winFactory;
    clientCode(winFactory);

    std::cout << "\n--- Using macOS Style ---" << std::endl;
    MacFactory macFactory;
    clientCode(macFactory);

    return 0;
}

results matching ""

    No results matching ""