C++设计模式Learning:原型模式

写在前面

我们知道,设计模式的终极目标是高内聚,低耦合,好的软件代码必然离不开好的设计。最近在学习设计模式这块的内容,参考的书籍是程杰的《大话设计模式》,这本书对于初学者来说比较友好,易上手,博客里的内容是参考本书以及网络资源整理的。

博客更新基本上是边学边写的过程,写这个专题一是为了作为自己的知识备忘,二是希望能给正在学习设计模式的童鞋一些参考,博客中内容有纰漏或错误之处,还请指出,谢谢。

基本定义

原型模式,属于创建型模式。原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

PS:原型模式,提供了对象拷贝的Clone接口,而在C++中,拷贝构造函数作为对象拷贝的一种实现方式。

UML图

 原型模式总体结构比较简单,主要由抽象原型类和具体原型类组成。

包含以下几类角色:

Prototype:抽象原型类(一般可定义为接口),声明一个克隆自身的接口。

ConcretePrototype:具体原型类,实现一个克隆自身的操作。

原型模式实例

场景:制作多份简历时,每份简历的内容存在些许差别,此时可以用到原型模式。

UML图

代码实现

 1. Object抽象原型类

// 抽象原型类,Object
class Object
{
public:
    virtual Object* Clone() = 0;
};

2. 具体原型类--简历类

// 工作经历类
class Experience
{
public:
    std::string m_workDate;
    std::string m_company;
};

//简历类(具体原型类),Resume
class Resume : public Object
{
public:
    Resume(string name, int age)
    {
        m_name = name;
        m_age = age;
        m_experience = new Experience();
    }
    //深拷贝构造函数,若不写则为默认拷贝构造函数,默认拷贝构造函数为浅拷贝。
    Resume(const Resume& resume)
    {
        m_name = resume.m_name;
        m_age = resume.m_age;
        m_experience = new Experience();
        m_experience->m_company = resume.m_experience->m_company;
        m_experience->m_workDate = resume.m_experience->m_workDate;
    }
    ~Resume()
    {
        if (m_experience != NULL) {
            delete m_experience;
        }
    }
    void SetPersonalInfo(std::string name, int age)
    {
        m_name = name;
        m_age = age;
    }
    void SetExperience(std::string workDate, std::string company)
    {
        m_experience->m_company = company;
        m_experience->m_workDate = workDate;
    }
    void Display()
    {
        std::cout << m_name << " " << m_age << std::endl;
        std::cout << "Experience: " << m_experience->m_workDate << " " <<m_experience->m_company << std::endl;
    }
    Object* Clone()
    {
        return new Resume(*this);
    }
public:
    std::string m_name;
    int m_age;
    Experience* m_experience = NULL;
};

注:这里为了访问方便,成员变量设置成public,实际应该设置为protected/private。

 3. 客户端测试代码

int main(int argc, char* argv[])
{
    Resume *resume1 = new Resume("ZZQ", 25);
    resume1->SetExperience("2017-7~2020-7", "Tsinghua University");
    Resume *resume2 = dynamic_cast<Resume*>(resume1->Clone());
    resume2->SetExperience("2020-7~2021-7", "Baidu.com, Inc");
    resume1->Display();
    resume2->Display();
    return 0;
}

 测试结果

D:\Project\code_exercise\cmake-build-debug\code_exercise.exe
ZZQ 25
Experience: 2017-7~2020-7 Tsinghua University
ZZQ 25
Experience: 2020-7~2021-7 Baidu.com, Inc

Process finished with exit code 0

优缺点和使用场景

优点:

1、提高性能 : 原型模式克隆实例对象 , 比使用构造函数重新创建对象性能要高  ( 针对类实例对象开销大的情况 )。

2、简化流程: 原型模式简化了创建实例的过程 ,隐藏创建细节, 可以直接修改现有的对象实例的值 , 达到复用的目的  ( 针对构造函数繁琐的情况 )。

缺点:

1、需要重写clone方法,并且对于复杂场景,要能熟练掌握深拷贝和浅拷贝的区别。

使用场景:

1、当使用类构造函数进行初始化时,当初始化流程出现繁琐,资源占用,耗时等情况时,可以使用原型模式克隆实例。

2、当实例化对象数量庞大时可以使用原型模式。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值