zoukankan      html  css  js  c++  java
  • 【设计模式】——原型模式

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

      下图是原型模式的结构图:

    原型模型其实就是一个对象再创建另外一个可定制的对象,而且不需任何创建的细节,我们来看看基本的原型模式代码。

    //原型类
    class Prototype
    {
    private:
        string id;
    public:
        Prototype(string id)
        {
            this->id=id;
        }
        string GetId()
        {
            return id;
        }
        virtual Prototype *Clone()=0;
    };
    //具体原型类
    class ConcretePrototype:public Prototype
    {
    public:
        ConcretePrototype(string id):Prototype(id){}
        Prototype *Clone()
        {
            return new ConcretePrototype(*this);
        }
    };

      一般在初始化的信息不发生变化的情况下,克隆是最好的方法。这既隐藏了对象创建的细节,又对性能是大大的提高。也就是不用重新初始化对象,而是动态地获得对象运行时的状态。

      原型系统的关键就是实现clone函数,当然这涉及到了浅拷贝和深拷贝之说,但是拷贝构造函数,需实现深拷贝。在用深拷贝实现简历之前,我们谈谈这两种拷贝。浅复制,被复制对象的所有变量都含有与原来相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制把引用对象的变量指向复制过的对象,而不是原有的被引用的对象。

    简历的深拷贝实现:

    #include <iostream>
    using namespace std;
    class IClonable
    {
    public:
        virtual void SetPersonalInfo(string sex,string age)=0;
        virtual void SetWorkExperience(string workDate,string company)=0;
        virtual void Display()=0;
        virtual IClonable* Clone()=0;
    };
    class WorkExperience:public IClonable
    {
    private:
        string workDate;
        string company;
    public:
        WorkExperience(){}
        void SetPersonalInfo(string sex,string age) {
        }
        void Display() {
        }
        void SetWorkExperience(string workDate,string company)
        {
            this->workDate=workDate;
            this->company=company;
        }
        string GetWorkDate()
        {
            return workDate;
        }
        string GetCompany()
        {
            return company;
        }
        IClonable* Clone()
        {
            WorkExperience *tmp=new WorkExperience();
            tmp->SetWorkExperience(workDate,company);
            return tmp;
        }
    };
    class Resume:public IClonable
    {
    private:
        string name;
        string sex;
        string age;
        WorkExperience *work;
        Resume(WorkExperience *work)
        {
            //提供Clone方法调用的私有构造函数,以便克隆”工作经历“的数据
            this->work=(WorkExperience*)work->Clone();
        }
    public:
        Resume(string name)
        {
            this->name=name;
            work=new WorkExperience();
        }
        void SetPersonalInfo(string sex,string age)
        {
            this->sex=sex;
            this->age=age;
        }
        void SetWorkExperience(string workDate,string company)
        {
            work->SetWorkExperience(workDate,company);
        }
        void Display()
        {
            cout << name << " " << sex << " " << age << endl;
            cout << "工作经历:" << work->GetWorkDate() << " " << work->GetCompany() << endl;
        }
        IClonable *Clone()
        {
            //调用私有的构造方法,让”工作经历“克隆完成,然后再给这个”简历“对象的相关字段赋值,最终返回一个深复制的简历对象
            Resume *obj=new Resume(this->work);
            obj->name=this->name;
            obj->sex=this->sex;
            obj->age=this->age;
            return obj;
        }
    };
    int main()
    {
        Resume *a=new Resume("大鸟");
        a->SetPersonalInfo("","29");
        a->SetWorkExperience("1998-2000","XX公司");
    
        Resume *b=(Resume*)a->Clone();
        b->SetWorkExperience("1998-2006","YY企业");
    
        Resume *c=(Resume*)a->Clone();
        c->SetPersonalInfo("","24");
        c->SetWorkExperience("1998-2003","ZZ企业");
    
        a->Display();
        b->Display();
        c->Display();
        return 0;
    }
  • 相关阅读:
    InstallShield自定义对话框模板代码(转)
    破解汇编知识(转)
    Openrowset数据库远程操作
    SQL类似sleep延时语句
    C#结束线程
    JavaScript中相应ActiveX事件
    Visual C# .NET 命令行编辑器
    AfxBeginThread
    atoi,atol,strtod,strtol,strtoul类型转换(转)
    SQLServer PadLeft,PadRight
  • 原文地址:https://www.cnblogs.com/awy-blog/p/3811082.html
Copyright © 2011-2022 走看看