c++ 原型模式

文章目录

什么是原型模式

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象,简单理解就是"克隆指定对象"

为什么要使用原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而不是通过标准的构造函数来创建。在C++中使用原型模式有以下几个主要原因:

  • 避免重复的初始化代码:
    如果一个对象的初始化过程非常复杂且耗时,使用原型模式可以避免每次创建新对象时都重复执行这些初始化步骤。通过复制一个已经初始化好的对象,可以节省大量的时间和资源。
  • 动态创建对象:
    在某些情况下,你需要在运行时决定创建哪种类型的对象。原型模式允许你预先创建一些原型对象,然后在需要时通过复制这些原型来创建新对象,这样可以灵活地动态创建对象。
  • 隐藏对象创建的复杂性:
    原型模式可以将对象的创建过程封装起来,客户端代码不需要知道具体的创建细节。这有助于降低系统的耦合度,使得代码更加模块化和易于维护。
  • 支持对象的深拷贝:
    在C++中,默认的拷贝构造函数和赋值操作符只能进行浅拷贝。如果对象内部包含指针或其他资源,浅拷贝可能导致资源共享和潜在的内存问题。原型模式可以实现深拷贝,确保每个新对象都是独立的,避免资源共享的问题。

使用场景

c 复制代码
1. 游戏开发

在游戏中,经常需要创建大量的游戏对象,如敌人、道具等。如果每次创建这些对象都重新初始化,可能会导致性能问题。通过使用原型模式,可以先创建一个对象作为原型,然后在需要的时候通过克隆这个原型对象来生成新的实例,这样可以节省初始化的时间。
2. 报表系统

报表系统中往往需要生成大量的类似数据表格。如果每个表格都需要从头开始创建,则会消耗很多资源。通过使用原型模式,可以先创建一个基本的表格模板,然后根据需要克隆这个模板并填充不同的数据,从而快速生成多个表格实例。
3. GUI 应用

在图形用户界面(GUI)应用中,经常需要创建许多具有相同外观但内容不同的组件(如按钮、列表项)。使用原型模式可以让开发者仅需创建一个基础组件作为原型,之后可以通过克隆并修改这个原型来创建新的组件实例。
4. 数据库操作

在数据库操作中,有时候需要批量插入数据或者更新记录。如果每次操作都需要重新构建对象,则效率低下。可以先构建一个数据对象作为原型,然后通过克隆这个对象并修改特定字段值来创建新的数据对象,从而优化数据库操作。
5. 测试环境

在软件测试中,尤其是单元测试和集成测试时,经常需要构造测试数据。如果直接创建测试数据对象比较耗时,可以采用原型模式来预先创建一个或几个完整的测试数据对象作为原型,然后通过复制这些原型来快速生成所需的测试数据。
6. 内存受限环境

在某些内存受限的环境中,比如嵌入式系统,频繁地创建和销毁对象会带来较大的开销。通过原型模式可以有效地减少内存分配和回收的操作,从而优化系统的性能。

示例

c 复制代码
#include <iostream>
#include <vector>

// 抽象基类 Shape
class Shape {
public:
    virtual ~Shape() {}
    virtual Shape* clone() const = 0;
    virtual void draw() const = 0;
};

// Rectangle 类
class Rectangle : public Shape {
    int width, height;
public:
    Rectangle(int w, int h) : width(w), height(h) {}
    Shape* clone() const {
        return new Rectangle(*this); // 深拷贝
    }
    void draw() const {
        std::cout << "Drawing Rectangle with width: " << width << " and height: " << height << std::endl;
    }
};

// Circle 类
class Circle : public Shape {
    int radius;
public:
    Circle(int r) : radius(r) {}
    Shape* clone() const {
        return new Circle(*this); // 深拷贝
    }
    void draw() const {
        std::cout << "Drawing Circle with radius: " << radius << std::endl;
    }
};

// 测试函数
void testPrototypePattern() {
    Shape* rect = new Rectangle(5, 10);
    Shape* circle = new Circle(7);

    // 克隆并绘制
    Shape* clonedRect = rect->clone();
    Shape* clonedCircle = circle->clone();

    clonedRect->draw();
    clonedCircle->draw();

    // 释放内存
    delete rect;
    delete circle;
    delete clonedRect;
    delete clonedCircle;
}

int main() {
    testPrototypePattern();
    return 0;
}

优点

  • 如果创建新的对象比较复杂,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
  • 简化对象的创建,无需理会创建过程。
  • 可以在程序运行时(对象属性发生了变化)获得一份内容相同的实例,他们之间不会相互干扰

缺点

  • 每一个类都必须配备一个克隆方法,对于已有的没有克隆方法的类来说是致命的。
相关推荐
kolyle6 分钟前
万级 QPS 下的 Token 分发系统架构:从 0 到 1 跑通 AI 时代的“水电煤“
开发语言·人工智能·系统架构·token·qps·极智词元·大模型私有化部署
caoerzhong19 分钟前
JeeWMS 开源仓库管理系统 GPL-3.0 合规指南:Java WMS 二次开发前必须弄清的授权边界
java·开发语言·开源·vue
Patrick在香港19 分钟前
Python 审计香港开放数据目录:两个端点差 10 倍,只有 9.3% 的资源标了「最后修改时间」
开发语言·数据库·python·数据分析·api·数据治理·开放数据
Sylvia33.1 小时前
火星数据体育API|一站式接入足球篮球电竞等18+项目实时数据
java·开发语言·python·websocket·游戏
Data_Journal1 小时前
使用 AutoScraper 进行网页抓取:分步教程
大数据·开发语言·数据库·python·scrapy
yume_sibai1 小时前
12-Rust 性能优化指南(性能分析 + 内存优化 + SIMD + 并发优化 + 编译器优化 + 基准测试)
开发语言·性能优化·rust
萧瑟余晖2 小时前
Hibernate 核心原理与架构详解
开发语言·架构·hibernate
爱喝水的鱼丶2 小时前
SAP-ABAP:SAP MM 模块物料主数据批量导入与增强开发:字段扩展、校验逻辑与批量导入工具开发
开发语言·性能优化·sap·abap·增强·经验交流·mm
geovindu2 小时前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
白远山2 小时前
健身场馆无人自动化解决方案:从架构到落地实践
java·开发语言·数据库·数据挖掘·需求分析