原型模式 (Prototype Pattern)

原型模式 (Prototype Pattern)

意图:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

基础组件
  • Prototype (抽象原型):声明克隆自身的接口
  • ConcretePrototype (具体原型):实现克隆操作
继承/实现关系
Prototype <|-- ConcretePrototype
应用场景
  • 需要创建的对象成本较高(如需要复杂计算或资源)
  • 系统需要独立于创建、组合和表示的方式
  • 避免使用与产品类层次平行的工厂类层次
C++ 实现(图形编辑器场景)
#include <iostream>
#include <memory>
#include <unordered_map>

/*
* 原型模式
* 意图:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
* 基础组件:
* - Prototype (抽象原型):声明克隆自身的接口
* - ConcretePrototype (具体原型):实现克隆操作
* 继承/实现关系:
* ConcretePrototype 类继承自 Prototype 类,并实现克隆方法。
*/

// 抽象原型,重点是声明一个克隆方法
class Graphic {
public:
    virtual ~Graphic() = default;
    virtual std::unique_ptr<Graphic> clone() const = 0;
    virtual void draw() const = 0;
};

// 具体原型:矩形
class Rectangle : public Graphic {
public:
    Rectangle(int width, int height, const std::string& color)
        : width_(width), height_(height), color_(color) {}

    std::unique_ptr<Graphic> clone() const override {
		// 这里使用 std::make_unique 来创建一个新的 Rectangle 对象
		// 相当于调用 Rectangle 的拷贝构造函数
        return std::make_unique<Rectangle>(*this);
    }

    void draw() const override {
        std::cout << "Drawing Rectangle: " << width_ << "x" << height_
            << ", Color: " << color_ << "\n";
    }

    void setSize(int w, int h) { width_ = w; height_ = h; }
    void setColor(const std::string& color) { color_ = color; }

private:
    int width_;
    int height_;
    std::string color_;
};

// 具体原型:圆形
class Circle : public Graphic {
public:
    Circle(int radius, const std::string& color)
        : radius_(radius), color_(color) {}

    std::unique_ptr<Graphic> clone() const override {
        return std::make_unique<Circle>(*this);
    }

    void draw() const override {
        std::cout << "Drawing Circle: Radius " << radius_
            << ", Color: " << color_ << "\n";
    }

    void setRadius(int r) { radius_ = r; }
    void setColor(const std::string& color) { color_ = color; }

private:
    int radius_;
    std::string color_;
};

// 原型管理器,用于存储和克隆原型
class GraphicManager {
public:
    void registerPrototype(const std::string& key, std::unique_ptr<Graphic> proto) {
        prototypes_[key] = std::move(proto);
    }

    std::unique_ptr<Graphic> createGraphic(const std::string& key) {
        auto it = prototypes_.find(key);
        if (it != prototypes_.end()) {
			// 通过已注册的原型,调用克隆方法创建新对象
            return it->second->clone();
        }
        return nullptr;
    }

private:
    std::unordered_map<std::string, std::unique_ptr<Graphic>> prototypes_;
};

void PrototypePattern()
{
	std::cout << std::string(13, '-') << " Prototype Pattern " << std::string(13, '-') << "\n";

	GraphicManager manager;

    manager.registerPrototype("large-red-rect", std::make_unique<Rectangle>(100, 50, "red"));
    manager.registerPrototype("small-blue-circle", std::make_unique<Circle>(10, "blue"));

    std::unique_ptr<Graphic> rect = manager.createGraphic("large-red-rect");
    rect->draw();

	std::unique_ptr<Graphic> circle = manager.createGraphic("small-blue-circle");
	if (auto c = dynamic_cast<Circle*>(circle.get())) {
		// 修改克隆对象,原型不会受影响
		c->setRadius(15); 
        c->setColor("green");
	}
	circle->draw();

	std::unique_ptr<Graphic> anotherCircle = manager.createGraphic("small-blue-circle");
	anotherCircle->draw();
}
组件对应关系
  • Graphic → 抽象原型
  • Rectangle/Circle → 具体原型
  • GraphicManager → 原型管理器(可选组件)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值