簡(jiǎn)介
聽起來特別高深笋庄,其實(shí)模式名稱已經(jīng)很形象的反映出其作用了:就是為了在某一時(shí)刻把當(dāng)前的狀態(tài)記錄下來蕊温,以后再恢復(fù)到那時(shí)的狀態(tài)跛蛋。
類型
行為型(behavioral)
場(chǎng)景
在不破壞封閉的前提下捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)蝌麸,并在該對(duì)象之外保存這個(gè)狀態(tài)拔第,從而可以將對(duì)象恢復(fù)到原先保存的狀態(tài)咕村。
正在開發(fā)一個(gè)功能,這個(gè)功能需要存檔的時(shí)候就應(yīng)該想到它蚊俺。例如游戲懈涛,文檔編輯器等等,都需要在你下次重新打開的時(shí)候恢復(fù)到你關(guān)閉它時(shí)候的狀態(tài)泳猬。
結(jié)構(gòu)
備忘錄模式有3個(gè)角色
Originator: 發(fā)起人
我們知道備忘錄模式就是要完成保存狀態(tài)批钠,然后恢復(fù)狀態(tài)的功能。那么保存和恢復(fù)誰的狀態(tài)呢得封?對(duì)了埋心,就是這個(gè)角色的狀態(tài)。
Memento: 備忘錄
這個(gè)就比較簡(jiǎn)單了忙上,就是一個(gè)存儲(chǔ)狀態(tài)的類拷呆,里面沒有業(yè)務(wù)邏輯,一般是一個(gè)POJO疫粥。
CareTaker: 管理者
負(fù)責(zé)保存和恢復(fù)Originator的狀態(tài)茬斧,狀態(tài)是保存在這類里面的。
發(fā)起人
package com.glj.webservice.demo.designPattern.Memento;
/**
* 發(fā)起人
*/
public class WordOriginator {
private int wordCount;
public WordProgressMemento saveProcess() {
return new WordProgressMemento(wordCount);
}
public void restoreProcess(WordProgressMemento memento) {
wordCount = memento.getCount();
}
//編輯文檔
public void editWord() {
System.out.println("------------------開始編輯文檔------------------");
System.out.println("當(dāng)前字?jǐn)?shù)為:"+ wordCount);
System.out.println("多寫1個(gè)字");
wordCount++;
System.out.println(String.format("總字?jǐn)?shù)為:%d", wordCount));
}
//退出編輯
public void exitWord(){
System.out.println("退出編輯");
wordCount = 0;
System.out.println("-----------------退出編輯-------------------");
}
}
備忘錄
基本上就是一個(gè)POJO梗逮。它不包含業(yè)務(wù)邏輯项秉,只包含數(shù)量數(shù)據(jù),結(jié)構(gòu)有要保存的狀態(tài)類決定慷彤。
package com.glj.webservice.demo.designPattern.Memento;
/**
* 備忘錄
*/
public class WordProgressMemento {
private int count;
public WordProgressMemento(int count) {
this.count = count;
}
public int getCount() {
return count;
}
}
管理者
管理者相對(duì)于發(fā)起人來說是一個(gè)外部組件娄蔼,它幫助發(fā)起人保存了數(shù)量,相當(dāng)于發(fā)起人將自己某一個(gè)時(shí)刻的數(shù)量保存到了外部瞬欧。
當(dāng)我們要保存數(shù)量時(shí)贷屎,使用此類的saveMemento。當(dāng)我們要恢復(fù)狀態(tài)時(shí)艘虎,使用此類的getMemento
package com.glj.webservice.demo.designPattern.Memento;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 管理者
*/
public class WordCareTaker {
public List<WordProgressMemento> memento= new ArrayList<>();
public void saveMemento(WordProgressMemento memento) {
this.memento.add(memento);
}
public WordProgressMemento getMemento(int index) {
return this.memento.get(index);
}
}
客戶端使用
package com.glj.webservice.demo.designPattern;
import com.glj.webservice.demo.designPattern.Memento.WordCareTaker;
import com.glj.webservice.demo.designPattern.Memento.WordOriginator;
import com.glj.webservice.demo.designPattern.strategy.CashContext;
public class PatternTest {
public static void main(String[] args) {
//備忘錄模式
WordOriginator originator = new WordOriginator();
WordCareTaker careTaker = new WordCareTaker();
for (int i = 0; i < 5; i++) {
if(i >0){
//重新打開編輯,恢復(fù)進(jìn)度
originator.restoreProcess(careTaker.getMemento(i-1));
}
originator.editWord();
//保存進(jìn)度
careTaker.saveMemento(originator.saveProcess());
//退出編輯
originator.exitWord();
}
// //開始編輯word
// originator.editWord();
// //點(diǎn)擊保存 保存進(jìn)度
// careTaker.saveMemento(originator.saveProcess());
// //退出編輯
// originator.exitWord();
//
// //重新打開編輯咒吐,恢復(fù)進(jìn)度
// originator.restoreProcess(careTaker.getMemento(careTaker.memento.size()-1));
// originator.editWord();
//
// //保存進(jìn)度
// careTaker.saveMemento(originator.saveProcess());
// //退出編輯
// originator.exitWord();
//
// //重新打開編輯野建,恢復(fù)進(jìn)度
// originator.restoreProcess(careTaker.getMemento(careTaker.memento.size()-1));
// originator.editWord();
}
}
輸出結(jié)果
------------------開始編輯文檔------------------
當(dāng)前字?jǐn)?shù)為:0
多寫一個(gè)字
總字?jǐn)?shù)為:1
退出編輯
-----------------退出編輯-------------------
------------------開始編輯文檔------------------
當(dāng)前字?jǐn)?shù)為:1
多寫一個(gè)字
總字?jǐn)?shù)為:2
退出編輯
-----------------退出編輯-------------------
------------------開始編輯文檔------------------
當(dāng)前字?jǐn)?shù)為:2
多寫一個(gè)字
總字?jǐn)?shù)為:3
退出編輯
-----------------退出編輯-------------------
------------------開始編輯文檔------------------
當(dāng)前字?jǐn)?shù)為:3
多寫一個(gè)字
總字?jǐn)?shù)為:4
退出編輯
-----------------退出編輯-------------------
------------------開始編輯文檔------------------
當(dāng)前字?jǐn)?shù)為:4
多寫一個(gè)字
總字?jǐn)?shù)為:5
退出編輯
-----------------退出編輯-------------------