您的位置:首页 > 编程语言 > C语言/C++

备忘录模式 C++实现

2014-09-06 14:40 302 查看
memento模式是设计模式中最枯燥的一种,没有用到继承、多态、甚至组合,方法也好理解,最不好理解的是三个角色类及其分工与配合,其中两个非常普通,originator(原发器)是产生memento的类,memento是保存状态信息和其他信息的类,而careTaker是管理memento的管理器角色。

这三个类设计非常合理,最大的工作量是careTaker的设计。redo和undo的memento都在这里存储和取回。如下面的careTaker如果仅有一个stack的话,就仅能实现undo,而不能实现redo了。

这个程序没有考虑到资源管理,引入shared_ptr显得复杂。

h文件:

#ifndef MEMENTO_H
#define MEMENTO_H

#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;

class userMemento
{
    std::string account;
    std::string pw;
    std::string telNom;
public:
    userMemento(string ac,string passw,string tel):account(ac),pw(passw),telNom(tel)
    {
    }
    std::string getAccount ( ) const
    {
        return account;
    }
    void setAccount (std::string val)
    {
        account = val;
    }

    std::string getPw ( ) const
    {
        return pw;
    }
    void setPw (std::string val)
    {
        pw = val;
    }
    std::string getTelNom ( ) const
    {
        return telNom;
    }
    void setTelNom (std::string val)
    {
        telNom = val;
    }
};

class userInfo
{
    std::string account;
    std::string pw;
    std::string telNom;
public:
    std::string getAccount ( ) const 
    { 
        return account; 
    }
    void setAccount (std::string val) 
    { 
        account = val; 
    }

    std::string getPw ( ) const 
    { 
        return pw; 
    }
    void setPw (std::string val) 
    { 
        pw = val; 
    }
    std::string getTelNom ( ) const 
    { 
        return telNom; 
    }
    void setTelNom (std::string val) 
    { 
        telNom = val; 
    }
    userMemento* crtMemento()
    {
        return new userMemento (account, pw, telNom);
    }
    void restorMemento(const userMemento* menentoP)
    {
        if(menentoP)
        {
            account = menentoP->getAccount ( );
            pw = menentoP->getPw ( );
            telNom = menentoP->getTelNom ( );
        }
        else
        {
            account.clear ( );
            pw.clear ( );
            telNom.clear();
        }
    }
    void printInfo()
    {
        std::cout << " this->account : " << this->account << std::endl;
        std::cout << " this->pw : " << this->pw << std::endl;
        std::cout << " this->telNom : " << this->telNom << std::endl;
    }
};

class careTaker
{
    typedef std::stack<userMemento*> CollType;
    CollType undo_list,redo_list;
    void emptyStack(CollType& stk)
    {
        while (!stk.empty ( ))
            stk.pop ( );
    }
public:
    void store(userMemento* um)
    {
        undo_list.push (um);
        emptyStack (redo_list);
    }
    userMemento* undo()
    {
        if (!undo_list.empty())
        {
            userMemento* um = undo_list.top ( );
            redo_list.push (um);
            undo_list.pop ( );
            return um;
        }
        return 0;
    }
    userMemento* redo()
    {
        if (!redo_list.empty())
        {
            userMemento* um = redo_list.top ( );
            undo_list.push (um);
            redo_list.pop ( );
            return um;
        }
        return 0;
    }
};

#endif //MEMENTO_H


cpp文件

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

#include "stdafx.h"
#include "memento.h"

int _tmain(int argc, _TCHAR* argv[])
{
    boost::shared_ptr<userInfo> ui(new userInfo);
    ui->setAccount ("kang");
    ui->setPw ("1234&*&7^");
    ui->setTelNom ("18949338041");
    ui->printInfo ( );

    boost::shared_ptr<careTaker> tak(new careTaker);
    tak->store (ui->crtMemento ( ));

    ui->setAccount ("li");
    ui->setPw ("4&*&7^");
    ui->setTelNom ("1891111111111");

    ui->printInfo ( );
    tak->store (ui->crtMemento ( ));

    tak->undo ( );
    ui->restorMemento (tak->undo());

    ui->printInfo ( );
    std::cout << "redo..............." << std::endl;
    ui->restorMemento (tak->redo ( ));
    ui->printInfo ( );

    ui->restorMemento (tak->redo ( ));
    ui->printInfo ( );

    ui->restorMemento (tak->redo ( ));
    ui->printInfo ( );

	return 0;
}






真实的careTaker应该是这个样子的,加入资源管理,经过智能指针的包装,才有了Java或者C#的方便,但确实累赘很多了:

class careTaker
{
    typedef boost::shared_ptr<userMemento> sharedMemento;
    typedef std::stack<sharedMemento> StackType;
    StackType undo_list,redo_list;
    void emptyStack(StackType& stk)
    {
        while (!stk.empty ( ))
            stk.pop ( );
    }
public:
    void store(sharedMemento um)
    {
        undo_list.push (um);
        emptyStack (redo_list);
    }
    sharedMemento undo()
    {
        if (!undo_list.empty())
        {
            sharedMemento um = undo_list.top ( );
            redo_list.push (um);
            undo_list.pop ( );
            return um;
        }
        return sharedMemento(0);
    }
    sharedMemento redo()
    {
        if (!redo_list.empty())
        {
            sharedMemento um = redo_list.top ( );
            undo_list.push (um);
            redo_list.pop ( );
            return um;
        }
        return sharedMemento(0);
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: