Chapter18 备忘录模式

备忘录模式简介

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

把要保存的细节给封装在了Memento中了,哪一天要更改保存的细节,也不用影响客户端。

Momento模式比较适用于功能比较复杂的,但需要维护或记录属性性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。

使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。

我认为,其实备忘录模式和原型模式的思想类似,只不过原型模式是利用clone来达到copy所有属性,而备忘录模式是为了保存部分属性而单独建立了个备忘录类。

 

备忘录模式UML类图

 

 

C++代码实现

// Originator类,要参与备忘的主体
#ifndef _ORIGINATOR_HPP
#define _ORIGINATOR_HPP

#include<iostream>
#include<string>
#include"memento.hpp"

using namespace std;
class Originator{
public:
    Originator(string n, int a, int h, int w)
        :name(n), age(a), height(h), weight(w) {

    }
    void SetFromMemento(Memento* m){
        age = m->getAge();
        height = m->getHeight();
        weight = m->getWeight();
    }
    Memento* createMemento(){
        return new Memento(age,height, weight);
    }
    void show(){
        cout << "name: " << name << endl;
        cout << "height: " << height << endl;
        cout << "weight: " << weight << endl;
    }
    void changeContent(int a, int h, int w) {
        age = a;
        height = h;
        weight = w;
    }   

private:
    string name;
    int age;
    int height;
    int weight;
};

#endif
// Memento类,存储需要备忘的属性
#ifndef _MEMENTO_HPP
#define _MEMENTO_HPP
class Memento{
public:
    Memento(int a, int h, int w):age(a),height(h),weight(w) {

    }

    int getAge(){ return age; }
    void setAge(int a){ age = a; }

    int getHeight() { return height;}
    void setHeight(int h) { height = h;}

    int getWeight() { return weight;}
    void setWeight(int w){ weight = w;}

private:
    int age;
    int height;
    int weight;
};

#endif
// Caretaker类, 存储管理备忘录
#ifndef _CARETAKER_HPP
#define _CARETAKER_HPP

#include"memento.hpp"

class Caretaker{
public:
    // get and set
    Memento* getMemento(){ return memento; } 
    void setMemento( Memento* m){ memento = m;}

private:
    Memento* memento;
};

#endif
// 客户端代码
#include<iostream>
#include"originator.hpp"
#include"memento.hpp"
#include"caretaker.hpp"

using namespace std;

int main(){
    Originator* originator = new Originator("Wang Er",18, 170, 60);
    Caretaker* caretaker = new Caretaker();
    caretaker->setMemento(originator->createMemento());
    originator->changeContent(25, 175, 80);
    originator->show();//Wang Er 25 175 80

    originator->SetFromMemento(caretaker->getMemento());
    originator->show(); // Wang Er 18 170 60 

    getchar();
    return 0;
}

 

posted @ 2020-03-27 11:08  yangbofun  阅读(152)  评论(0)    收藏  举报