您的位置:首页 > 其它

设计模式学习--原型模式

2015-06-30 00:01 393 查看
原型模式是属于对象创建型,通过克隆的方式从一个对象在创建另外一个可定制的对象,而且不需要知道任何创建的细节,原型模式常与工厂模式混合使用

定义

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

结构



适用性

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

2 当要实例化的类是在运行时指定时,比如:通过动态装载

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

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

5 资源优化的场景

6 性能和安全要求的场景

7 一个对象多个修改者的场景

协作

客户请求一个原型克隆自身

优点

1 运行时刻增加和删除产品

2 改变值以指定新的对象

3 改变结构以指定新的对象

4 减少子类的构建

5 用类动态配置应用

6 性能优良

7 逃避构造函数的约束

缺点

原型模型必须要求子类实现Clone的操作,在有时候这可能变得很困难

实现考虑的问题

1 使用一个原型管理器,即在当一个系统中原型数目不固定时,可以使用一个注册表,客户请求的时候去注册表查找。

2 实现克隆操作 浅拷贝和深拷贝的问题

3 初始化克隆对象

例子,以一个邮件发送系统为例

// ProtoType.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Mail.h"
#include "AdvTemplate.h"
#include <iostream>

using namespace std;
//发送邮件的接口
void sendMaile(Mail* mail)
{
cout << "标题:" << mail->getSubject() << endl;
cout << "收件人:" << mail->getReceiver() << endl;
cout << "发送成功" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
//发送邮件数量
int Max_count = 6;
int i = 0;
//邮件广告模板
AdvTemplate advTemplate;
//邮件原始对象
Mail* mail = new Mail(advTemplate);
mail->setTail("XX所有权");
string name("jaime");
while ( i < Max_count )
{
name = name + name;
//通过克隆出邮件的另一个实例
Mail* mailClone = mail->clone();
//操作实例
mailClone->setAppellation(name + "先生/女士");
mailClone->setReceiver(name + "@gmail.com");
//发送邮件
sendMaile(mailClone);
i++;
}
return 0;
}

/************************************************************************
@fileName:AdvTemplate.h
@function: 邮件系统中的邮件广告模板类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include <string>
using namespace std;
class AdvTemplate
{
public:
AdvTemplate();
~AdvTemplate();
string getAdvSubject();
string getAdvContext();
private:
string m_advSubject;
string m_advContext;
};
//广告模板类的实现
#include "AdvTemplate.h"
AdvTemplate::AdvTemplate()
:m_advSubject("XX银行国庆信用卡抽奖活动"),
m_advContext("国庆抽奖通知,只要刷卡就送")
{
}

AdvTemplate::~AdvTemplate()
{
}
//设置标题
std::string AdvTemplate::getAdvSubject()
{
return this->m_advSubject;
}
//设置上下文
std::string AdvTemplate::getAdvContext()
{
return this->m_advContext;
}

/************************************************************************
@fileName: MailClone.h
@function: 原型模式的原型父类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once

class MailClone
{
public:
MailClone();
~MailClone();
virtual MailClone* clone() = 0;
private:

};
/************************************************************************
@fileName: Mail.h
@function: 原型模式的原型父类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include "MailClone.h"
#include <string>
#include "AdvTemplate.h"

using namespace std;

class Mail : public MailClone
{
public:
Mail(AdvTemplate& advTemplate);
Mail(const Mail& mail);
~Mail();
virtual Mail* clone();
string getReceiver();
void setReceiver(string receiver);
string getSubject();
void setSubject(string subject);
string getAppellation();
void setAppellation(string appellation);
string getContext();
void setContext(string context);
string getTail();
void setTail(string tail);
private:
string m_receiver;
string m_subject;
string m_appellation;
string m_context;
string m_tail;
AdvTemplate m_advTemplate;
};

#include "Mail.h"

Mail::Mail(AdvTemplate& advTemplate)
{
m_advTemplate = advTemplate;
}

Mail::Mail(const Mail& mail)
{

}

Mail::~Mail()
{
}

std::string Mail::getReceiver()
{
return this->m_receiver;
}

void Mail::setReceiver(string receiver)
{
this->m_receiver = receiver;
}

std::string Mail::getSubject()
{
return this->m_subject;
}

void Mail::setSubject(string subject)
{
this->m_subject = subject;
}

std::string Mail::getAppellation()
{
return this->m_appellation;
}

void Mail::setAppellation(string appellation)
{
this->m_appellation = appellation;
}

std::string Mail::getContext()
{
return this->m_context;
}

void Mail::setContext(string context)
{
this->m_context = context;
}

std::string Mail::getTail()
{
return this->m_tail;
}

void Mail::setTail(string tail)
{
this->m_tail = tail;
}


运行结果是:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息