o2o網(wǎng)站開發(fā)框架長春seo排名優(yōu)化
【聲明】本題目來源于卡碼網(wǎng)(題目頁面 (kamacoder.com))
【提示:如果不想看文字介紹,可以直接跳轉(zhuǎn)到C++編碼部分】
【設(shè)計模式大綱】
【簡介】
? ? ? ? -- 什么是備忘錄模式?(第17種模式)
????????備忘錄模式(Memento Pattern)是?種?為型設(shè)計模式,它允許在不暴露對象實現(xiàn)的情況下捕獲對象的內(nèi)部狀態(tài)并在對象之外保存這個狀態(tài),以便稍后可以將其還原到先前的狀態(tài)。
【基本結(jié)構(gòu)】
????????備忘錄模式包括以下?個重要??:
- 發(fā)起?Originator : 需要還原狀態(tài)的那個對象,負責創(chuàng)建?個【備忘錄】,并使?備忘錄記錄當前時刻的內(nèi)部狀態(tài)。
- 備忘錄Memento : 存儲發(fā)起?對象的內(nèi)部狀態(tài),它可以包含發(fā)起?的部分或全部狀態(tài)信息,但是對外部是不可?的,只有發(fā)起?能夠訪問備忘錄對象的狀態(tài)。
????????備忘錄有兩個接?,發(fā)起?能夠通過寬接?訪問數(shù)據(jù),管理者只能看到窄接?,并將備忘錄傳遞給其他對象。
- 管理者Caretaker : 負責存儲備忘錄對象,但并不了解其內(nèi)部結(jié)構(gòu),管理者可以存儲多個備忘錄對象。
- 客戶端:在需要恢復狀態(tài)時,客戶端可以從管理者那?獲取備忘錄對象,并將其傳遞給發(fā)起?進?狀態(tài)的恢復。
【基本實現(xiàn)】
下面以Java代碼作以簡要說明:
1.?創(chuàng)建發(fā)起?類:可以創(chuàng)建備忘錄對象
class Originator {private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}// 創(chuàng)建備忘錄對象public Memento createMemento() {return new Memento(state);}// 通過備忘錄對象恢復狀態(tài)public void restoreFromMemento(Memento memento) {state = memento.getState();}
}
2.?創(chuàng)建備忘錄類:保存發(fā)起?對象的狀態(tài)
class Memento {private String state;// 保存發(fā)起?的狀態(tài)public Memento(String state) {this.state = state;}public String getState() {return state;}
}
3.?創(chuàng)建管理者:維護?組備忘錄對象
class Caretaker {private List<Memento> mementos = new ArrayList<>();public void addMemento(Memento memento) {mementos.add(memento);}public Memento getMemento(int index) {return mementos.get(index);}
}
4.?客戶端使用備忘錄模式
/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file MementoMode.hpp
* @brief 備忘錄模式
* @autor 寫代碼的小恐龍er
* @date 2024/01/19
*/
public class Main {public static void main(String[] args) {// 創(chuàng)建發(fā)起?對象Originator originator = new Originator();originator.setState("State 1");// 創(chuàng)建管理者對象Caretaker caretaker = new Caretaker();// 保存當前狀態(tài)caretaker.addMemento(originator.createMemento());// 修改狀態(tài)originator.setState("State 2");// 再次保存當前狀態(tài)caretaker.addMemento(originator.createMemento());// 恢復到先前狀態(tài)originator.restoreFromMemento(caretaker.getMemento(0));System.out.println("Current State: " + originator.getState());}
}
【使用場景】
????????備忘錄模式在保證了對象內(nèi)部狀態(tài)的封裝和私有性前提下可以輕松地添加新的備忘錄和發(fā)起?,實現(xiàn)“備份”,不過備份對象往往會消耗較多的內(nèi)存,資源消耗增加。
????????備忘錄模式常常?來實現(xiàn)撤銷和重做功能,?如在Java Swing GUI編程中,javax.swing.undo 包中的撤銷(undo)和重做(redo)機制使?了備忘錄模式。UndoManager 和UndoableEdit 接?是與備忘錄模式相關(guān)的主要類和接?。
【C++編碼部分】
1. 題目描述
????????小明正在設(shè)計一個簡單的計數(shù)器應用,支持增加(Increment)和減少(Decrement)操作,以及撤銷(Undo)和重做(Redo)操作,請你使用備忘錄模式幫他實現(xiàn)。
2. 輸入描述
????????輸入包含若干行,每行包含一個字符串,表示計數(shù)器應用的操作,操作包括 "Increment"、 "Decrement"、"Undo" 和 "Redo"。
3. 輸出描述
????????對于每個 "Increment" 和 "Decrement" 操作,輸出當前計數(shù)器的值,計數(shù)器數(shù)值從0開始 對于每個 "Undo" 操作,輸出撤銷后的計數(shù)器值。 對于每個 "Redo" 操作,輸出重做后的計數(shù)器值。
4. C++編碼實例
/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file MementoMode.hpp
* @brief 備忘錄模式
* @autor 寫代碼的小恐龍er
* @date 2024/01/19
*/#include <iostream>
#include <string>
#include <vector>
#include <stack>using namespace std;// 前置聲明// 備忘錄類 -- 保存發(fā)起?對象的狀態(tài)
class Memento;
// 發(fā)起人類 -- 可以創(chuàng)建備忘錄對象
class Counter;
// 管理者 -- 一組備忘錄對象
class MementoManager;// 類的定義// 備忘錄類
class Memento
{
// 成員數(shù)據(jù)
private:int _value;// 備忘錄操作的成員函數(shù)
public:Memento(int value){SetValue(value);}void SetValue(int value){this->_value = value;}int GetValue(){return this->_value;}
};// 發(fā)起人 類
class Counter
{
// 成員數(shù)據(jù)
private:int _value;// 發(fā)起人的計數(shù)值std::stack<Memento *> _undoStack; // 發(fā)起人撤銷操作的棧 std::stack<Memento *> _redoStack; // 發(fā)起人重新操作的棧// 成員函數(shù)
public:Counter(){}// 獲取值int GetValue(){return this->_value;}// 增加計數(shù)值void IncreaseValue(Memento *memento){//清空重做的棧while(!_redoStack.empty()){_redoStack.pop();}_undoStack.push(memento);_value++;}// 減少計數(shù)值void DecreaseValue(Memento *memento){//清空重做的棧while(!_redoStack.empty()){_redoStack.pop();}_undoStack.push(memento);_value--;}// 撤銷操作void Undo(Memento *memento){if(!_undoStack.empty()){_redoStack.push(memento);_value = _undoStack.top()->GetValue();}}// 重新操作void Redo(Memento *memento){if(!_redoStack.empty()){_undoStack.push(memento);_value = _redoStack.top()->GetValue();}}
};// 管理者
class MementoManager
{
// 成員數(shù)據(jù)
private:std::vector<Memento *> _mementoVec;// 成員函數(shù)
public:// 增加備忘錄void AddMemento(Memento *mento){_mementoVec.push_back(mento);}// 尋找備忘錄 按照順序 或者 備忘錄中的計數(shù)值Memento * GetMemento(int index){if(index >= _mementoVec.size()) return nullptr;else return _mementoVec[index];}
};// 客戶端
int main()
{// 操作類型string type = "";// 新建 發(fā)起人 類 Counter *counter = new Counter();// 新建備忘錄管理者MementoManager *manager = new MementoManager();// 新建備忘錄Memento *memento = nullptr;// 等待輸入指令while(std::cin >> type){if(type == "Increment"){memento = new Memento(counter->GetValue());counter->IncreaseValue(memento);}else if(type == "Decrement"){memento = new Memento(counter->GetValue());counter->DecreaseValue(memento);}else if(type == "Undo"){memento = new Memento(counter->GetValue());counter->Undo(memento);}else if(type == "Redo"){memento = new Memento(counter->GetValue());counter->Redo(memento);}// 將備忘錄添加至管理者中 【此時備忘錄管理者可以去做其他的事情】manager->AddMemento(memento);// 輸出計數(shù)器的值std::cout<< counter->GetValue() << endl;}// 析構(gòu)if(memento != nullptr){delete memento;memento = nullptr;}delete counter;counter = nullptr;delete manager;manager = nullptr;return 0;
}
......
To be continued.