23种设计模式 - 原型模式(Prototype)

原型模式(Prototype)------ 复制粘贴大法好

大白话解释

你在画图软件里画了一个图形(比如一个圆),

想再来几个一样的:

👉 不用重新画!

👉 直接 Ctrl + C / Ctrl + V

然后改个颜色、大小就行。

原型模式:通过复制(克隆)现有对象来创建新对象,而不是重新走一遍复杂的创建流程。

常见场景:

  • 游戏中批量生成相似的敌人(克隆模板怪)
  • 配置对象的复制(复制一份默认配置再修改)
  • 图形编辑器中复制图形元素

核心思路

  1. 定义克隆接口(clone() 方法)
  2. 具体类实现 clone(),返回自身的副本
  3. 需要新对象时,不 new 而是 clone()

C++ 代码示例

cpp 复制代码
#include <iostream>
#include <memory>
#include <vector>
#include <string>

// ==============================
// 原型基类:图形
// ==============================
class Shape {
public:
    virtual ~Shape() = default;

    int x = 0, y = 0;
    std::string color;

    virtual std::unique_ptr<Shape> clone() const = 0;
    virtual void draw() const = 0;
};

// ==============================
// 圆形
// ==============================
class Circle : public Shape {
public:
    int radius = 0;

    Circle(int x, int y, int r, const std::string& c) {
        this->x = x;
        this->y = y;
        this->radius = r;
        this->color = c;
    }

    std::unique_ptr<Shape> clone() const override {
        return std::make_unique<Circle>(*this); // 拷贝构造
    }

    void draw() const override {
        std::cout << "【圆】位置(" << x << "," << y 
                  << ") 半径:" << radius 
                  << " 颜色:" << color << "\n";
    }
};

// ==============================
// 矩形
// ==============================
class Rectangle : public Shape {
public:
    int width = 0;
    int height = 0;

    Rectangle(int x, int y, int w, int h, const std::string& c) {
        this->x = x;
        this->y = y;
        this->width = w;
        this->height = h;
        this->color = c;
    }

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

    void draw() const override {
        std::cout << "【矩形】位置(" << x << "," << y 
                  << ") 宽:" << width 
                  << " 高:" << height 
                  << " 颜色:" << color << "\n";
    }
};

int main() {
    // 创建一个原型(画好的图形)
    auto circle = std::make_unique<Circle>(10, 10, 5, "红色");

    std::cout << "=== 原始图形 ===\n";
    circle->draw();

    // ==============================
    // 复制图形(Ctrl + C / Ctrl + V)
    // ==============================
    std::cout << "\n=== 复制多个图形 ===\n";

    std::vector<std::unique_ptr<Shape>> shapes;

    for (int i = 0; i < 3; ++i) {
        auto copy = circle->clone(); // 克隆
        copy->x += i * 10;           // 改位置
        copy->color = "蓝色";        // 改颜色
        shapes.push_back(std::move(copy));
    }

    for (auto& s : shapes) {
        s->draw();
    }

    // ==============================
    // 不同图形也可以复制
    // ==============================
    std::cout << "\n=== 复制矩形 ===\n";
    auto rect = std::make_unique<Rectangle>(0, 0, 20, 10, "绿色");

    auto rectCopy = rect->clone();
    rectCopy->x = 50;
    rectCopy->color = "黄色";

    rect->draw();
    rectCopy->draw();

    return 0;
}

输出:

复制代码
=== 原始图形 ===
【圆】位置(10,10) 半径:5 颜色:红色

=== 复制多个图形 ===
【圆】位置(10,10) 半径:5 颜色:蓝色
【圆】位置(20,10) 半径:5 颜色:蓝色
【圆】位置(30,10) 半径:5 颜色:蓝色

=== 复制矩形 ===
【矩形】位置(0,0) 宽:20 高:10 颜色:绿色
【矩形】位置(50,0) 宽:20 高:10 颜色:黄色

浅拷贝 vs 深拷贝注意事项

cpp 复制代码
// ⚠️ 如果对象包含指针,必须实现深拷贝
class Node {
public:
    int value;
    int* data; // 指针成员!

    // 浅拷贝:两个对象共用同一块内存(危险!)
    // 深拷贝:克隆一份新的内存
    std::unique_ptr<Node> clone() const {
        auto newNode = std::make_unique<Node>();
        newNode->value = this->value;
        newNode->data = new int(*this->data); // 深拷贝指针
        return newNode;
    }
};

优缺点

说明
✅ 优点 避免重复的初始化代码,克隆比 new 更快
✅ 优点 可以在运行时动态生成对象
❌ 缺点 实现深拷贝比较麻烦,容易出 bug
❌ 缺点 循环引用的对象克隆很复杂

一句话记忆

原型模式 = 图形编辑器复制粘贴,克隆已有图形,改一改就能用。

相关推荐
绿豆人4 小时前
Go设计模式学习
学习·设计模式·golang
逮到647了6 小时前
23种设计模式简述
设计模式
爱吃烤鸡翅的酸菜鱼7 小时前
【Java】封装位运算通用工具类——用一个整数字段替代几十个布尔列,极致节省存储空间
java·开发语言·设计模式·工具类·位运算·合成复用原则
geovindu8 小时前
go: Model,Interface,DAL ,Factory,BLL using mysql
开发语言·mysql·设计模式·golang·软件构建
guojb8249 小时前
当 Vue 3 遇上桥接模式:手把手教你优雅剥离虚拟滚动的业务大泥球
vue.js·设计模式
我登哥MVP9 小时前
【Spring6笔记】 - 15 - Spring中的八大设计模式
java·spring boot·笔记·spring·设计模式·intellij-idea
无籽西瓜a10 小时前
【西瓜带你学设计模式 | 第十六期 - 迭代器模式】迭代器模式 —— 统一遍历实现、优缺点与适用场景
java·后端·设计模式·迭代器模式·软件工程
程序员小寒11 小时前
JavaScript设计模式(十):模板方法模式实现与应用
前端·javascript·设计模式·模板方法模式
likerhood11 小时前
关于三种工厂的设计模式总结
设计模式
榴莲omega11 小时前
第14天:React 工程化与设计模式
前端·react.js·设计模式