(本博客旨在个人总结回顾)
1、详情:
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
说明:
①根据定义原型模式是通过拷贝一个现有对象生成新对象的,这样可以直接拷贝某个状态下的新对象,减少了对象的初始化和对该状态下对象的赋值,提高效率。
②原型模式与拷贝构造函数,赋值运算符重载函数的关系:原型模式通俗讲就是克隆,复制一个新的对象。而拷贝构造函数和赋值运算符重载函数可以实现这样的对象复制,所以他们可以是原型模式,但复制一个对象的方法有很多种,也就是说,原型模式是实现对象复制的一种模式,而拷贝构造函数和运算符重载函数可以按照原型模式来实现。
使用场景: ①资源优化场景。 ②类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 ③性能和安全要求的场景。 ④通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 ⑤一个对象多个修改者的场景
优点:①性能提高。
缺点: 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
2、应用实例:
个人资料拷贝(使用简单例子易于理解)
3.1、UML类图:
3.2、例子源码
stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
// TODO: 在此处引用程序需要的其他头文件
Proto.h
#pragma once
class Proto
{
public:
Proto();
virtual ~Proto();
public:
virtual void display() = 0;
virtual void setPerson(int age, char* name) = 0;
virtual Proto* clone() = 0;
};
Proto.cpp
#include "stdafx.h"
#include "Proto.h"
Proto::Proto()
{
}
Proto::~Proto()
{
}
Person.h
#pragma once
#include "Proto.h"
class Person :
public Proto
{
public:
Person();
~Person();
public:
Proto* clone();
void setPerson(int age, char* name);
void display();
private:
char* m_strName;
int m_nAge;
};
Person.cpp
#include "stdafx.h"
#include "Person.h"
#include <string.h>
#include <cstdlib>
#include <cstdio>
Person::Person()
: m_strName(NULL)
, m_nAge(0)
{
}
Person::~Person()
{
}
Proto* Person::clone()
{
Person* pPerson = new Person();
pPerson->setPerson(m_nAge, m_strName);
return pPerson;
}
void Person::setPerson(int age, char* name)
{
m_nAge = age;
if (NULL == m_strName)
{
m_strName = new char[strlen(name) + 1];
}
else
{
delete m_strName;
m_strName = new char[strlen(name) + 1];
}
strcpy_s(m_strName, strlen(name) + 1, name);
}
void Person::display()
{
cout << "name:" << m_strName << endl << "age:" << m_nAge << endl;
}
ProtoPatternMemo.cpp
// ProtoPatternMemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Person.h"
int _tmain(int argc, _TCHAR* argv[])
{
Person person;
person.setPerson(26, "王思聪");
Proto* pPerson1 = person.clone();
Proto* pPerson2 = pPerson1->clone();
pPerson1->setPerson(67, "王健林");
pPerson2->setPerson(36, "林二狗");
person.display();
pPerson1->display();
pPerson2->display();
delete pPerson1;
pPerson1 = NULL;
delete pPerson2;
pPerson2 = NULL;
system("pause");
return 0;
}