当前位置:编程学习 > C/C++ >>

[设计模式]备忘录

我们经常遇到将一个类的状态恢复到历史版本的需求。比如一个记事本,想保存一个上N个状态,通过Ctrl+Z可以恢复此前编辑内容。备忘录就非常适合这种场景。此时发起者类,希望能够将自身状态保留在某处,而且不希望过多的暴露细节。为了上述目的,发起者会在某个时刻通过new出一个备忘类对象,并将该对象托管给管理者类。然后需要恢复状态时,又从管理者类中获取具体状态,将自身恢复到某个状态。

为了保持封装性,备忘录一般除了将自己暴露给发起者外(或者可以认为是发起者将自己状态暴露给了备忘类),不为外部类提供任何访问状态相关接口。C++中这个通常是通过将自己所有接口都改成private(包括构造函数),然后将发起者设为自己的友元类来实现。

写了个demo,可以支持多个版本:


[cpp]
/***************************************************************************
 * 
 * Copyright (c) 2013 itegel.com, Inc. All Rights Reserved
 * 
 **************************************************************************/ 
  
  
  
/**
 * @file test_memento.cpp
 * @author itegel
 * @date 2013/06/08 11:29:08
 * @brief 
 *  
 **/ 
 
#include <string>  
#include <map>  
#include <iostream>  
using namespace std; 
 
class State{ 
    public: 
        int version; 
        string content; 
}; 
 
class Memento{ 
    public: 
    private: 
        friend class NoteBook; 
        Memento(State state) : _state(state){} 
        ~Memento(){} 
 
        State * GetState(){ 
            return &_state; 
        } 
        void SetState(State state){ 
            _state = state; 
        } 
        State _state; 
}; 
 
//originator  
class NoteBook{ 
    public: 
        NoteBook(int version, string content){ 
            _state.version = version; 
            _state.content = content;             
        } 
         
        NoteBook(State & state):_state(state){ 
                     
        } 
         
        void SetMemento(Memento * mem){ 
            _state = mem->_state; 
        } 
 
        Memento * GetMemento(){ 
            return new Memento(_state); 
        } 
 
        void SetState(int version, string content){ 
            _state.version = version; 
            _state.content = content; 
        } 
         
        int GetVersion(){ 
            return _state.version; 
        } 
 
        void PrintState(){ 
            cout<<"Note:\n\tversion:\t"<<_state.version<<endl<<"\tcontent:\t"<<_state.content<<endl; 
        } 
 
    private: 
        State _state; 
}; 
 
 
class CareTaker{ 
    public: 
        CareTaker(){} 
        void Save(int id, Memento * mem){ 
            _memento_map[id] = mem; 
        } 
        Memento * GetMemento(int id){ 
            return _memento_map[id]; 
        } 
    private: 
        map<int, Memento *> _memento_map; 
}; 
 
int main(){ 
    NoteBook my_note(0, ""); 
    CareTaker care_taker; 
 
    my_note.PrintState(); 
    cout<<"Save State 0!"<<endl; 
    care_taker.Save(my_note.GetVersion(), my_note.GetMemento()); 
 
    cout<<endl<<"Edit for 1st time!"<<endl; 
    my_note.SetState(1, "Hello world!"); 
    my_note.PrintState(); 
    care_taker.Save(my_note.GetVersion(), my_note.GetMemento()); 
     
    cout<<endl<<"Edit for 2nd time!"<<endl; 
    my_note.SetState(2, "Hello World! It is the 2nd version!"); 
    my_note.PrintState(); 
    care_taker.Save(my_note.GetVersion(), my_note.GetMemento()); 
     
    cout<<endl<<"Edit for 3rd time!"<<endl; 
    my_note.SetState(3, "Hello Itegel! It is the 3rd version!"); 
    my_note.PrintState(); 
    care_taker.Save(my_note.GetVersion(), my_note.GetMemento()); 
 
 
    cout<<endl<<"Restore 2nd version:"<<endl; 
    Memento * mem = care_taker.GetMemento(2); 
    my_note.SetMemento(mem); 
    my_note.PrintState(); 
     
    cout<<endl<<"Restore 0 version:"<<endl; 
    mem = care_taker.GetMemento(0); 
   

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,