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

8.原型模式(Prototype)

动机

在软件系统中,经常面临着某些结构复杂的对象的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。

之前的工厂方法和抽象工厂将抽象基类和具体的实现分开。原型模式也差不多,但是原型模式将抽象基类合并。

原型模式的应用场景

原型模式特别适用于以下场景:

  • 对象的创建过程比较复杂或耗时。
  • 需要动态创建对象,且对象的类型在运行时才能确定。
  • 需要避免重复初始化对象的开销。
#include <iostream>
#include <memory>
#include <string>

// 抽象类
class ISplitter {
public:
    virtual void split() = 0;
    virtual std::unique_ptr<ISplitter> clone() const = 0; // 返回一个智能指针
    virtual ~ISplitter() {}
};

// 二进制拆分器
class BinarySplitter : public ISplitter {
private:
    std::string data; // 假设这是需要拆分的二进制数据
public:
    BinarySplitter(const std::string& data) : data(data) {}

    void split() override {
        std::cout << "Splitting binary data: " << data << std::endl;
        // 具体的二进制拆分逻辑
    }

    std::unique_ptr<ISplitter> clone() const override {
        return std::make_unique<BinarySplitter>(*this); // 深拷贝
    }
};

// 文本拆分器
class TxtSplitter : public ISplitter {
private:
    std::string data; // 假设这是需要拆分的文本数据
public:
    TxtSplitter(const std::string& data) : data(data) {}

    void split() override {
        std::cout << "Splitting text data: " << data << std::endl;
        // 具体的文本拆分逻辑
    }

    std::unique_ptr<ISplitter> clone() const override {
        return std::make_unique<TxtSplitter>(*this); // 深拷贝
    }
};

// 使用示例
int main() {
    // 创建原始对象
    BinarySplitter binarySplitter("01010101");
    TxtSplitter txtSplitter("Hello, World!");

    // 克隆对象
    std::unique_ptr<ISplitter> binaryClone = binarySplitter.clone();
    std::unique_ptr<ISplitter> txtClone = txtSplitter.clone();

    // 使用克隆对象
    binaryClone->split();
    txtClone->split();

    return 0;
}

模式定义

使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。

什么时候使用原型,什么时候使用工厂最大的区分点就在于:用工厂方法创建对象是不是非常简单的几个步骤就可以把这个对象创建出来,还是说需要考虑对象很复杂的中间状态,然后又很希望保留这个中间状态,如果是后者的话就用原型。

要点总结

Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有稳定的接口。

Prototype模式对于“如何创建易变类”的实体对象“采用”原型克隆的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象–所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方Clone。

Prototype模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝。


http://www.kler.cn/a/530169.html

相关文章:

  • Python 网络爬虫实战:从基础到高级爬取技术
  • springboot 启动原理
  • 【DeepSeek】本地快速搭建DeepSeek
  • 【2025年最新版】Java JDK安装、环境配置教程 (图文非常详细)
  • 一文讲解Java中的ArrayList和LinkedList
  • Unity实现按键设置功能代码
  • 代码随想录算法训练营第十六天| 二叉树4
  • 【论文复现】基于Otsu方法的多阈值图像分割改进鲸鱼优化算法
  • LLMs之OpenAI o系列:OpenAI o3-mini的简介、安装和使用方法、案例应用之详细攻略
  • 【每天学习一点点】通过使用@property装饰器来创建一个属性的getter和setter方法
  • 【周易哲学】生辰八字入门讲解(八)
  • STM32 DMA数据转运
  • leetcode 930. 和相同的二元子数组
  • 【人工智能】使用Python和Hugging Face构建情感分析应用:从模型训练到Web部署
  • ASP.NET Core Filter
  • 一文讲解Java中HashMap的put流程
  • 完全卸载mysql server步骤
  • Unity游戏(Assault空对地打击)开发(3) 摄像机的控制
  • C# 精炼题18道题(类,三木运算,Switch,计算器)
  • DeepSeek与OpenAI:谁是AI领域的更优选择?
  • 04树 + 堆 + 优先队列 + 图(D1_树(D8_B*树(B*)))
  • 书生大模型实战营7
  • openmv的端口被拆分为两个 导致电脑无法访问openmv文件系统解决办法 openmv USB功能改动 openmv驱动被更改如何修复
  • 人工智能学习(四)之机器学习基本概念
  • work-stealing算法 ForkJoinPool
  • 【C语言】填空题/程序填空题1