C++实现设计模式---原型模式 (Prototype)

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

原型模式 (Prototype)

原型模式 是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化。

意图



  • 利用原型实例指定要创建的对象类型,并通过复制该原型来天生新对象。
  • 提供一种高效创建对象的方式,尤其是当对象的创建成本较高时。

利用场景


  • 对象创建成本高

    • 如果直接实例化对象开销较大(如对象初始化需要大量资源),可以通过克隆已存在的对象快速天生新实例。

  • 复杂对象需要重复创建

    • 当对象的结构较复杂,需要创建多个相似对象时。

  • 制止直接依赖具体类

    • 原型模式通过复制实例而不是直接依赖构造函数,可以减少对具体类的依赖。


到场者角色


  • 原型接口 (Prototype)

    • 界说一个克隆方法,用于复制对象。

  • 具体原型 (Concrete Prototype)

    • 实现原型接口,界说克隆方法,返回当前实例的复成品。

  • 客户端 (Client)

    • 利用原型接口创建新对象,而不直接依赖具体类。


示例代码

以下示例展示了如何利用原型模式创建几种不同类型的图形对象。
  1. #include <iostream>
  2. #include <memory>
  3. #include <string>
  4. // 原型接口
  5. class Shape {
  6. public:
  7.     virtual ~Shape() {}
  8.     virtual std::unique_ptr<Shape> clone() const = 0;
  9.     virtual void draw() const = 0;
  10. };
  11. // 具体原型:圆形
  12. class Circle : public Shape {
  13. private:
  14.     int radius;
  15. public:
  16.     Circle(int r) : radius(r) {}
  17.     // 实现克隆方法
  18.     std::unique_ptr<Shape> clone() const override {
  19.         return std::make_unique<Circle>(*this);
  20.     }
  21.     void draw() const override {
  22.         std::cout << "Drawing a Circle with radius: " << radius << std::endl;
  23.     }
  24. };
  25. // 具体原型:矩形
  26. class Rectangle : public Shape {
  27. private:
  28.     int width, height;
  29. public:
  30.     Rectangle(int w, int h) : width(w), height(h) {}
  31.     // 实现克隆方法
  32.     std::unique_ptr<Shape> clone() const override {
  33.         return std::make_unique<Rectangle>(*this);
  34.     }
  35.     void draw() const override {
  36.         std::cout << "Drawing a Rectangle with width: " << width
  37.                   << " and height: " << height << std::endl;
  38.     }
  39. };
  40. // 客户端代码
  41. int main() {
  42.     // 创建具体原型
  43.     std::unique_ptr<Shape> circlePrototype = std::make_unique<Circle>(10);
  44.     std::unique_ptr<Shape> rectanglePrototype = std::make_unique<Rectangle>(20, 30);
  45.     // 克隆原型
  46.     auto circle1 = circlePrototype->clone();
  47.     auto circle2 = circlePrototype->clone();
  48.     auto rectangle1 = rectanglePrototype->clone();
  49.     // 使用克隆对象
  50.     circle1->draw(); // 输出:Drawing a Circle with radius: 10
  51.     circle2->draw(); // 输出:Drawing a Circle with radius: 10
  52.     rectangle1->draw(); // 输出:Drawing a Rectangle with width: 20 and height: 30
  53.     return 0;
  54. }
复制代码

代码解析

1. 原型接口



  • 界说了 clone() 方法,用于创建当前对象的副本:
  1. virtual std::unique_ptr<Shape> clone() const = 0;
复制代码
2. 具体原型类



  • Circle 和 Rectangle 是具体原型类,分别实现了 clone() 方法,返回自身的副本:
  1. std::unique_ptr<Shape> clone() const override {
  2.     return std::make_unique<Circle>(*this);
  3. }
复制代码
3. 客户端



  • 客户端通过调用 clone() 方法创建对象,而无需直接依赖具体类:
  1. auto circle1 = circlePrototype->clone();
  2. circle1->draw();
复制代码

优缺点

长处


  • 对象复制高效

    • 直接复制对象比重新实例化速度更快。

  • 减少依赖

    • 客户端代码无需依赖具体类的构造函数。

  • 动态创建对象

    • 可在运行时动态天生对象,而不是在编译时确定。

缺点


  • 深拷贝复杂性

    • 如果对象中包罗指针或其他复杂资源,需特别留意深拷贝逻辑。

  • 实现复杂

    • 需要为每个类实现 clone() 方法,增长了一定的代码量。


实用场景



  • 需要大量相似对象:如图形编辑器中需要重复创建雷同图形。
  • 对象初始化成本高:如大型游戏中加载模子、地图等资源。
  • 需要动态天生对象:如根据设置文件动态天生对象。

改进与扩展


  • 深拷贝支持

    • 如果对象包罗动态内存或指针成员变量,需要实现深拷贝以制止资源共享题目。

  • 结合原型注册表

    • 利用注册表保存全部原型实例,根据名称或类型动态克隆对象:
    1. class PrototypeRegistry {
    2. private:
    3.     std::unordered_map<std::string, std::unique_ptr<Shape>> prototypes;
    4. public:
    5.     void registerPrototype(const std::string& name, std::unique_ptr<Shape> prototype) {
    6.         prototypes[name] = std::move(prototype);
    7.     }
    8.     std::unique_ptr<Shape> create(const std::string& name) const {
    9.         return prototypes.at(name)->clone();
    10.     }
    11. };
    复制代码


总结

原型模式通过复制已有对象来快速创建新对象,制止了复杂的初始化逻辑,并减少了对具体类的依赖。
它实用于需要动态天生大量相似对象或高效创建对象的场景。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表