当前位置: 首页 > ds >正文

设计模式 八:原型模式 (Prototype Pattern)

动机(Motivation)

1、在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
2、如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?

解决方法:使用原型模式

原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而不是通过构造函数创建。 

基本概念

原型模式的核心思想是:

  • 创建一个原型接口,声明克隆方法

  • 具体类实现这个接口并提供克隆自身的能力

  • 客户端通过请求原型对象克隆自身来创建新对象

实现方式

1. 基本实现

#include <iostream>
#include <memory>// 原型基类
class Prototype {
public:virtual ~Prototype() = default;virtual std::unique_ptr<Prototype> clone() const = 0;virtual void print() const = 0;
};// 具体原型类
class ConcretePrototype : public Prototype {
public:ConcretePrototype(int value) : value_(value) {}// 复制构造函数实现克隆std::unique_ptr<Prototype> clone() const override {return std::make_unique<ConcretePrototype>(*this);}void print() const override {std::cout << "ConcretePrototype with value: " << value_ << std::endl;}void setValue(int value) {value_ = value;}private:int value_;
};int main() {// 创建原型对象auto prototype = std::make_unique<ConcretePrototype>(10);// 克隆对象auto clone1 = prototype->clone();auto clone2 = prototype->clone();// 修改克隆对象dynamic_cast<ConcretePrototype*>(clone1.get())->setValue(20);dynamic_cast<ConcretePrototype*>(clone2.get())->setValue(30);// 输出结果prototype->print();  // 输出: ConcretePrototype with value: 10clone1->print();     // 输出: ConcretePrototype with value: 20clone2->print();     // 输出: ConcretePrototype with value: 30return 0;
}

2. 使用原型管理器

#include <iostream>
#include <memory>
#include <unordered_map>class Prototype {
public:virtual ~Prototype() = default;virtual std::unique_ptr<Prototype> clone() const = 0;virtual void print() const = 0;
};class ConcretePrototypeA : public Prototype {
public:ConcretePrototypeA(int value) : value_(value) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<ConcretePrototypeA>(*this);}void print() const override {std::cout << "ConcretePrototypeA with value: " << value_ << std::endl;}private:int value_;
};class ConcretePrototypeB : public Prototype {
public:ConcretePrototypeB(std::string str) : str_(std::move(str)) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<ConcretePrototypeB>(*this);}void print() const override {std::cout << "ConcretePrototypeB with string: " << str_ << std::endl;}private:std::string str_;
};class PrototypeManager {
public:void registerPrototype(const std::string& key, std::unique_ptr<Prototype> prototype) {prototypes_[key] = std::move(prototype);}std::unique_ptr<Prototype> create(const std::string& key) {if (prototypes_.find(key) != prototypes_.end()) {return prototypes_[key]->clone();}return nullptr;}private:std::unordered_map<std::string, std::unique_ptr<Prototype>> prototypes_;
};int main() {PrototypeManager manager;// 注册原型manager.registerPrototype("A", std::make_unique<ConcretePrototypeA>(100));manager.registerPrototype("B", std::make_unique<ConcretePrototypeB>("Hello"));// 从原型创建对象auto obj1 = manager.create("A");auto obj2 = manager.create("B");auto obj3 = manager.create("A");if (obj1) obj1->print();  // 输出: ConcretePrototypeA with value: 100if (obj2) obj2->print();  // 输出: ConcretePrototypeB with string: Helloif (obj3) obj3->print();  // 输出: ConcretePrototypeA with value: 100return 0;
}

 UML结构

 

原型模式的优点

  1. 减少子类数量:不需要为每种对象创建专门的子类

  2. 动态配置应用:可以在运行时添加或删除原型

  3. 简化对象创建:特别是当对象初始化过程复杂时

  4. 性能优化:克隆通常比新建对象更高效

适用场景

  1. 当系统需要独立于其产品的创建、组合和表示时

  2. 当要实例化的类是在运行时指定时

  3. 当需要避免建立与产品类层次平行的工厂类层次时

  4. 当一个类的实例只能有几个不同状态组合中的一种时

注意事项

  1. 深拷贝与浅拷贝问题:确保克隆操作正确地复制了所有成员变量

  2. 对于包含循环引用的对象,需要特别处理克隆逻辑

  3. 原型模式可能隐藏了对象的创建细节,使代码更难理解

原型模式在C++中特别有用,因为它可以利用拷贝构造函数和赋值操作符来实现克隆操作,同时结合智能指针可以很好地管理内存。

http://www.xdnf.cn/news/16233.html

相关文章:

  • .NET-键控服务依赖注入
  • LeetCode|Day23|326. 3 的幂|Python刷题笔记
  • 认识Transformer架构
  • 第十讲:stack、queue、priority_queue以及deque
  • 【力扣】第15题:三数之和
  • C# 继承 虚方法
  • idea部署新项目时,用自定义的maven出现的问题解决
  • QMC5883L 坐标系Z轴是垂直于芯片平面向下(芯片朝上时指向地面)还是垂直于芯片平面向上(芯片朝上时指向天空)
  • Qt内存管理的核心点
  • 游戏盾 在线游戏的终极防护屏障
  • 【2025目标检测】最新论文
  • 2025年Zigbee技术白皮书:全球物联网无线通信的关键创新
  • 深度学习的Logits:logist 是什么,上一维度的隐藏向量怎么获取
  • 基于GitHub的Terraform自动化管理最佳实践
  • rust嵌入式开发零基础入门教程(四)
  • 第一章:Go语言基础入门之Hello World与Go程序结构
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-微博点赞量Top6实现
  • Https以及CA证书
  • 基于php的校园招聘平台
  • SpringCloud seata全局事务
  • Matlab学习笔记:逻辑基础
  • 【数学建模 | Matlab】二维绘图 和 三维绘图
  • CLI 与 IDE 编码代理比较:提升开发效率的两种路径
  • 使用Docker搭建SearXNG搜索引擎
  • 直播一体机技术方案解析:基于RK3588S的硬件架构特性​
  • 地理类专业选择指南:地理科学/测绘工程/遥感科学与技术
  • 基于LNMP分布式个人云存储
  • Docker详解及实战
  • 274款古装人物头像
  • 20250704-基于强化学习在云计算环境中的虚拟机资源调度研究