行为设计模式---备忘录模式(Memento)

来源:互联网 发布:如何识别淘宝出售假货 编辑:程序博客网 时间:2024/05/19 14:18

备忘录模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可将该对象恢复到原先保存的状态。

Memento.h

#ifndef _MEMENTO_H_
#define _MEMENTO_H_

class Number;

class Memento
{
public:
    Memento(int state);

private:
    friend class Number;
    int state_;

};

class Number
{
public:
    Number(int value);
    void doub();
    void half();
    int getValue();
    Memento * createMemento();
    void reinstateMemento(Memento *mem);

private:
    int value_;

};

class Command
{
public:
   typedef void (Number:: *Action)();
   Command(Number *receiver, Action action);
   virtual void execute();
   static void undo();
   static void redo();
   static void destroy();

protected:
   Number *receiver_;
   Action action_;
   static Command *commandList[20];
   static Memento* mementoList[20];
   static int numCommands_;
   static int highWater_;

};

#endif
     
Memento.cpp

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

using std::cout;
using std::endl;

Memento::Memento(int state) : state_(state)
{
}

Number::Number(int value) : value_(value)
{
}

void Number::doub()
{
     value_ =  value_ * 2.0;
}

void Number::half()
{
     value_ =  value_ / 2.0;
}

int Number::getValue()
{
    return value_;
}

Memento * Number::createMemento()
{
    return new Memento(value_);
}

void Number::reinstateMemento(Memento *mem)
{
     value_ = mem->state_;
}

Command * Command::commandList[20] = { NULL };
Memento * Command::mementoList[20] = { NULL };
int Command::numCommands_ = 0;
int Command::highWater_ = 0;

Command::Command(Number *receiver, Action action)
{
    receiver_ = receiver;
    action_ = action;
}

void Command::execute()
{
     mementoList[numCommands_] = receiver_->createMemento();
     commandList[numCommands_] = this;
     if (numCommands_ > highWater_)
        highWater_ = numCommands_;
     ++numCommands_;
     (receiver_->*action_)();
}

void Command::undo()
{
     if (0 == numCommands_)
     {
         cout << "Attempt to run off the end" << endl;
         return ;
     }
     commandList[numCommands_-1]->receiver_->reinstateMemento(
          mementoList[numCommands_-1]);
     --numCommands_;
}

void Command::redo()
{
    if (numCommands_ > highWater_)
    {
        cout << "Attemp to run off the end" << endl;
        return ;
    }
    (commandList[numCommands_]->receiver_->*(commandList[numCommands_]
             ->action_))();
    ++numCommands_;
}

void Command::destroy()
{
    for (int i = 0; i < 20; ++i)
        if (NULL != mementoList[i])
        {
                delete mementoList[i];
                mementoList[i] = NULL;
        }
}

main.cpp

#include <iostream>
#include "Memento.h"
using std::cout;
using std::cin;
using std::endl;

int main()
{
    int i;
    cout << "input an integer: ";
    cin>>i;
    Number *obj = new Number(i);
    Command * cmd[3];
    cmd[1] = new Command(obj, &Number::doub);
    cmd[2] = new Command(obj, &Number::half);
    cout << "Exit[0], Doub[1], Half[2], Undo[3], Redo[4]: " << endl;
    cin >> i;
    while (i)
    {
       if (3 == i)
          Command::undo();
       else if (4 == i)
          Command::redo();
       else if (1 == i || 2 == i)
          cmd[i]->execute();
       cout << obj->getValue() << endl;
       cout << "Exit[0], Doub[1], Half[2], Undo[3], Redo[4]: ";
       cin >> i;
     }

     Command::destroy();
     if (NULL != obj)
     {
         delete obj;
         obj = NULL;
     }

     if (NULL != cmd[1])
     {
         delete cmd[1];
         cmd[1] = NULL;
     }

     if (NULL != cmd[2])
     {
         delete cmd[2];
         cmd[2] = NULL;
     }

     return 0;
}

Makefile

cc=g++
exe=main
obj= main.o Memento.o
$(exe): $(obj)
        $(cc) -g -o $(exe) $(obj)
main.o: main.cpp Memento.h
        $(cc) -g -c main.cpp
Memento.o: Memento.cpp Memento.h
        $(cc) -g -c Memento.cpp
clean:
        rm -rf *o $(exe)

0 0
原创粉丝点击