原型模式 (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→ 原型管理器(可选组件)
1419

被折叠的 条评论
为什么被折叠?



