成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

設計模式系列—備忘錄模式

開發 前端
本篇和大家一起來學習備忘錄模式相關內容。

 模式定義

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,以便以后當需要時能將該對象恢復到原先保存的狀態。該模式又叫快照模式。

模版實現如下:

  1. package com.niuh.designpattern.memento.v1; 
  2.  
  3. /** 
  4.  * <p> 
  5.  * 備忘錄模式 
  6.  * </p> 
  7.  */ 
  8. public class MementoPattern { 
  9.     public static void main(String[] args) { 
  10.         Originator or = new Originator(); 
  11.         Caretaker cr = new Caretaker(); 
  12.         or.setState("S0"); 
  13.         System.out.println("初始狀態:" + or.getState()); 
  14.         cr.setMemento(or.createMemento()); //保存狀態       
  15.         or.setState("S1"); 
  16.         System.out.println("新的狀態:" + or.getState()); 
  17.         or.restoreMemento(cr.getMemento()); //恢復狀態 
  18.         System.out.println("恢復狀態:" + or.getState()); 
  19.     } 
  20.  
  21. //備忘錄 
  22. class Memento { 
  23.     private String state; 
  24.  
  25.     public Memento(String state) { 
  26.         this.state = state; 
  27.     } 
  28.  
  29.     public void setState(String state) { 
  30.         this.state = state; 
  31.     } 
  32.  
  33.     public String getState() { 
  34.         return state; 
  35.     } 
  36.  
  37. //發起人 
  38. class Originator { 
  39.     private String state; 
  40.  
  41.     public void setState(String state) { 
  42.         this.state = state; 
  43.     } 
  44.  
  45.     public String getState() { 
  46.         return state; 
  47.     } 
  48.  
  49.     public Memento createMemento() { 
  50.         return new Memento(state); 
  51.     } 
  52.  
  53.     public void restoreMemento(Memento m) { 
  54.         this.setState(m.getState()); 
  55.     } 
  56.  
  57. //管理者 
  58. class Caretaker { 
  59.     private Memento memento; 
  60.  
  61.     public void setMemento(Memento m) { 
  62.         memento = m; 
  63.     } 
  64.  
  65.     public Memento getMemento() { 
  66.         return memento; 
  67.     } 

輸出結果如下:

  1. 初始狀態:S0 
  2. 新的狀態:S1 
  3. 恢復狀態:S0 

解決的問題

備忘錄模式能記錄一個對象的內部狀態,當用戶后悔時能撤銷當前操作,使數據恢復到它原先的狀態。

每個人都有犯錯誤的時候,都希望有種“后悔藥”能彌補自己的過失,讓自己重新開始,但現實是殘酷的。在計算機應用中,客戶同樣會常常犯錯誤,能否提供“后悔藥”給他們呢?當然是可以的,而且是有必要的。這個功能由“備忘錄模式”來實現。

模式組成

 

備忘錄模式的核心是設計備忘錄類以及用于管理備忘錄的管理者類。

實例說明

實例概況

 

以游戲存檔為例,看一下如何用備忘錄模式實現

使用步驟

 

步驟1:定義備忘錄角色,用于存儲角色狀態。

  1. class RoleStateMemento { 
  2.  
  3.     private int vit;    //生命力 
  4.     private int atk;    //攻擊力 
  5.     private int def;    //防御力 
  6.  
  7.     public RoleStateMemento(int vit, int atk, int def) { 
  8.         this.vit = vit; 
  9.         this.atk = atk; 
  10.         this.def = def; 
  11.     } 
  12.  
  13.     public int getVit() { 
  14.         return vit; 
  15.     } 
  16.  
  17.     public void setVit(int vit) { 
  18.         this.vit = vit; 
  19.     } 
  20.  
  21.     public int getAtk() { 
  22.         return atk; 
  23.     } 
  24.  
  25.     public void setAtk(int atk) { 
  26.         this.atk = atk; 
  27.     } 
  28.  
  29.     public int getDef() { 
  30.         return def; 
  31.     } 
  32.  
  33.     public void setDef(int def) { 
  34.         this.def = def; 
  35.     } 

步驟2:定義發起人角色(當前游戲角色),記錄當前游戲角色的生命力、攻擊力、防御力。通過saveState()方法來保存當前狀態,通過recoveryState()方法來恢復角色狀態。

  1. class GameRole { 
  2.  
  3.     private int vit;    //生命力 
  4.     private int atk;    //攻擊力 
  5.     private int def;    //防御力 
  6.  
  7.     public int getVit() { 
  8.         return vit; 
  9.     } 
  10.  
  11.     public void setVit(int vit) { 
  12.         this.vit = vit; 
  13.     } 
  14.  
  15.     public int getAtk() { 
  16.         return atk; 
  17.     } 
  18.  
  19.     public void setAtk(int atk) { 
  20.         this.atk = atk; 
  21.     } 
  22.  
  23.     public int getDef() { 
  24.         return def; 
  25.     } 
  26.  
  27.     public void setDef(int def) { 
  28.         this.def = def; 
  29.     } 
  30.  
  31.     //狀態顯示 
  32.     public void stateDisplay() { 
  33.         System.out.println("角色當前狀態:"); 
  34.         System.out.println("體力:" + this.vit); 
  35.         System.out.println("攻擊力:" + this.atk); 
  36.         System.out.println("防御力: " + this.def); 
  37.         System.out.println("-----------------"); 
  38.     } 
  39.  
  40.     //獲得初始狀態 
  41.     public void getInitState() { 
  42.         this.vit = 100; 
  43.         this.atk = 100; 
  44.         this.def = 100; 
  45.     } 
  46.  
  47.     //戰斗后 
  48.     public void fight() { 
  49.         this.vit = 0; 
  50.         this.atk = 0; 
  51.         this.def = 0; 
  52.     } 
  53.  
  54.     //保存角色狀態 
  55.     public RoleStateMemento saveState() { 
  56.         return (new RoleStateMemento(vit, atk, def)); 
  57.     } 
  58.  
  59.     //恢復角色狀態 
  60.     public void recoveryState(RoleStateMemento memento) { 
  61.         this.vit = memento.getVit(); 
  62.         this.atk = memento.getAtk(); 
  63.         this.def = memento.getDef(); 
  64.     } 

步驟3:定義管理者角色,角色狀態管理者

  1. class RoleStateCaretaker { 
  2.  
  3.     private RoleStateMemento memento; 
  4.  
  5.     public RoleStateMemento getMemento() { 
  6.         return memento; 
  7.     } 
  8.  
  9.     public void setMemento(RoleStateMemento memento) { 
  10.         this.memento = memento; 
  11.     } 

步驟4:測試輸出

  1. public class MementoPattern { 
  2.  
  3.     // 邏輯大致為打boss前存檔,打boss失敗了 
  4.     public static void main(String[] args) { 
  5.         //打boss前 
  6.         GameRole gameRole = new GameRole(); 
  7.         gameRole.getInitState(); 
  8.         gameRole.stateDisplay(); 
  9.  
  10.         //保存進度 
  11.         RoleStateCaretaker caretaker = new RoleStateCaretaker(); 
  12.         caretaker.setMemento(gameRole.saveState()); 
  13.  
  14.         //打boss失敗 
  15.         gameRole.fight(); 
  16.         gameRole.stateDisplay(); 
  17.  
  18.         //恢復狀態 
  19.         gameRole.recoveryState(caretaker.getMemento()); 
  20.         gameRole.stateDisplay(); 
  21.     } 

輸出結果

  1. 角色當前狀態: 
  2. 體力:100 
  3. 攻擊力:100 
  4. 防御力: 100 
  5. ----------------- 
  6. 角色當前狀態: 
  7. 體力:0 
  8. 攻擊力:0 
  9. 防御力: 0 
  10. ----------------- 
  11. 角色當前狀態: 
  12. 體力:100 
  13. 攻擊力:100 
  14. 防御力: 100 

優點

備忘錄模式是一種對象行為型模式,其主要優點如下。

  • 提供了一種可以恢復狀態的機制。當用戶需要時能夠比較方便地將數據恢復到某個歷史的狀態。
  • 實現了內部狀態的封裝。除了創建它的發起人之外,其他對象都不能夠訪問這些狀態信息。
  • 簡化了發起人類。發起人不需要管理和保存其內部狀態的各個備份,所有狀態信息都保存在備忘錄中,并由管理者進行管理,這符合單一職責原則。

缺點

資源消耗大。如果要保存的內部狀態信息過多或者特別頻繁,將會占用比較大的內存資源。

注意事項

  1. 為了符合迪米特法則,需要有一個管理備忘錄的類
  2. 不要在頻繁建立備份的場景中使用備忘錄模式。為了節約內存,可使用原型模式+備忘錄模式

應用場景

  1. 需要保存和恢復數據的相關場景
  2. 提供一個可回滾的操作,如ctrl+z、瀏覽器回退按鈕、Backspace鍵等
  3. 需要監控的副本場景

模式的擴展

 

在備忘錄模式中,有單狀態備份的例子,也有多狀態備份的例子。可以結合原型模式混合使用。在備忘錄模式中,通過定義“備忘錄”來備份“發起人”的信息,而原型模式的 clone() 方法具有自備份功能,所以,如果讓發起人實現 Cloneable 接口就有備份自己的功能,這時可以刪除備忘錄類,其結構如下:

源碼中的應用

  1. #Spring 
  2. org.springframework.binding.message.StateManageableMessageContext 

StateManageableMessageContext 部分源碼

  1. public interface StateManageableMessageContext extends MessageContext { 
  2.  
  3.    /** 
  4.     * Create a serializable memento, or token representing a snapshot of the internal state of this message context. 
  5.     * @return the messages memento 
  6.     */ 
  7.    public Serializable createMessagesMemento(); 
  8.  
  9.    /** 
  10.     * Set the state of this context from the memento provided. After this call, the messages in this context will match 
  11.     * what is encapsulated inside the memento. Any previous state will be overridden. 
  12.     * @param messagesMemento the messages memento 
  13.     */ 
  14.    public void restoreMessages(Serializable messagesMemento); 
  15.  
  16.    /** 
  17.     * Configure the message source used to resolve messages added to this context. May be set at any time to change how 
  18.     * coded messages are resolved. 
  19.     * @param messageSource the message source 
  20.     * @see MessageContext#addMessage(MessageResolver) 
  21.     */ 
  22.    public void setMessageSource(MessageSource messageSource); 

PS:以上代碼提交在 Github :

https://github.com/Niuh-Study/niuh-designpatterns.git

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-10-07 00:14:53

2023-10-31 09:07:16

備忘錄模式保存

2024-05-15 17:41:37

備忘錄模式多線程

2023-04-19 08:03:52

Go設計模式

2025-02-17 14:48:14

2018-12-24 21:40:12

2014-04-17 10:30:41

Linux 命令黑白備忘錄

2023-10-10 15:26:30

內存泄露OOM

2017-03-21 11:02:59

基礎深度學習備忘錄

2011-08-16 18:38:23

Core Animat動畫

2011-04-11 10:03:32

錢伯斯思科

2022-01-12 13:33:25

工廠模式設計

2020-11-04 08:54:54

狀態模式

2020-11-03 13:05:18

命令模式

2020-10-23 09:40:26

設計模式

2018-06-20 13:14:16

MySQL數據優化查詢備忘錄

2013-08-29 10:50:48

移動網站性能優化移動web

2016-03-03 10:09:26

2021-09-29 13:53:17

抽象工廠模式

2022-01-14 09:22:22

設計模式橋接
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精久久久久久 | 91电影 | 夜夜精品视频 | 久久久激情 | 国产在线视频一区 | 免费国产视频在线观看 | 蜜桃一区二区三区在线 | 99热在这里只有精品 | 欧美极品在线观看 | 国产欧美精品在线观看 | 狠狠干天天干 | 97视频在线观看网站 | 国产色婷婷 | 久久伊 | 中文字幕国产视频 | 夜久久| 国产精品视屏 | 91p在线观看 | 久久久999精品 | 成人小视频在线观看 | 国产精品一区二区三区免费观看 | 91福利网址 | 久久天堂网| 可以在线看的黄色网址 | 日韩毛片在线免费观看 | 成人午夜视频在线观看 | 国产91丝袜在线18 | 日韩中文在线 | 国产日韩欧美一区 | 亚洲国产精品视频一区 | 国产偷录叫床高潮录音 | 色影视| 亚洲色视频 | 播放一级毛片 | 久亚州在线播放 | 视频在线日韩 | 亚洲综合在线播放 | 日韩有码在线观看 | 四虎影院在线观看免费视频 | 久久高清亚洲 | 九色网址 |