C++设计模式之 —— 原型模式 Prototype

原创 2015年07月08日 21:40:44

什么是原型模式?

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

    说白了,就是从一个对象创建另外一个同类型的可定制的对象,并且创建的过程隐藏了创建的细节。使得客户端在创建多个对象时更为简洁。 当一个类的构建比较复杂,而我们需要动态的进行创建,只有部分数据需要定制时,原型模式可以在隐藏创建细节的同时很好的确保代码的简洁。

举个例子

    对于同班的同学,具有一些共同的属性,例如同一所学校,同一个专业等,如果我们需要动态的创建多个学生的实例,由于大部分的属性信息都是相同的,没有必要对每个实例进行创建,使用原型模式创建一个副本,并进行定制即可。 示例代码:

1. Prototype.h

#ifndef Prototype_h__
#define Prototype_h__

#include <string>

using namespace std;

/*
 * Prototype interface
 */
class IPrototype
{
public:
	virtual IPrototype* Clone() = 0;
};

struct COrganizeInfo
{
	string m_strSchool;
	string m_strMajor;
};


class CStudent : IPrototype
{
public:
	CStudent();
	~CStudent();

	virtual IPrototype* Clone();

	void SetName(const string& name)		{ m_strName = name;		}
	void SetOrganizeInfo(COrganizeInfo* pOrgInfo) {m_pOrgInfo = pOrgInfo;}
	void PrintInfo();

private:
	string			m_strName;
	COrganizeInfo*	m_pOrgInfo;
};

#endif // Prototype_h__

2. Prototype.cpp

#include "Prototype.h"
#include <iostream>

CStudent::CStudent(): m_strName(""),m_pOrgInfo(NULL)
{
}

CStudent::~CStudent()
{
	delete m_pOrgInfo;
}

IPrototype* CStudent::Clone()
{
	CStudent* pStudent = new CStudent();

	//deep copy
	COrganizeInfo* pOrgInfo = new COrganizeInfo();
	pOrgInfo->m_strSchool = m_pOrgInfo->m_strSchool;
	pOrgInfo->m_strMajor = m_pOrgInfo->m_strMajor;
	pStudent->SetOrganizeInfo(pOrgInfo);

	pStudent->SetName(m_strName);
	return pStudent;
}

void CStudent::PrintInfo()
{
	cout << "Student:" << m_strName
		 << ", School:" << m_pOrgInfo->m_strSchool
		 << ", Major:" << m_pOrgInfo->m_strMajor << endl;
}



3. Client

COrganizeInfo* pOrgInfoA = new COrganizeInfo();
pOrgInfoA->m_strSchool = "School XXX";
pOrgInfoA->m_strMajor = "CS";
CStudent* pStudentA = new CStudent();
pStudentA->SetOrganizeInfo(pOrgInfoA);
pStudentA->SetName("nameA");
pStudentA->PrintInfo();

CStudent* pStudentB = (CStudent*)pStudentA->Clone();
pStudentB->SetName("nameB");
pStudentB->PrintInfo();

CStudent* pStudentC = (CStudent*)pStudentA->Clone();
pStudentC->SetName("nameC");
pStudentC->PrintInfo();



从client 的示例代码可以看出, studentB 和 studentC 对象的创建直接通过 Clone() 进行创建,只需要更改必要的数据(name)便完成了新对象的创建初始化工作。如果我们不使用原型模式,client 端的代码类似下面所示:

COrganizeInfo* pOrgInfoA = new COrganizeInfo();
pOrgInfoA->m_strSchool = "School XXX";
pOrgInfoA->m_strMajor = "CS";
CStudent* pStudentA = new CStudent();
pStudentA->SetOrganizeInfo(pOrgInfoA);
pStudentA->SetName("nameA");
pStudentA->PrintInfo();

COrganizeInfo* pOrgInfoB = new COrganizeInfo();
pOrgInfoB->m_strSchool = "School XXX";
pOrgInfoB->m_strMajor = "CS";
CStudent* pStudentB = new CStudent();
pStudentB->SetOrganizeInfo(pOrgInfoA);
pStudentB->SetName("nameB");
pStudentB->PrintInfo();


通过对比可以看出,一般在初始化的信息不怎么发生变化的情况下,克隆是最好的办法。


我所理解的设计模式(C++实现)——原型模式(Prototype Pattern)

解决的问题: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是一致的,实际上就是动态抽取当前对象运行时的状态。 类图结构:      ...

设计模式C++实现(4)——原型模式(Prototype)

原帖: http://www.cnblogs.com/jiese/p/3164428.html 作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 ...

我所理解的设计模式(C++实现)——原型模式(Prototype Pattern)

解决的问题: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是一致的,实际上就是动态抽取当前对象运行时的状态。 类图结构:  ...

C++设计模式之九--Prototype原型模式

转自:http://www.cnblogs.com/jiese/archive/2013/07/01/3164428.html  作用: 用原型实例指定创建对象的种类,...

C++设计模式-Prototype原型模式

作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在...

c++设计模式之原型模式Prototype

/************************************************************************/ /* 原型模式 ...

设计模式之 原型模式(prototype)(C++实现 深拷贝 + 浅拷贝版本[bug])

本文介绍设计模式中的原型模式。 本质上其实就是克隆。 下面以个人简历很工作经历为例。 深拷贝版本: #include #include #include using namespa...

C++设计模式-Prototype原型模式

作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言...

设计模式C++原型模式(Prototype)

意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 适用性: 当一个系统应该独立于他的产品创建、构成和表示时,需要使用原型模式 当要实例化的类是在运行时刻指定时,...

C++设计模式-Prototype原型模式

作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++设计模式之 —— 原型模式 Prototype
举报原因:
原因补充:

(最多只允许输入30个字)