C++設計模式-Memento備忘錄模式


Memento模式
作用:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣以后就可將該對象恢復到原先保存的狀態。

UML圖



Originator:負責創建一個備忘錄Memento,用以記錄當前時刻它的內部狀態,並可使用備忘錄恢復內部狀態。Originator可根據需要決定Memento存儲Originator的哪些內部狀態。

Memento:負責存儲Originator對象的內部狀態,並可防止Originator以外的其他對象訪問備忘錄Memento。備忘錄有兩個接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對象。Originator能夠看到一個寬接口,允許它訪問返回到先前狀態所需的所有數據。

Caretaker:負責保存好備忘錄Memento,不能對備忘錄的內容進行操作或檢查。

Memento模式中封裝的是需要保存的狀態,當需要恢復的時候才取出來進行恢復.原理很簡單,實現的時候需要注意一個地方:窄接口和寬接口.所謂的寬接口就是一般意義上的接口,把對外的接口作為public成員;而窄接口反之,把接口作為private成員,而把需要訪問這些接口函數的類作為這個類的友元類,也就是說接口只暴露給了對這些接口感興趣的類,而不是暴露在外部.下面的實現就是窄實現的方法來實現的.

Memento模式比較適用於功能比較復雜的,但需要維護或記錄歷史屬性的類,或者需要保存的屬性只是眾多屬性中的一小部分時,Originator可以根據保存的Memento信息還原到前一狀態。

如果在某個系統中使用命令模式時,需要實現命令的撤銷功能,那么命令模式可以使用備忘錄模式來存儲可撤銷操作的狀態。

代碼如下

Memento.h

 1 #ifndef _MEMENTO_H_
 2 #define _MEMENTO_H_
 3 #include <string>
 4 
 5 using namespace std;
 6 
 7 //負責存儲Originator對象的內部狀態,並可防止Originator以外的其他對象訪問備忘錄Memento。
 8 //備忘錄有兩個接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對象。Originator能夠看到一個寬接口,允許它訪問返回到先前狀態所需的所有數據。
 9 class Memento
10 {
11 private:
12     //將Originator為friend類,可以訪問內部信息,但是其他類不能訪問
13     friend class Originator;
14     Memento(const string& state);
15     ~Memento();
16     void SetState(const string& state);
17     string GetState();
18     string _state;
19 };
20 
21 //負責創建一個備忘錄Memento,用以記錄當前時刻它的內部狀態,並可使用備忘錄恢復內部狀態
22 class Originator
23 {
24 public:
25     Originator();
26     Originator(const string& state);
27     ~Originator();
28     void RestoreToMemento(Memento* pMemento);
29     Memento* CreateMemento();
30     void SetState(const string& state);
31     string GetState();
32     void show();
33 protected:
34 private:
35     string _state;
36 };
37 
38 //負責保存好備忘錄Memento,不能對備忘錄的內容進行操作或檢查
39 class Caretaker
40 {
41 public:
42     Caretaker();
43     ~Caretaker();
44     void SetMemento(Memento*);
45     Memento* GetMemento();
46 private:
47     Memento* _memento;
48 };
49 
50 #endif

Memento.cpp

 1 #include "Memento.h"
 2 #include <iostream>
 3 #include <string>
 4 
 5 using namespace std;
 6 
 7 Memento::Memento(const string& state)
 8 {
 9     this->_state = state;
10 }
11 
12 Memento::~Memento()
13 {}
14 
15 string Memento::GetState()
16 {
17     return this->_state;
18 }
19 
20 void Memento::SetState(const string& state)
21 {
22     this->_state = state;
23 }
24 
25 Originator::Originator()
26 {}
27 
28 Originator::Originator(const string& state)
29 {
30     this->_state = state;
31 }
32 
33 Originator::~Originator()
34 {}
35 
36 string Originator::GetState()
37 {
38     return this->_state;
39 }
40 
41 void Originator::show()
42 {
43     cout << this->_state << endl;
44 }
45 
46 void Originator::SetState(const string& state)
47 {
48     this->_state = state;
49 }
50 
51 Memento* Originator::CreateMemento()
52 {
53     return new Memento(this->_state);
54 }
55 
56 void Originator::RestoreToMemento(Memento* pMemento)
57 {
58     this->_state = pMemento->GetState();
59 }
60 
61 Caretaker::Caretaker()
62 {}
63 
64 Caretaker::~Caretaker()
65 {}
66 
67 Memento* Caretaker::GetMemento()
68 {
69     return this->_memento;
70 }
71 
72 void Caretaker::SetMemento(Memento* pMemento)
73 {
74     this->_memento = pMemento;
75 }

main.cpp

 1 #include "Memento.h"
 2 
 3 int main()
 4 {
 5     //初始化對象,狀態為“Old”
 6     Originator* o = new Originator("Old");
 7     o->show();
 8 
 9     //建立並保存Memento
10     Caretaker* pTaker = new Caretaker();
11     pTaker->SetMemento(o->CreateMemento());
12 
13     //改變狀態
14     o->SetState("New");
15     o->show();
16 
17     //恢復狀態
18     o->RestoreToMemento(pTaker->GetMemento());
19     o->show();
20 
21     return 0;
22 }

結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM