设计模式之原型模式(C++)

简介: 设计模式之原型模式(C++)

一、原型模式是什么?

      原型模式是一种创建型的软件设计模式,通俗的来讲就是复制粘贴。


      通过一个原型对象,快速地创建出多个一致的对象,并对其进行相关的操作。比如文件夹中存放了一个Word文件,你把文件复制了一个副本出来,原件不动,对副本进行修改以达到自己的目的。原型像是一个模板,你可以基于它复制好多对象,而复制出来的副本产生任何变化都不会影响到原型(注意:前提是clone的实现要满足深拷贝)。


      原型模式的优点:

  1. 便捷、简洁、高效。不需要考虑对象的复杂程度,只需要复制即可。
  2. 无需初始化。可动态地获取当前原型的状态,并在当前基础上进行拷贝。
  3. 允许动态增加或减少产品类。

     原型模式的缺点:

  1. 每个类都需要配备一个clone函数,若对已有的类进行改造,需要修改其源码,违背了开闭原则。

二、原型模式

2.1 结构图

      客户端即Main主函数,可基于原型提供的clone方法,拷贝多个对象。

2.2 代码示例

      场景描述:我创建了一个Word文件,对其进行复制粘贴,得到多个副本文件。

//Product.h
/****************************************************/
#pragma once
#include <iostream>
using namespace std;
// 内容类
class Content
{
public:
  // 显式构造函数
  explicit Content(string input) :m_text(input) {};
  // 析构函数
  ~Content() {}
  // 设置内容
  void setText(string input) {
    m_text = input;
  }
  // 获取内容
  string getText() {
    return m_text;
  }
private:
  string m_text;                                       // 文本内容
};
// 抽象文件类
class File
{
public:
  // 构造函数
  File(string name) :m_name(name) {
    m_content = nullptr;
  };
  // 析构函数
  virtual ~File() {
    if (m_content != nullptr) {
      cout << "  内容地址:" << m_content << endl;
      delete m_content;
      m_content = nullptr;
    }
  };
  // 添加内容
  void setContent(string input) {
    if (m_content == nullptr) {
      m_content = new Content(input);
    }
    else {
      m_content->setText(input);
    }
  }
  // 输出内容
  string getContent() {
    if (m_content == nullptr) {
      return "";
    }
    else {
      return m_content->getText();
    }
  }
  // 拷贝函数
  virtual File* clone() = 0;
protected:
  string m_name;                                       // 文件名字
  Content *m_content;                                  // 内容
};
// Word文件类(具体)
class WordFile :public File
{
public:
  // 构造函数
  WordFile(string name) :File(name) {
    cout << " Word文件类构造,名为:" << name << endl;
  };
  // 析构函数
  virtual ~WordFile() {
    cout << " Word文件类析构。" << endl;
  };
  // 拷贝构造函数
  WordFile(const WordFile& file) : File(file) {
    m_name = file.m_name;
    cout << " Word文件类拷贝构造,名为:" << m_name << endl;
    if (file.m_content != nullptr) {
      m_content = new Content(file.m_content->getText());
    }
    else {
      m_content = nullptr;
    } 
  }
  // 克隆
  virtual File* clone() {
    return new WordFile(*this);
  }
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Product.h"
using namespace std;
int main()
{
  cout << "创建文件1。" << endl;
  File* file1 = new WordFile("test");
  file1->setContent("今天天气真好!");
  cout << "克隆文件1,生成文件2。" << endl;
  File* file2 = file1->clone();
  file2->setContent("肚子饿了。。。");
  cout << "删除文件1。" << endl;
  delete file1;
  cout << "克隆文件2,生成文件3。" << endl;
  File* file3 = file2->clone();
  cout << "文件3的内容是:" << file3->getContent() << endl;
  cout << "删除文件3。" << endl;
  delete file3;
  cout << "删除文件2。" << endl;
  delete file2;
  return 0;
}

 程序结果如下。

      在上述示例中,我们可以看到,除了抽象原型和具体原型,我还创建了一个内容类,并在原型中放入了一个它的指针,这样做是为了让大家直观地看看深拷贝和浅拷贝的区别。原型中的普通变量一般是浅拷贝,通过值传递完成,而指针如果通过new申请了空间,那么拷贝的对象中对应的指针则需要重新new,不然两个指针指向同一地址,若原型进行了析构,那么复制品再次析构时,就会对已经释放过的空间再次释放,进而引起崩溃。

三、总结

      我尽可能用较通俗的话语和直观的代码例程,来表述我对原型模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解原型模式。

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
2月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
65 0
|
17天前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
20天前
|
设计模式 Java
【设计模式系列笔记】原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,其主要目的是通过复制现有对象来创建新对象,而无需知道其具体类型。这种模式属于对象创建型模式,通过克隆来避免使用new关键字创建对象,提高性能和降低系统的耦合度。
32 6
|
29天前
|
设计模式 Java
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式
|
1月前
|
设计模式 Java
23种设计模式,原型模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新的对象,而无需知道如何创建的细节。这种模式的核心思想是基于一个原型实例,通过复制这个原型来创建新的对象
25 7
|
2月前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
126 1
|
2月前
|
设计模式 机器学习/深度学习 算法
C++设计模式新篇章:掌握状态委托
C++设计模式新篇章:掌握状态委托
75 0
|
2月前
|
设计模式 算法 C++
从 C++ 优化状态机实现:结合设计模式的实用指南
从 C++ 优化状态机实现:结合设计模式的实用指南
69 1
|
2月前
|
设计模式 存储 安全
C++多线程管理的艺术:从基础到设计模式
C++多线程管理的艺术:从基础到设计模式
67 0
|
2月前
|
设计模式 缓存 编译器
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
68 0