【5】设计模式之Prototype模式

来源:互联网 发布:ubuntu gtx1080 驱动 编辑:程序博客网 时间:2024/04/30 08:36

1、描述

Prototype模式提供了自我复制的功能,新对象的创建可以通过已有对象进程创建,Prototype通过提供一个已存在对象进行新对象创建的借口Clone()。

2、示例

现在电子账单越来越流行了,比如你的信用卡,到月初的时候银行就会发一份电子邮件到你邮箱中,说你这个月消费了多少,什么时候消费的,积分是多少等等,这个是每个月发一次,但是还有一种也是银行发的邮件你肯定有印象:广告信,现在各大银行的信用卡部门都在拉拢客户,电子邮件是一种廉价、快捷的通讯方式,你用纸质的广告信那个费用多高呀,比如我今天推出一个信用卡刷卡抽奖活动,通过电子账单系统可以一个晚上发送给 600 万客户,为什么要用电子账单系统呢?直接找个发垃圾邮件不就解决问题了吗?是个好主意,但是这个方案在金融行业是行不通的,银行发这种邮件是有要求的,一是一般银行都要求个性化服务,发过去的邮件上总有一些个人信息吧,比如“XX 先生”,“XX 女士”等等,二是邮件的到达率有一定的要求,由于大批量的发送邮件会被接收方邮件服务器误认是垃圾邮件,因此在邮件头要增加一些伪造数据,以规避被反垃圾邮件引擎误认为是垃圾邮件;从这两方面考虑广告信的发送也是电子账单系统(电子账单系统一般包括:账单分析、账单生成器、广告信管理、发送队列管理、发送机、退信处理、报表管理等)的一个子功能,我们今天就来考虑一下广告信这个模块是怎么开发的。那既然是广告信,肯定需要一个模版,然后再从数据库中把客户的信息一个一个的取出,放到模版中生成一份完整的邮件,然后扔给发送机进行发送处理,我们来看类图:

 

工程目录:


AdvTemplate

//AdvTemplate.h#ifndef __Prototype__AdvTemplate__#define __Prototype__AdvTemplate__#include <iostream>using std::string;class CAdvTemplate{public:CAdvTemplate();~CAdvTemplate();string GetAdvSubject();string GetAdvContext();private:string m_advSubject;string m_advContext;};#endif /* defined(__Prototype__AdvTemplate__) *///AdvTemplate.cpp#include "AdvTemplate.h"CAdvTemplate::CAdvTemplate(){this->m_advSubject = "XX银行国庆信用卡抽奖活动";this->m_advContext = "国庆抽奖活动通知:只要刷卡就送你1百万!……";}CAdvTemplate::~CAdvTemplate(void){}//取得广告信的名称string CAdvTemplate::GetAdvSubject(){return this->m_advSubject;}//取得广告信的名称string CAdvTemplate::GetAdvContext(){return this->m_advContext;}

Mail

//Mail.h#ifndef __Prototype__Mail__#define __Prototype__Mail__#include <iostream>#include "ICloneableNow.h"#include "AdvTemplate.h"using std::string;class CMail : public ICloneableNow{public:    CMail(CAdvTemplate* pAdvTemp);    ~CMail();    string getReceiver();    void setReceiver(string& receiver);    string getSubject();    void setSubject(string& subject);    string getAppellation();    void setAppellation(string& appellation);    string getContxt();    void setContxt(string& contxt);    string getTail();    void setTail(string& tail);    CMail * Clone();    private:    string m_receiver;    //收件人    string m_subject;     //邮件名称    string m_appellation; //称谓    string m_contxt;      //邮件内容    string m_tail;        //邮件的尾部,一般都是加上“XXX版权所有”等信息};#endif /* defined(__Prototype__Mail__) *///Mail.cpp#include "Mail.h"CMail::CMail(CAdvTemplate* pAdvTemp){    m_contxt = pAdvTemp->GetAdvContext();    m_subject = pAdvTemp->GetAdvSubject();}CMail::~CMail(){    }string CMail::getReceiver(){    return m_receiver;}void CMail::setReceiver(string& receiver){    m_receiver = receiver;}string CMail::getSubject(){    return m_subject;}void CMail::setSubject(string& subject){    m_subject = subject;}string CMail::getAppellation(){    return m_appellation;}void CMail::setAppellation(string& appellation){    m_appellation = appellation;}string CMail::getContxt(){    return m_contxt;}void CMail::setContxt(string& contxt){    m_contxt = contxt;}string CMail::getTail(){    return m_tail;}void CMail::setTail(string& tail){    m_tail = tail;}CMail* CMail::Clone(){    const CMail entity = *this;    CMail* pMail = new CMail(entity);    return pMail;}
ICloneableNow:增加该接口同时在Mail中重写Clone方法,避免sendMail修改为多线程后存在安全性问题

#ifndef Prototype_ICloneableNow_h#define Prototype_ICloneableNow_hclass CMail;class ICloneableNow{public:        ICloneableNow(void)    {    }        virtual ~ICloneableNow(void)    {    }    virtual CMail * Clone() = 0;};#endif
main.cpp

#include <iostream>#include "Mail.h"#include "AdvTemplate.h"#include <time.h>using std::cout;using std::endl;using std::string;int rand_int(int min,int max){    int temp = rand()%max;    while(temp < rand()%min)        temp = rand()%max;    return temp;}int getRand1(){    srand((unsigned int)time(0));    for(int i = 0; i <= 9; i++)    {        int temp = rand();        cout << temp << endl;        return temp;    }    return 0;}int gerRand2(int previout){    srand((unsigned int)time(NULL)+ previout);    for(int i = 0; i < 100; i++)    {        int j = rand()%52;        if(j != previout)            return j;    }    return 0;}char *pSource = "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";string getRandString(int count){    char* pRet = new char[count + 1];    int index = static_cast<int>(time(NULL));    for(int i = 0; i < count; i++)    {        index = rand_int(5, 30);        pRet[i] = *(pSource + index);    }    pRet[count] = '\0';    string ret(pRet);    delete pRet;    pRet = NULL;    return ret;}void sendMail(CMail mail){    cout << " 主题:" << mail.getSubject().c_str();    cout << " 收件人:" << mail.getReceiver().c_str();    cout << " ....邮件发送成功" << endl;}void DoIt(){    int i = 0;    int count = 3;    CAdvTemplate temp;    CMail mail(&temp);    string tail("XX银行版权所有");    mail.setTail(tail);    while(i < count)    {        CMail* pCloneMail = mail.Clone();        string appellation = getRandString(8);        appellation.append("先生(女士)");        pCloneMail->setAppellation(appellation);        string receiver = getRandString(5);        receiver.append("@");        receiver.append(getRandString(8));        receiver.append(".com");                pCloneMail->setReceiver(receiver);        sendMail(*pCloneMail);        delete pCloneMail;        i++;    }}int main(int argc, const char * argv[]) {    // insert code here...    DoIt();    std::cout << "Hello, World!\n";    return 0;}

3、运行结果



参考资料:http://blog.csdn.net/rexuefengye/article/details/12704821,感谢热血枫叶博主的精彩博文。



0 0
原创粉丝点击