日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

备忘录模式(Memento)

發布時間:2025/5/22 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 备忘录模式(Memento) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、備忘錄模式介紹

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

例如:

1.office重新打開時的恢復功能。

2.事務的回滾操作

備忘錄模式UML圖:

Originator(發起人):負責創建一個備忘錄Memento,用以記錄當前時刻它的內部狀態,并可使用備忘錄恢復內部狀態。

Originator可根據需要決定Memento存儲Originator的哪些內部狀態

Memento(備忘錄):負責存儲Originator對象的內部狀態,并可防止Originator以外的其他對象訪問備忘錄Memento。

備忘錄有兩個接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對象。Originator能夠看到一個寬接口,允許它訪問返回到

先前狀態所需的所有數據。

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

?

二、備忘錄模式代碼實現

以一個Emp實體對象來作為例子

首先,創建一個發起人:發起人內部保存著需要備忘的屬性,它負責創建一個備忘錄Memento,用以記錄當前時刻它的內部狀態,并可使用備忘錄恢復內部狀態。

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //發起人:發起人內部有自身的內部狀態,并且發起人可以創建備忘錄和恢復備忘錄 public class EmpOriginator { ????//需要備份的自身屬性 ????private String ename; ????private int age; ????private double salary;????? ????//備份 ????public EmpMemento memento(){ ????????return new EmpMemento(this);//將當前自身對象備份 ????}????? ????//恢復 ????public void recovery(EmpMemento emp){ ????????this.ename = emp.getEname(); ????????this.age = emp.getAge(); ????????this.salary = emp.getSalary(); ????}?????? ????//省略get,set和帶參構造器?? }

創建備忘錄對象:備忘錄就是用來備份發起人的數據,所以構造器需要提供一個發起人對象

1 2 3 4 5 6 7 8 9 10 11 12 13 14 //備忘錄對象 public class EmpMemento { ????//自身屬性 ????private String ename; ????private int age; ????private double salary;? ????//構造備忘錄對象時,需要傳入一個需要備忘的對象(發起人) ????public EmpMemento(EmpOriginator emp) { ????????this.ename = emp.getEname(); ????????this.age = emp.getAge(); ????????this.salary = emp.getSalary(); ????} ????//省略3個屬性的set,get方法 }

開始創建一個備忘錄的管理者

1 2 3 4 5 6 7 8 9 10 11 //管理者:管理備忘錄對象 public class CareTaker { ????//需要管理的備忘錄對象,這里也可以使用一個list容器來存儲。這樣可以備份多個點?? ????private EmpMemento empMemento; ????public EmpMemento getEmpMemento() { ????????return empMemento; ????} ????public void setEmpMemento(EmpMemento empMemento) { ????????this.empMemento = empMemento; ????}?? }

單次備份測試:測試只能備份一次的備忘錄

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static void main(String[] args) { ????CareTaker taker = new CareTaker();//構建一個備忘錄管理者 ????//構建發起人 ????EmpOriginator emp = new EmpOriginator("張三", 20, 4000); ????System.out.println("第一次:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????//備份 ????taker.setEmpMemento(emp.memento()); ????? ????//備份完了后再修改 ????emp.setEname("李四"); ????emp.setAge(30); ????emp.setSalary(50000); ????//然后再次打印 ????System.out.println("修改后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????? ????//開始恢復 ????emp.recovery(taker.getEmpMemento()); ????System.out.println("恢復后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); }

測試結果如下:

????????????????第一次:張三---20---4000.0

????????????????修改后:李四---30---50000.0

????????????????恢復后:張三---20---4000.0

但是,這樣的效果是只能備份一次。有時候我們需要備份多個點,根據需要來還原具體哪次的數據

多次備份

使用Stack來存儲備份數據,進行多次備份。用Stack的好處是Stack是后進先出的,也就是說:你最近一次備份的數據會優先獲取到

修改管理者中的代碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import java.util.Stack; //管理者:管理備忘錄對象 public class CareTaker { ????//需要管理的備忘錄對象,這里也可以使用一個list容器來存儲。這樣可以備份多個點 ????//或者使用一個Stack棧來保存,因為Stack是后進先出的 ????private Stack<EmpMemento> stack = new Stack<EmpMemento>(); ????//備份emp數據到棧中 ????public void mementoEmp(EmpMemento emp){ ????????stack.push(emp); ????} ????//從棧中獲取最近一次備份的emp數據 ????public EmpMemento getEmpForStack(){???? ????????if (!stack.empty()) { ????????????return stack.peek();//peek只獲取,不刪除 ????????}else{ ????????????return null; ????????} ????} ????//從棧中獲取最近一次備份的emp數據,并且從棧中刪除該數據 ????public EmpMemento getEmpForStackAndRemove(){ ????????if (!stack.empty()) { ????????????return stack.pop();//pop獲取后刪除該元素 ????????}else{ ????????????return null; ????????}?????? ????}?? }

再次測試:后進先出,也就是說。恢復的話恢復的是最后一次備份的數據

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public static void main(String[] args) { ????CareTaker taker = new CareTaker();//構建一個備忘錄管理者 ????//構建發起人 ????EmpOriginator emp = new EmpOriginator("張三", 20, 4000); ????System.out.println("第一次:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????//第1次備份 ????taker.mementoEmp(emp.memento()); ????? ????//備份完了后再修改 ????emp.setEname("李四"); ????emp.setAge(30); ????emp.setSalary(50000); ????//然后再次打印 ????System.out.println("1修改后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????//第2次備份 ????taker.mementoEmp(emp.memento()); ????? ????//備份完了后再修改 ????emp.setEname("李四2"); ????emp.setAge(32); ????emp.setSalary(52000); ????//然后再次打印 ????System.out.println("2修改后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????//第3次備份 ????taker.mementoEmp(emp.memento()); ????//備份完了后再修改 ????emp.setEname("李四3"); ????emp.setAge(33); ????emp.setSalary(32000); ????//然后再次打印 ????System.out.println("3修改后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); ????//第4次備份 ????taker.mementoEmp(emp.memento()); ????? ????//開始恢復 ????emp.recovery(taker.getEmpForStack());//恢復的是第4次備份的數據(3修改后) ????System.out.println("恢復后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary()); }

測試結果如下:

????????????第一次:張三---20---4000.0

????????????1修改后:李四---30---50000.0

????????????2修改后:李四2---32---52000.0

????????????3修改后:李四3---33---32000.0

????????????恢復后:李四3---33---32000.0

當然,也可以恢復之后把它從棧中刪除。

測試:恢復之前從棧中刪除兩個最近的數據

1 2 3 4 5 //開始恢復 taker.getEmpForStackAndRemove();//刪除最近一次的備份 taker.getEmpForStackAndRemove();//刪除最近一次的備份 emp.recovery(taker.getEmpForStack());//此時獲取的是原來未刪除時倒數第二次的備份 System.out.println("恢復后:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());

此時的結果就是如下:可見,這里已經把2和3給刪除了

????????????????第一次:張三---20---4000.0

????????????????1修改后:李四---30---50000.0

????????????????2修改后:李四2---32---52000.0

????????????????3修改后:李四3---33---32000.0

????????????????恢復后:李四---30---50000.0

?

三、總結

開發中常見場景:

棋類游戲中的悔棋操作

軟件中的撤銷操作

數據庫中的事務回滾操作

常用軟件中的歷史記錄功能

?

?



Java23種設計模式學習筆記【目錄總貼】

參考資料:

  大話設計模式(帶目錄完整版).pdf

  HEAD_FIRST設計模式(中文版).pdf

  尚學堂_高淇_java300集最全視頻教程_【GOF23設計模式】



轉載于:https://www.cnblogs.com/meet/p/5116407.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的备忘录模式(Memento)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。