備忘錄模式 C++實現

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);
    }
};



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章