设计模式之原型模式(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,不然两个指针指向同一地址,若原型进行了析构,那么复制品再次析构时,就会对已经释放过的空间再次释放,进而引起崩溃。

三、总结

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

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

相关文章
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
3月前
|
设计模式 Java
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
|
5月前
|
设计模式
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
|
5月前
|
设计模式 C++
C++一分钟之-设计模式:工厂模式与抽象工厂
【7月更文挑战第14天】设计模式是解决软件设计问题的通用方案。工厂模式与抽象工厂模式是创建型模式,用于对象创建而不暴露创建逻辑。工厂模式推迟实例化到子类,但过度使用会增加复杂性。抽象工厂则创建相关对象族,但过度抽象可能造成不必要的复杂度。两者均应按需使用,确保设计灵活性。代码示例展示了C++中如何实现这两种模式。
47 3
|
5月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
65 2
|
5月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
53 6
|
7月前
|
设计模式 开发框架 算法
C++中的设计模式:基本概念与应用
C++中的设计模式:基本概念与应用
72 2
|
6月前
|
设计模式 Java
Java设计模式之原型模式详解
Java设计模式之原型模式详解
|
6月前
|
设计模式
原型模式-大话设计模式
原型模式-大话设计模式
|
6月前
|
设计模式 Java Spring
设计模式——原型模式
设计模式——原型模式

热门文章

最新文章

  • 1
    设计模式转型:从传统同步到Python协程异步编程的实践与思考
    59
  • 2
    C++一分钟之-设计模式:工厂模式与抽象工厂
    47
  • 3
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    54
  • 4
    C++一分钟之-C++中的设计模式:单例模式
    65
  • 5
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    43
  • 6
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    70
  • 7
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    62
  • 8
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    43
  • 9
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    52
  • 10
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    121