#include <iostream>
#include <memory>
#include <string>

// ===========================
// Implementation Interface: Color
// ===========================
class Color {
public:
    virtual ~Color() = default;
    virtual std::string fill() const = 0;  // Return color description
};

// Concrete Implementation: Red
class Red : public Color {
public:
    std::string fill() const override {
        return "red";
    }
};

// Concrete Implementation: Blue
class Blue : public Color {
public:
    std::string fill() const override {
        return "blue";
    }
};

// ===========================
// Abstraction Interface: Shape
// ===========================
class Shape {
protected:
    // Hold reference to implementation through composition - this is the "bridge"
    std::shared_ptr<Color> color_;
public:
    explicit Shape(std::shared_ptr<Color> color) : color_(std::move(color)) {}
    virtual ~Shape() = default;

    // Draw shape, uses color implementation
    virtual void draw() const = 0;
};

// Refined Abstraction: Circle
class Circle : public Shape {
public:
    explicit Circle(std::shared_ptr<Color> color) : Shape(std::move(color)) {}

    void draw() const override {
        std::cout << "Drawing a " << color_->fill() << " circle" << std::endl;
    }
};

// Refined Abstraction: Rectangle
class Rectangle : public Shape {
public:
    explicit Rectangle(std::shared_ptr<Color> color) : Shape(std::move(color)) {}

    void draw() const override {
        std::cout << "Drawing a " << color_->fill() << " rectangle" << std::endl;
    }
};

// ===========================
// Main Function Demo
// ===========================
int main() {
    // Create different color implementations
    auto red = std::make_shared<Red>();
    auto blue = std::make_shared<Blue>();

    // Combine abstraction with implementation (through bridge)
    Circle redCircle(red);
    Rectangle blueRectangle(blue);

    // Can also dynamically switch implementations
    Circle blueCircle(blue);
    Rectangle redRectangle(red);

    // Draw shapes
    redCircle.draw();        // Draw a red circle
    blueRectangle.draw();    // Draw a blue rectangle
    blueCircle.draw();       // Draw a blue circle
    redRectangle.draw();     // Draw a red rectangle

    return 0;
}

results matching ""

    No results matching ""