《golang設計模式》第三部分·行為型模式-06-備忘錄模式(Memento)

文章目錄

  • 1. 概述
    • 1.1 角色
    • 1.2 類圖
  • 2. 代碼示例
    • 2.1 設計
    • 2.2 代碼
    • 2.3 類圖

1. 概述

備忘錄(Memento)用于在不破壞目標對象封裝特性的基礎上,將目標對象內部的狀態存儲到外部對象中,以備之后恢復狀態時使用。

1.1 角色

  • Originator(發起者):當前的基礎對象,它會將自己的狀態保存進備忘錄。
    • savememento()方法:Originator通過該方法將它自己狀態保存進一個備忘錄對象。
    • restorememento()方法:Originator通過該方法將它自己狀態回滾至指定備忘錄。
  • Memento(備忘錄) : 存儲Originator狀態的對象
  • Caretaker(管理者):保存多條備忘錄的對象,并維護著備忘錄的索引,在需要的時候會返回相應的備忘錄。

1.2 類圖

Originator
-state:State
+RestoreState(m:Memento)
+CreateMemento()
Memento
-state:State
+GetState()
Caretaker
+StoreMemento(m:Memento)
+GetMemento(c:Condition)

2. 代碼示例

2.1 設計

  • 定義備忘錄memento來記錄發起者狀態
  • 它的Get()方法獲取它的狀態
  • 定義發起者Originator
    • 它的方法 CreateMemento() 用它自己創建一條備忘錄
    • 它的方法 RollBack() 將它自己回滾至指定備忘錄的狀態
    • 它的Set()方法可以設置它的狀態
    • 它的Get()方法可以獲取它的狀態
  • 創建一個管理者Caretaker,它是備忘錄Memento的聚合
    • 它的AddMemento方法,向它自身加入一條備忘錄
    • 它的GetMemento()方法,查詢一條它管理的指定備忘錄
  • 調用
    • 初始化
      • 實例化一個管理者caretaker
      • 實例化一個發起者originator
    • 創建備忘錄測試
      • 第一次
        • 用發起者創建一條備忘錄
        • 管理者收錄該備忘錄
      • 第二次
        • 改變發起者狀態
        • 用發起者創建一條新備忘錄
        • 管理者收錄該備忘錄
      • 第三次
        • 改變發起者狀態
        • 用發起者創建一條新備忘錄
        • 管理者收錄該備忘錄
      • 查看管理者信息,應該有三條備忘錄
    • 回滾測試
      • 從管理者獲取指定索引的備忘錄
      • 將發起者回滾至該備忘錄狀態

2.2 代碼

  • 代碼
package mainimport "fmt"// 定義備忘錄
type Memento struct {state string
}// 查備忘錄狀態
func (m *Memento) Get() string {return m.state
}// 定義發起者
type Originator struct {state string
}// 根據發起者狀態創建一條備忘錄
func (e *Originator) CreateMemento() (memento *Memento) {memento = &Memento{state: e.state}fmt.Printf("創建一條備忘錄:%+v\n", memento)return memento
}// 將發起者狀態回滾至指定備忘錄狀態
func (e *Originator) RollBack(m *Memento) {e.state = m.Get()fmt.Printf("發起者狀態回滾至:%v\n", e)
}// 設置發起者狀態
func (e *Originator) Set(state string) {e.state = statefmt.Println("發起者狀態更改為:", e.state)
}// 獲取發起者狀態
func (e *Originator) Get() string {fmt.Println("獲取發起者狀態為:", e.state)return e.state
}// 定義管理者,管理者是備忘錄的聚合
type Caretaker struct {mementoArray []*Memento
}// 向管理者中添加一條備忘錄
func (c *Caretaker) AddMemento(m *Memento) {fmt.Printf("向管理者中添加一條備忘錄:%+v\n", m)c.mementoArray = append(c.mementoArray, m)
}// 獲取指定備忘錄信息
func (c *Caretaker) GetMemento(index int) *Memento {fmt.Printf("獲取到第 %d 條備忘錄信息為:%+v\n", index, c.mementoArray[index])return c.mementoArray[index]
}func main() {//實例化一個管理者caretaker := &Caretaker{mementoArray: make([]*Memento, 0),}//實例化一個發起者originator := &Originator{state: "A",}//為發起者創建一條備忘錄memento0 := originator.CreateMemento()//在管理者中加入該備忘錄caretaker.AddMemento(memento0)//改變發起者狀態originator.Set("B")//為發起者創建第二條備忘錄memento1 := originator.CreateMemento()//在管理者中加入該備忘錄caretaker.AddMemento(memento1)//再次改變發起者狀態originator.Set("C")//為發起者創建第三條備忘錄memento2 := originator.CreateMemento()//在管理者中加入該備忘錄caretaker.AddMemento(memento2)fmt.Println("此時管理者應該有三條備忘錄:")for _, memento := range caretaker.mementoArray {fmt.Printf("%+v\n", memento)}fmt.Println("=========回滾測試===========")originator.RollBack(caretaker.GetMemento(1))fmt.Println("=========回滾測試===========")originator.RollBack(caretaker.GetMemento(0))
}
  • 輸出
創建一條備忘錄:&{state:A}
向管理者中添加一條備忘錄:&{state:A} 
發起者狀態更改為: B
創建一條備忘錄:&{state:B}
向管理者中添加一條備忘錄:&{state:B} 
發起者狀態更改為: C
創建一條備忘錄:&{state:C}
向管理者中添加一條備忘錄:&{state:C} 
此時管理者應該有三條備忘錄
&{state:A}
&{state:B}
&{state:C}
=========回滾測試===========
獲取到第 1 條備忘錄信息為:&{state:B}
發起者狀態回滾至:&{B}
=========回滾測試===========
獲取到第 0 條備忘錄信息為:&{state:A}
發起者狀態回滾至:&{A}

2.3 類圖

Originator
-string:State
+CreateMemento()
+RollBack(m *Memento)
+Set(state string)
+Get()
Memento
-String:State
+Get()
Caretaker
+[]*Memento:mementoArray
+AddMemento(m *Memento)
+GetMemento(index int) : Memento

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161461.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161461.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161461.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【洛谷 B2008】計算 (a+b)×c 的值 題解(順序結構+四則運算)

計算 (ab)c 的值 題目描述 給定 3 3 3 個整數 a , b , c a,b,c a,b,c,計算表達式 ( a b ) c (ab) \times c (ab)c 的值。 輸入格式 輸入僅一行,包括三個整數 a , b , c a,b,c a,b,c,數與數之間以一個空格分開。 輸出格式 輸出一行…

如何訪問linux上的web服務

1.獲取服務運行端口 例如8080 2.如果時vmware 需要先配置轉發端口和主機ip 主機ip需要未使用的 例如: 3.查看虛擬機防火墻設置 centos8 為例 : firewall-cmd --zonepublic --list-ports 查看放通端口 如果沒有放通 firewall-cmd --zonepublic --add-p…

04 if進階

elif 否則如果 如果條件沒有滿足 會繼續進入“否則如果”里面判斷 只要滿足一個條件 條件判斷立即終止 chinese 100 if chinese 100:print("我們去迪士尼玩")elif chinese > 90:print("我們去朱雀森林公園")else:print("回家寫作業")if n…

GO MySQL數據庫操作封裝

Go 語言操作數據庫, 數據庫連接封裝: package Test_dbimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql""log""sync" )var (DB *sql.DBpoolOnce sync.Once )func NewConnection() (*sql.…

微信小程序藍牙連接 uniApp藍牙連接設備

藍牙列表期待效果 代碼 <template><view class"bluetooth-list"><view class"align-items option" style"justify-content: space-between;" v-for"item in bluetoothList" :key"item.deviceId"><vie…

游戲開發團隊配置與協作流程

游戲開發技術圖譜 - 知乎 游戲制作的流程是什么啊&#xff1f; - 知乎 系統策劃&#xff1a;一張圖梳理游戲系統的生產流程 - 知乎 游戲開發入門&#xff08;十一&#xff09;游戲引擎架構-CSDN博客

全局定制序列化

作用:將返回實體類中的屬性如果為null 變成"" package com.example.micrweb.config;import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.f…

linux驅動——原子操作

linux驅動——原子操作 原子操作 API Linux 內核定義了叫做 atomic_t 的結構體來完成整型數據的原操作&#xff0c;在使用是使用原子變量來代替整型變量。此結構體定義在 include/linux/types.h 文件中&#xff0c;定義如下&#xff1a; typedef struct {int counter; }atom…

websocket與node.js實現

什么是 websocket&#xff1f; websoket 是一種網絡通信協議&#xff0c;基于 tcp 連接的全雙工通信協議&#xff08;客戶端和服務器可以同時收發信息&#xff09;&#xff0c;值得注意的是他不基于 http 協議&#xff0c;websocket 只有在建立連接的時候使用到 http 協議進行…

Kubernetes(k8s)之Pod詳解

文章目錄 Kubernetes之Pod詳解一、Pod介紹pod結構pod定義 二、Pod配置pod基本配置鏡像拉取策略啟動命令環境變量端口設置資源配額 三、Pod生命周期創建和終止初始化容器鉤子函數容器探測重啟策略 四、Pod調度定向調度NodeNameNodeSelector 親和性調度NodeAffinityPodAffinityPo…

風電場葉片運輸車模型-FBX格式-帶動畫-數字孿生場景搭建

FBX格式的風電場中葉片運輸車輛模型&#xff0c;按照真實尺寸建模&#xff0c;車輛多個部位帶動畫效果&#xff0c;適用于風電場三維數字化場景和風電場數字孿生使用&#xff0c;也可以用來作為各種三維平臺的測試模型。 模型效果圖 下載地址 葉片運輸車模型下載地址

php生成xml數據

在PHP中&#xff0c;你可以使用以下幾種方法生成XML數據&#xff1a; 使用DOM擴展&#xff1a; $xml new DOMDocument(1.0, UTF-8); $root $xml->createElement(root); $xml->appendChild($root); $child $xml->createElement(child); $root->appendChild($ch…

使用 Raspberry Pi、Golang 和 HERE XYZ 制作實時地圖

到目前為止&#xff0c;您可能已經看過我的一些與 Raspberry Pi 和位置數據相關的教程。我是這些小型物聯網 (IoT) 設備的忠實粉絲&#xff0c;并編寫了有關使用 Golang 進行 WLAN 定位 和 使用 Node.js 進行 GPS 定位的教程。 我想繼續沿著 Golang 路線&#xff0c;做一個關于…

目標檢測YOLO實戰應用案例100講-基于YOLO的小目標檢測改進算法

目錄 前言 國內外研究現狀 常規尺寸目標檢測算法 小目標的檢測算法

stm32定時器輸入捕獲模式

頻率測量 頻率測量有兩種方法 測頻法&#xff1a;在閘門時間T內&#xff0c;對上升沿或下降沿計次&#xff0c;得到N&#xff0c;則評率fxN/T測周法&#xff1a;兩個上升沿內&#xff0c;以標準頻率fc計次得到N&#xff0c;則頻率fx fc/N中界頻率&#xff1a;測頻法和測周法誤…

Spark的通用運行流程與Spark YARN Cluster 模式的運行流程

Spark的通用運行流程 集群啟動后Worker節點會向Master節點心跳匯報資源Client向Driver提交APP&#xff0c;根據不同的運行模式在不同的地方創建Driver。Driver以粗粒度的方式向Master注冊應用并申請資源&#xff08;在Application執行之前&#xff0c;將所有的資源申請完畢&…

助力企業前行——ScalaSpark最佳實踐課程

時間飛逝&#xff0c;轉眼間我們的Scala&Spark培訓課程已經圓滿結束&#xff01;在這段精彩的學習旅程中&#xff0c;你們展現了堅韌、決心和追求卓越的品質。 scala(Scalable Language)是一種多范式的編程語言&#xff0c;其設計的初衷是要集成面向對象編程和函數式編程的…

Cookie與Session知識

目錄 一.Cookie與Session的發展史 1.Cookie的發展史 2.Session的發展史 3.Cookie和Session的關系 4.總結 二.Cookie與Session詳解 1.Cookie 2.Session 3.token 4.總結 三.Django操作Cookie 1.設置Cookie 2.獲取Cookie 3.設置超時時間 4.注銷Cookie 5.登錄功能實…

【機器學習】On the Identifiability of Nonlinear ICA: Sparsity and Beyond

前言 本文是對On the Identifiability of Nonlinear ICA: Sparsity and Beyond (NIPS 2022)中兩個結構稀疏假設的總結。原文鏈接在Reference中。 什么是ICA(Independent component analysis)&#xff1f; 獨立成分分析簡單來說&#xff0c;就是給定很多的樣本X&#xff0c;通…

Springboot-熱部署-IDEA2023

方式一&#xff1a;jrebel 方式二&#xff1a; 1、導入依賴 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <…