[大话设计模式C++版] 第9章 简历复印 —— 原型模式

2023-11-04

源码可以在这里找到 大话设计模式C++版

简历代码初步实现

写一个简历类,必须要有姓名,可以设置性别和年龄,可以设置工作经历,客户端实例化三份简历

//main.cpp
#include <iostream>

using namespace std;

class Resume {
private:
    string m_name;
    string m_sex;
    string m_age;
    string m_timeArea;
    string m_company;
public:
    Resume(string name) {
        m_name = name;
    }
    void SetPersonalInfo(string sex, string age) {
        m_sex = sex;
        m_age = age;
    }
    void SetWorkExperience(string timeArea, string company) {
        m_timeArea = timeArea;
        m_company = company;
    }
    void Display() {
        cout << m_name << " " << m_sex << " " << m_age << endl;
        cout << "工作经历: " << m_timeArea << " " << m_company << endl;
    }
};

int main(int argc, char *argv[])
{
    Resume* a = new Resume("大鸟");
    a->SetPersonalInfo("男", "29");
    a->SetWorkExperience("1998-2000", "XX公司");

    Resume* b = new Resume("大鸟");
    b->SetPersonalInfo("男", "29");
    b->SetWorkExperience("1998-2000", "XX公司");

    Resume* c = new Resume("大鸟");
    c->SetPersonalInfo("男", "29");
    c->SetWorkExperience("1998-2000", "XX公司");

    a->Display();
    b->Display();
    c->Display();

    return 0;
}

每次实例化对象时,都需要给对象传入初始值,十分麻烦。虽然C++可以用拷贝构造函数用现有对象实例化新的对象,但是这样的代码违背了 依赖倒转原则,原型模式可以解决此类问题。

简历的原型实现

//main.cpp
#include <iostream>

using namespace std;

class IResume {
protected:
    string m_name;
    string m_sex;
    string m_age;
    string m_timeArea;
    string m_company;
public:
    virtual IResume* clone() = 0;
    virtual void SetPersonalInfo(string sex, string age) = 0;
    virtual void SetWorkExperience(string timeArea, string company) = 0;
    virtual void Display() = 0;
    virtual ~IResume() {}
};

class Resume : public IResume {
public:
    Resume(string name) {
        m_name = name;
    }
    Resume(const Resume& src) {  //其实这里浅拷贝就够了,无需自定有拷贝构造函数
        m_name = src.m_name;
        m_sex = src.m_sex;
        m_age = src.m_age;
        m_timeArea = src.m_timeArea;
        m_company = src.m_company;
    }
    IResume* clone() {
        return new Resume(*this);
    }
    void SetPersonalInfo(string sex, string age) {
        m_sex = sex;
        m_age = age;
    }
    void SetWorkExperience(string timeArea, string company) {
        m_timeArea = timeArea;
        m_company = company;
    }
    void Display() {
        cout << m_name << " " << m_sex << " " << m_age << endl;
        cout << "工作经历: " << m_timeArea << " " << m_company << endl;
    }
};

int main(int argc, char *argv[])
{
    IResume* a = new Resume("大鸟");
    a->SetPersonalInfo("男", "29");
    a->SetWorkExperience("1998-2000", "XX公司");
    IResume* b = a->clone();
    b->SetPersonalInfo("男", "24");
    IResume* c = a->clone();
    c->SetWorkExperience("1998-2006", "YY公司");

    a->Display();
    b->Display();
    c->Display();

    return 0;
}

Prototype原型模式 [李建忠C++笔记]

  • 通过“对象创建”模式绕开 new ,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
  • 典型模式
    • Factory Method
    • Abstract Factory
    • Prototype
    • Builder

动机(Motivation)

  • 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
  • 如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
//ISplitterPrototype.h
//原型类
class ISplitter {
public:
    virtual void split() = 0;
    virtual ISplitter* clone() = 0;  //通过克隆自己来创建对象
    virtual ~ISplitter() {}
};
//Splitter.h
#include "ISplitterPrototype.h"
//具体类
class BinarySplitter : public ISplitter {
public:
    virtual void split() {}
    virtual ISplitter* clone() {
        return new BinarySplitter(*this);  //通过拷贝构造函数克隆
    }
};

class TxtSplitter : public ISplitter {
public:
    virtual void split() {}
    virtual ISplitter* clone() {
        return new TxtSplitter(*this);  //通过拷贝构造函数克隆
    }
};

class PictureSplitter : public ISplitter {
public:
    virtual void split() {}
    virtual ISplitter* clone() {
        return new PictureSplitter(*this);  //通过拷贝构造函数克隆
    }
};

class VideoSplitter : public ISplitter {
public:
    virtual void split() {}
    virtual ISplitter* clone() {
        return new VideoSplitter(*this);  //通过拷贝构造函数克隆
    }
};
//MainForm.cpp
#include "ISplitterPrototype.h"

class MainForm : public Form {
    ISplitter* prototype;  //原型对象
public:
    MainForm(ISplitter* prototype) {
        this->prototype = prototype;
    }
    void Button1_Click() {
        ISplitter* splitter = this->prototype->clone();  //克隆原型
        splitter->split();
    }
};

模式定义

使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。——《设计模式》GoF

在这里插入图片描述

要点总结

  • Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
  • Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方Clone
  • Prototype模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[大话设计模式C++版] 第9章 简历复印 —— 原型模式 的相关文章

随机推荐

  • C++语言基础--递归函数

    对于很多编程初学者来说 递归算法是学习语言的最大障碍之一 可能也有一大部分人知道递归 也能看的懂递归 但在实际做题过程中 却不知道怎么使用 递归的定义 1 很官方的说法 递归 在数学与计算机科学中 是指在函数的定义中使用函数自身的方法 也就
  • 机器学习集成模型学习——Boosting集成学习(四)

    Boosting Boosting模型是线性训练的 后面的模型会纠结于前一个模型预测错的部分 然后尝试把它修正 步骤如下 第一个模型用一部分训练集训练 得出这部分训练集上的错误点 错误的数据会有更大的概率被后续的模型选择 第二个模型再拿一部
  • Unbiased Teacher v2: Semi-supervised Object Detection for Anchor-free and Anchor-based Detectors

    摘要 随着最近半监督目标检测 SS OD 技术的发展 目标检测器可以通过使用有限的标记数据和丰富的未标记数据来改进 然而 仍有两个挑战没有解决 1 在无锚检测器上没有先期的SS OD工作 2 在伪标签边界框回归时 先期工作是无效的 在本文中
  • webpack学习

    前端工程化具体的解决方案 webpack 1 新建项目空白目录 文件夹地址栏cmd运行 npm init y 初始化包管理配置文件package json 2 新建src源代码目录 3 src下新建index html和index js 4
  • Java --- 堆空间大小设置与OutOfMemoryError(OOM)

    目录 一 堆空间大小设置 二 OutOfMemoryError异常 一 堆空间大小设置 1 Java堆区用于存储Java对象实例 那么堆的大小在JVM启动时就已经设定好了 大家可以通过选项 Xmx 和 Xms 来进行设置 Xms 用于表示堆
  • gorm的全部标签说明

    在 GORM 中 可以使用多种标签来控制模型结构体的行为和数据库列的属性 以下是一些常用的 GORM 标签 primaryKey 将字段设置为模型的主键 autoIncrement 将字段设置为自增长字段 unique 将字段设置为唯一的
  • Filter链,FilterConfig接口,Filter实现用户自动登录

    一 Filter链 在一个 Web 应用程序中可以注册多个 Filter 程序 每个 Filter 程序都可以针对某一个 URL 进行拦截 如果多个 Filter 程序都对同一个 URL 进行拦截 那么这些 Filter 就会组成一个 Fi
  • mongodb replica初始化

    use admin cfg id audit members id 0 host 10 96 91 192 17017 priority 2 id 1 host 10 96 91 192 27017 priority 1 id 2 host
  • VSCode中JS脚本的运行(控制台输出配置)

    F5开始调试 进入launch json中进行如下配置 使用 IntelliSense 了解相关属性 悬停以查看现有属性的描述 欲了解更多信息 请访问 https go microsoft com fwlink linkid 830387
  • node版本降级

    问题原因 因为node版本过高 导致npm install 或npm run dev报错 1 安装node版本管理模块 n sudo npm install n g 2 根据自己需要的安装版本 例如 安装稳定版本 sudo n stable
  • 设计模式之抽象工厂

    抽象工厂模式结构图 抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口 而无需指定它们具体的类 工厂方法模式 定义一个用于创建对象的接口 让子类决定实例化哪一个类 抽象工厂模式是围绕一个超级工厂创建其他工厂 该超级工程又称为其他工厂的
  • 【Spring容器的启动流程】

    Spring容器的启动流程主要分为以下几个步骤 加载配置文件 Spring容器会从指定的配置文件中读取配置信息 包括bean的定义 依赖关系 AOP切面等 创建容器 Spring容器启动后会创建一个容器实例 容器负责管理bean的生命周期和
  • 使用Numpy随机生成一个4维矩阵,计算最后两维的和

    深度学习作业 1 使用Numpy随机生成一个4维矩阵 计算最后两维的和 import numpy def chapter2 6 ax1 ax2 ax3 ax4 arr numpy random randint 2 size ax1 ax2
  • 云原生之使用Docker部署Laverna笔记工具

    云原生之使用Docker部署Laverna笔记工具 一 Laverna介绍 1 Laverna简介 2 Laverna特点 二 检查本地环境状态 1 检查系统版本 2 检查docker状态 三 下载Laverna镜像 四 部署Laverna
  • 【MQTT】MQTT服务器mosquitto和客户端paho的使用

    MQTT服务器mosquitto和客户端paho mosquitto安装使用 1 mosquitto下载 从官网下载最新版本 https mosquitto org download 以下是mosquitto2 0 14windowsX64
  • Vue入门案例--TodoList备忘录

    文章目录 前言 1 创建Vue项目 2 搭建项目 2 1 MyHeader编写 2 2 MyList编写 2 3 MyItem编写 2 4 MyFooter编写 2 5 App编写 3 初始化列表 3 1 App定义数据 3 2 MyLis
  • 排序动态图

    1 冒泡排序 2 选择排序 3 鸡尾酒排序 4 插入排序 5 归并排序 6 堆排序 7 希尔排序 8 快速排序 上面的图片如果打不开 在新标签页面就可以
  • python3.7 安装Airflow中HiveToMySqlTransfer报错解决

    报错内容如下 File app python lib python3 7 site packages airflow hooks hive hooks py line 783 in get conn from pyhive hive imp
  • 百度地图BMap

    做了半天 搜到一个很好的demo 能解决多点的问题 http blog csdn net a497785609 article details 24009031 div style width 100 height 500px border
  • [大话设计模式C++版] 第9章 简历复印 —— 原型模式

    源码可以在这里找到 大话设计模式C 版 简历代码初步实现 写一个简历类 必须要有姓名 可以设置性别和年龄 可以设置工作经历 客户端实例化三份简历 main cpp include