原型模式(大话设计模式)C/C++版本

原型模式

在这里插入图片描述

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15924300.html

#include <iostream>
#include <string>
using namespace std;

class WorkExprerience
{
private:
    string workDate;
    string company;

public:
    WorkExprerience() {}
    ~WorkExprerience() {}

    WorkExprerience(WorkExprerience *work)
    {
        this->workDate = work->workDate;
        this->company = work->company;
    }

    string getWorkDate()
    {
        return workDate;
    }

    void setWorkDate(string workDate)
    {
        this->workDate = workDate;
    }

    string getCompany()
    {
        return company;
    }

    void setCompany(string company)
    {
        this->company = company;
    }

    WorkExprerience *Clone()
    {
        return new WorkExprerience(this);
    }
};

class Prototype
{
protected:
    string name;
    string sex;
    string age;
    string timeArea;
    string company;

public:
    virtual void SetPersonalInfo(string sex, string age) = 0;
    virtual void Display() = 0;
    virtual Prototype &Clone() = 0;
};

class Resume : public Prototype
{
private:
    WorkExprerience *workExp;

public:
    Resume(string name)
    {
        this->name = name;
        workExp = new WorkExprerience();
    }
    ~Resume()
    {
        if (workExp != NULL)
            delete workExp;
    }
    void SetPersonalInfo(string sex, string age)
    {
        this->sex = sex;
        this->age = age;
    }
    void SetWorkExperience(string workDate, string company)
    {
        workExp->setCompany(company);
        workExp->setWorkDate(workDate);
    }
    void Display()
    {
        cout << name << "  " << age << " " << sex << "  " << endl;
        cout << "工作经历  " << workExp->getWorkDate() << "  " << workExp->getCompany() << endl;
    }
    Resume &Clone()
    {
        Resume *clonedResume = new Resume(name);
        clonedResume->SetPersonalInfo(sex, age);
        return *clonedResume;
    }
};

int main()
{
    Resume *a = new Resume("big bird");
    a->SetPersonalInfo("MAN", "22");
    a->SetWorkExperience("1998-2000", "baidu");

    Resume b = a->Clone();
    b.SetWorkExperience("2000-2008", "google");

    Resume c = a->Clone();
    c.SetWorkExperience("2010-2018", "apple");

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

    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char workDate[50];
    char company[50];
} WorkExperience;

typedef struct
{
    char name[50];
    char sex[10];
    char age[10];
    char timeArea[50];
    char company[50];
} PersonalInfo;

typedef struct Resume Resume;
struct Resume
{
    PersonalInfo info;
    WorkExperience *workExp;
    void (*display)(Resume *);
    Resume *(*clone)(Resume *);
};

void DisplayResume(Resume *resume);
Resume *CloneResume(Resume *original);

void InitWorkExperience(WorkExperience *exp)
{
    strcpy(exp->workDate, "");
    strcpy(exp->company, "");
}

void SetWorkExperience(WorkExperience *exp, const char *date, const char *company)
{
    strcpy(exp->workDate, date);
    strcpy(exp->company, company);
}

void DisplayWorkExperience(const WorkExperience *exp)
{
    printf("工作经历  %s  %s\n", exp->workDate, exp->company);
}

Resume *CreateResume(const char *name)
{
    Resume *resume = (Resume *)malloc(sizeof(Resume));
    strcpy(resume->info.name, name);
    strcpy(resume->info.sex, "");
    strcpy(resume->info.age, "");
    strcpy(resume->info.timeArea, "");
    strcpy(resume->info.company, "");
    resume->workExp = (WorkExperience *)malloc(sizeof(WorkExperience));
    InitWorkExperience(resume->workExp);
    resume->display = DisplayResume;
    resume->clone = CloneResume;
    return resume;
}

void DestroyResume(Resume *resume)
{
    if (resume)
    {
        if (resume->workExp)
            free(resume->workExp);
        free(resume);
    }
}

void SetPersonalInfo(Resume *resume, const char *sex, const char *age)
{
    strcpy(resume->info.sex, sex);
    strcpy(resume->info.age, age);
}

void SetWorkExperienceForResume(Resume *resume, const char *date, const char *company)
{
    SetWorkExperience(resume->workExp, date, company);
}

void DisplayResume(Resume *resume)
{
    printf("%s  %s %s  \n", resume->info.name, resume->info.age, resume->info.sex);
    DisplayWorkExperience(resume->workExp);
}

Resume *CloneResume(Resume *original)
{
    Resume *cloned = CreateResume(original->info.name);
    strcpy(cloned->info.sex, original->info.sex);
    strcpy(cloned->info.age, original->info.age);
    SetWorkExperienceForResume(cloned, original->workExp->workDate, original->workExp->company);
    return cloned;
}

int main()
{
    Resume *a = CreateResume("big bird");
    SetPersonalInfo(a, "MAN", "22");
    SetWorkExperienceForResume(a, "1998-2000", "baidu");

    Resume *b = a->clone(a);
    SetWorkExperienceForResume(b, "2000-2008", "google");

    Resume *c = a->clone(a);
    SetWorkExperienceForResume(c, "2010-2018", "apple");

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

    DestroyResume(a);
    DestroyResume(b);
    DestroyResume(c);

    return 0;
}

总结

关键在于实现一个Clone函数(和构造拷贝一样要注意深浅拷贝)!
与拷贝构造函数相比就是:方便扩展,动态灵活定义拷贝行为(而且可被继承)

原型模式和赋值/拷贝构造有啥区别?

原型模式可以更灵活的进行对象的创建和定制,可以运行时动态决定克隆哪个类型;这是赋值/构造函数所不能做到的,因为他们无法被继承重写。

为什么需要使用原型模式,我觉得构造函数完全够用啊?

因为某些场景下,业务会有那些大型类,这些类的初始化往往可能包含了很多资源分配(如数据库连接、文件打开、网络连接等),计算或调用外部服务等,所以也就是说往往是代表的是一部分初始化过程,而不仅仅就是一个类的构造,其实也就是将初始化部分封装,可以打包复制。否则重新构造的话,对于性能和流程逻辑都是巨大的考验。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值