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

源码可以在这里找到 大话设计模式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方法可以利用某些框架中的序列化来实现深拷贝
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值