1.原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2.原型模式其实就是从一个对象再创建另外一个可订制的对象。而且不需要知道任何创建的细节。
3.一般在初始化的信息不发生变化的情况下,克隆是最好的方法。这既隐藏了对象创建的细节,又对性能是大大的提高。
4.原型模式是不用重新初始化对象,而是动态地获得对象运行时的状态。
5.在C#中的Memberwise是浅复制。因为如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原始对象及其副本引用同一对象。
6.深复制:把引用对象的]变量指向复制过的新对象,而不是原来有的被引用的对象。所有在深复制中,把要复制的对象引用都应该复制一遍。
7.深复制要深入到多少层,需要事先就考虑好,而且要当心出现循环引用的问题。
8.比如数据集对象DataSet,它就有Clone()方法和Copy()方法,Clone()方法用来复制DataSet的结构,但不复制DataSet的数据,实现了原型模式的浅复制。Copy()方法不但复制结构,也复制数据,其实就是实现了原型模式的深
复制。
9.大量的复制简历的例子就是原型模式的最好体现。
9.2 在没有原型复制的情况下,创建简历时多么的复杂啊
9.2.1 Resume.h
#pragma once
#include <string>
#include <iostream>
class Resume
{
public:
Resume(std::string name)
{
m_Name = name;
};
//设置个人信息
void SetPersonalInfo(std::string sex, std::string age)
{
m_Sex = sex;
m_Age = age;
};
//设置工作简历
void SetWorkExperience(std::string timeArea, std::string company)
{
m_TimeArea = timeArea;
m_Company = company;
};
//显示
void Display(void)
{
std::cout << m_Name << m_Sex << m_Age
<< "\n工作经历:" << m_TimeArea << m_Company << std::endl;
}
private:
std::string m_Name;
std::string m_Sex;
std::string m_Age;
std::string m_TimeArea;
std::string m_Company;
};
9.2.2 客户端
#include "stdafx.h"
#include "Resume.h"
int _tmain(int argc, _TCHAR* argv[])
{
Resume* a = new Resume("Big Bird");
a->SetPersonalInfo("male", "29");
a->SetWorkExperience("1998-2000","XX公司");
Resume* b = new Resume("Big Bird");
b->SetPersonalInfo("male", "29");
b->SetWorkExperience("1998-2000","XX公司");
Resume* c = new Resume("Big Bird");
c->SetPersonalInfo("male", "29");
c->SetWorkExperience("1998-2000","XX公司");
a->Display();
b->Display();
c->Display();
delete a;
delete b;
delete c;
return 0;
}
9.3 原型模式
9.3.1 Prototype.h
#pragma once
#include <string>
class Prototype
{
public:
Prototype(std::string id)
{
m_id = id;
};
std::string GetId(void)
{
return m_id;
};
virtual Prototype* Clone(void) = 0;
protected:
std::string m_id;
};
//具体原形类
class ConcretePrototype1 :public Prototype
{
public:
ConcretePrototype1(std::string id)
:Prototype(id)
{
};
Prototype* Clone(void)
{
return static_cast<Prototype*>(new ConcretePrototype1(m_id));
};
};
9.3.2 客户端
#include "stdafx.h"
#include "Prototype.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
ConcretePrototype1* p1 = new ConcretePrototype1("I");
ConcretePrototype1* c = (ConcretePrototype1*)p1->Clone();
std::cout << c->GetId() << "is Cloned!!!" << std::endl;
return 0;
}
9.4 大量的复制简历
9.4.1 ProtoType.h
#pragma once
#include <string>
#include <iostream>
#include <memory>
template<typename T>
class ProtoType
{
public:
ProtoType()
{
m_ptr.reset(0);
}
virtual ~ProtoType(){};
public:
virtual T *Clone() = 0;
protected:
std::auto_ptr<T> m_ptr;
};
class ConcreteResume: public ProtoType<ConcreteResume>
{
public:
ConcreteResume(std::string name)
{
m_Name = name;
};
void SetPersonalInfo(std::string sex, std::string age)
{
m_Sex = sex;
m_Age = age;
};
void SetWorkExperience(std::string timeArea, std::string company)
{
m_TimeArea = timeArea;
m_Company = company;
};
virtual ~ConcreteResume(){};
public:
inline ConcreteResume *Clone()
{
ConcreteResume* p = new ConcreteResume("BIG Bird");
p->SetPersonalInfo("male", "29");
p->SetWorkExperience("1998-2000","XX公司");
m_ptr.reset(p);
return m_ptr.get();
};
void Display(void)
{
std::cout << m_Name << m_Sex << m_Age
<< "\n工作经历:" << m_TimeArea << m_Company << std::endl;
};
private:
std::string m_Name;
std::string m_Sex;
std::string m_Age;
std::string m_TimeArea;
std::string m_Company;
};
9.4.2 客户端
#include "stdafx.h"
#include "ProtoType.h"
int _tmain(int argc, _TCHAR* argv[])
{
ConcreteResume* a = new ConcreteResume("Big Bird");
a->SetPersonalInfo("male", "29");
a->SetWorkExperience("1998-2000","公司");
ConcreteResume* b = a->Clone();
delete a;
return 0;
}