创建型模式-Prototype 模式(原型模式)

news/2025/2/23 23:20:00

原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,通过复制现有对象来创建新对象,避免了重复创建对象的开销‌。原型模式的核心在于通过复制现有的实例对象来生成新的实例对象,从而提升效率。‌

场景假设:需要创建复杂配置的仪器连接对象(含IP、端口、校验配置等)

1. 不使用原型模式(直接构造新对象)

class DeviceConnection {
private:
    string ip;
    int port;
    vector<uint8_t> configData; // 大型配置数据
public:
    // 复杂构造函数(模拟耗时操作)
    DeviceConnection(string ip, int port) : ip(ip), port(port) {
        // 模拟耗时配置加载(从文件/数据库读取)
        this->configData.resize(1024*1024); // 1MB数据
        std::iota(configData.begin(), configData.end(), 0);
    }

    void setValidation(bool enable) { /*...*/ }
    void print() { cout << ip << ":" << port << endl; }
};

// 客户端代码
DeviceConnection conn1("192.168.1.10", 5025); // 耗时构造
DeviceConnection conn2 = conn1; // 仅浅拷贝(危险!)
conn2.setValidation(true);      // 修改会影响conn1吗?

缺点分析:

  1. 重复初始化成本:每个新对象都要执行完整的构造函数逻辑
  2. 浅拷贝风险:默认拷贝构造函数导致configData内存共享
  3. 配置同步问题:修改一个对象的配置不会影响另一个(但共享数据会出问题)

2. 使用原型模式(显式克隆)// 基类实现克隆接口

class ICloneable {
public:
    virtual unique_ptr<ICloneable> clone() const = 0;
    virtual ~ICloneable() = default;
};

class DeviceConnection : public ICloneable {
private:
    string ip;
    int port;
    vector<uint8_t> configData;
public:
    // 原型对象构造(仅首次需要耗时)
    DeviceConnection(string ip, int port) : ip(ip), port(port) {
        this->configData.resize(1024*1024);
        std::iota(configData.begin(), configData.end(), 0);
    }

    // 实现深拷贝克隆
    unique_ptr<ICloneable> clone() const override {
        auto newObj = make_unique<DeviceConnection>(*this);
        newObj->configData = this->configData; // 显式深拷贝
        return newObj;
    }

    void setIP(string newIP) { ip = newIP; }
    void print() { cout << ip << ":" << port << endl; }
};

// 客户端代码
auto prototype = make_unique<DeviceConnection>("192.168.1.10", 5025);

// 快速克隆已有配置
auto conn1 = prototype->clone();
dynamic_cast<DeviceConnection*>(conn1.get())->setIP("192.168.1.11");

auto conn2 = prototype->clone();
dynamic_cast<DeviceConnection*>(conn2.get())->setIP("192.168.1.12");

缺点分析:

  1. 类型转换开销:需要dynamic_cast处理具体类型
  2. 内存消耗:克隆大型对象时需要复制全部数据
  3. 接口约束:必须继承ICloneable接口

关键对比表格:

特性原型模式不用原型模式
对象创建速度✅ 快速克隆(避开构造函数)❌ 每次完整构造
内存效率❌ 可能重复存储相同数据✅ 仅保留必要数据
对象状态一致性✅ 确保初始状态一致❌ 依赖构造函数正确性
代码复杂度❌ 需实现克隆接口✅ 直接使用默认构造
多态支持✅ 支持异构对象克隆❌ 只能创建同类对象
配置修改安全性✅ 独立内存空间❌ 默认浅拷贝风险

工程建议:

// 最佳实践:结合工厂模式管理原型
class DeviceFactory {
private:
    static unordered_map<DeviceType, unique_ptr<DeviceConnection>> prototypes;
public:
    static void init() {
        prototypes[DeviceType::SCOPE] = 
            make_unique<DeviceConnection>("192.168.1.100", 5025);
        // 其他设备类型初始化...
    }

    static unique_ptr<DeviceConnection> create(DeviceType type) {
        return prototypes[type]->clone();
    }
};

适用场景建议:

•优先使用原型模式:当对象初始化成本 > 克隆成本时
•避免使用原型模式:当对象简单或需要完全独立初始化时


http://www.niftyadmin.cn/n/5863856.html

相关文章

GStreamer源码安装1.24版本

从官网下载 1.24的源码包 https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/1.24?ref_typeheads#getting-started &#xff0c;尝试过使用git clone 的方式&#xff0c;但速度贼慢&#xff0c;就选择了下载源码包的方式安装依赖 sudo apt install libssl-dev g me…

【Leetcode 每日一题】2506. 统计相似字符串对的数目

问题背景 给你一个下标从 0 0 0 开始的字符串数组 w o r d s words words。 如果两个字符串由相同的字符组成&#xff0c;则认为这两个字符串 相似 。 例如&#xff0c;“abca” 和 “cba” 相似&#xff0c;因为它们都由字符 ‘a’、‘b’、‘c’ 组成。然而&#xff0c;“…

八大排序算法(1)插入排序-直接插入排序 和 希尔排序

直接插入排序&#xff08;Insertion Sort&#xff09; 直接插入排序是最基本的插入排序算法&#xff0c;工作原理如下&#xff1a; 从第二个元素开始&#xff0c;将其与前面已经排好序的部分进行比较。 找到合适的位置后&#xff0c;将该元素插入到合适的位置&#xff0c;同…

【20250221更新】WebStorm2024.3.3版本安装+使用方法

1、官网下载正版WebStorm&#xff0c;链接如下 Thank you for downloading WebStorm! 2、获取使用教程&#xff0c;给博主留言【压缩包有密码&#xff0c;见下面】 通过百度网盘分享的文件&#xff1a;【2025022… 链接:https://pan.baidu.com/s/1UMMEDKbRwlGcffAhOlwR5g?pw…

华为guass在dbever和springboot配置操作

下面记录华为guass在dbever和springboot配置操作&#xff0c;以备忘。 1、安装dbeaver-ce-23.2.0-x86_64-setup.exe和驱动程序 Download | DBeaver Community 2、配置高斯数据库驱动 3、新建数据库连接 4、操作指引 opengauss官方文档 https://docs-opengauss.osinfra.cn/zh…

商业航天级微控制器单元(MCU)技术特征分析

在商业航天及特种工业控制领域&#xff0c;微控制器单元&#xff08;MCU&#xff09;的抗辐射性能与系统可靠性直接关系到设备在极端环境下的运行效能。国科安芯AS32S601系列MCU基于自主RISC-V架构&#xff0c;其180MHz(AS32S601)的工作频率与抗辐射加固设计&#xff0c;为航天…

C++跨平台开发:策略与实践在软件开发领域

在软件开发领域&#xff0c;跨平台能力意味着一个应用程序可以在不同的操作系统上运行&#xff0c;无需针对每个平台单独编写代码。C作为一种强大的编程语言&#xff0c;因其高效性和灵活性&#xff0c;在跨平台开发领域有着广泛的应用。本文将探讨C跨平台开发的关键策略与实践…

【操作幂等和数据一致性】保障业务在MySQL和COS对象存储的一致

业务场景 发布信息&#xff0c;更新到数据库MySQLCOS操作&#xff0c;更新JSON文件 不过可能存在幂等性和数据一致性的问题。 // 批量存MySQL entityPublishService.saveOrUpdateBatch(entityPublishList); // 遍历批量存COS对象存储searchEntitys.forEach(req -> {//删除…