原型模式(Prototype)

原型模式(Prototype)

一、介绍
  1. 意图:

    • 用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
    • 原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后通过复制这个原型对象的方法,创建出更多同类型的对象。原型模式分为两种:浅拷贝和深拷贝。浅拷贝仅仅复制所考虑的对象,而不复制它引用的对象,也就是其中的成员对象并不复制;深拷贝除了对象本身被复制之外,对象包含的引用也被复制,即成员对象也被复制。
  2. 结构:

    • 其中:
      • Prototype声明一个复制自身的接口。
      • ConcretePrototype实现一个复制自身的操作。
      • Client让一个原型复制自身从而创建一个新的对象。
  3. 适用:

    • 当一个系统应该独立于它的产品的创建、构成和表示时。

    • 当要实例化的类是在运行时刻指定时,例如,通过动态装载。

    • 为了避免创建一个与产品类层次平行的工厂类层次时。

    • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化更方便一些。

    • 原型模式的优点是:

      • 向客户隐藏制造新实例的复杂性;
      • 提供让客户能够产生未知类型对象的选项;
      • 在某些环境下,复制对象比创建新对象更有效。
二、考题
  1. 2013上半年下午

    • 现要求实现一个能够自动生成求职简历的程序。简历的解百纳内容包括求职者的姓名、性别、年龄及工作经历等。希望每份简历中的工作经历有所不同,并尽量减少程序中的重复代码。
    #include <iostream>
    using namespace std;
    
    class Cloneable {
    public:
    	virtual Cloneable * Colne() = 0; // (1)
    }
    
    class WorkExperience : public Cloneable{ // 工作经历
    private:
        string workDate;
        string company;
    public:
        Cloneable * Colne(){
            WorkExperience* obj = new WorkExperience(); // (2)
            obj->workDate = this->workDate;
            obj->company = this->company;
            return obj;
        }
        // 其余代码省略
    }
    
    class Resume : public Cloneable{ // 简历
    private:
        string name;string sex;string age;
        WorkExperience * work;
        Resume(WorkExperience * work){
            this->work = (WorkExperience*)work.clone(); // (3)
        }
    public:
        Resume(string name) {/*实现略*/}
        void SetPersonalInfo(string sex, string age) {/*实现略*/}
        void SetWorkExperience(string workDate, string company) {/*实现略*/}
        Cloneable * Clone(){
            Resume * obj = new Resume(); // (4)
            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", "xxx公司");
        Resume* b = (Resume*)a->Clone(); // (5)
        a->SetWorkExperience("2001-2006", "yyy公司");
        return 0;
    }
    
    
posted @ 2023-01-15 18:19  某科学的撒把豆子  阅读(245)  评论(0)    收藏  举报