av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Go設計模式--備忘錄模式,帶暫存的業(yè)務功能可以參考它來實現(xiàn)

大家好,這里是每周都在陪你一起進步的網(wǎng)管~!今天繼續(xù)學習設計模式—備忘錄模式

創(chuàng)新互聯(lián)云計算的互聯(lián)網(wǎng)服務提供商,擁有超過13年的服務器租用、電信內(nèi)江機房、云服務器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗,已先后獲得國家工業(yè)和信息化部頒發(fā)的互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務許可證。專業(yè)提供云主機、虛擬主機、域名申請、VPS主機、云服務器、香港云服務器、免備案服務器等。

備忘錄模式(Memento Pattern)又叫作快照模式(Snapshot Pattern), 或令牌模式(Token Pattern), 指在不破壞封裝的前提下, 捕獲一個對象的內(nèi)部狀態(tài), 并在對象之外保存這個狀態(tài)。 這樣以后就可將該對象恢復到原先保存的狀態(tài), 屬于行為型設計模式。

備忘錄模式主要適用于以下應用場景。

  1. 需要保存歷史快照的場景。
  2. 希望在對象之外保存狀態(tài),且除了自己,其他類對象無法訪問狀態(tài)保存的具體內(nèi)容。

備忘錄模式是一種行為型設計模式。這種模式允許我們保存對象在某些關鍵節(jié)點時的必要信息,以便于在適當?shù)臅r候可以將之恢復到之前的狀態(tài)。通常它可以用來幫助設計撤銷/恢復操作。

備忘錄模式的類結(jié)構(gòu)

下面是備忘錄模式的類圖,

圖片來自https://refactoringguru.cn/design-patterns/memento,我后面實現(xiàn)的時候不會完全按照這個結(jié)構(gòu)去實現(xiàn),這里先把結(jié)構(gòu)里的各個角色給大家說清楚。

備忘錄模式中主要有這三個角色的類

  • Originator(發(fā)起者):Originator是當前的基礎對象,它會將自己的狀態(tài)保存進備忘錄,此角色可以類比博客系統(tǒng)中的文章對象
  • 發(fā)起者中要有保存方法和從備忘錄中恢復狀態(tài)的方法,保存方法會返回當時狀態(tài)組成的備忘錄對象
  • Memento(備忘錄) : 存儲著Originator的狀態(tài)的對象,類比理解即為文章對象的不同版本。
  • Caretaker(管理人):Caretaker是保存著多條備忘錄的對象,并維護著備忘錄的索引,在需要的時候會返回相應的備忘錄 -- 類比理解為博客系統(tǒng)中的編輯器對象
  • 管理者的保存和恢復操作,會代理其持有的發(fā)起者對象的保存和恢復操作,在這些代理方法中會增加對備忘錄對象列表、當前備忘錄版本的維護。

上面這個類圖結(jié)構(gòu)是實現(xiàn)備忘錄模式的最簡單方式,真實使用的時候,Caretaker,Originator、memento 這些角色可以繼續(xù)抽象出對應的接口和實現(xiàn)。這里就不搞那么復雜了,要舉的例子比較簡單,這么一拆顯得這個模式用起來特別費事兒。

其實其他設計模式也是一樣,學習的時候大家知道了它的結(jié)構(gòu)后,在實現(xiàn)應用的環(huán)節(jié)不必完完全全按照結(jié)構(gòu)一板一眼地全部進行實現(xiàn),有的應用場景并不復雜,能合并的角色可以按需進行合并。

應用舉例

場景

某線上博客平臺, 需為用戶提供在線編輯文章功能,文章主要包括標題 - title 和內(nèi)容 - content等信息。為最大程度防止異常情況導致編輯內(nèi)容的丟失, 需要提供版本暫存和Undo, Redo功能。

"版本暫存"問題可以應用備忘錄模式, 將編輯器的狀態(tài)完整保存起來(主要就是編輯內(nèi)容),Undo和Redo的本質(zhì), 是在歷史版本中前后移動把當時保存的內(nèi)容加載到文章對象上。

方案設計

  • IEditor: 定義編輯器接口
  • EditorMemento: 定義編輯器的備忘錄, 也就是編輯器的內(nèi)部狀態(tài)數(shù)據(jù)模型, 同時也對應一個歷史版本
  • Editor: 編輯器類, 實現(xiàn)IEditor接口

這個例子里我們把原發(fā)器和管理人兩個角色集中在Editor類型上一起實現(xiàn),例子比較簡單,就沒有單獨實現(xiàn)一個Article類型作為原發(fā)器角色,如果你想完全按照備忘錄模式的結(jié)構(gòu)實現(xiàn),把Title、Content這寫屬性和Save方法抽離到單獨的Article類型上,再讓Editor嵌套組合Article即可。

下面我們根據(jù)UML類圖實現(xiàn)一下這個帶Undo、Redo功能的編輯器。

代碼實現(xiàn)

首先在IEditor 接口里定義編輯器對象要實現(xiàn)的行為

// 編輯器接口定義
type IEditor interface {
Title(title string)
Content(content string)
Save()
Undo() error
Redo() error
Show()
}

接下來定義編輯器的備忘錄, 也就是編輯器的內(nèi)部狀態(tài)數(shù)據(jù)模型, 同時也對應一個歷史版本。

"本文使用的完整可運行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設計模式】即可領取"
type Memento struct {
title string
content string
createTime int64
}

func newMemento(title string, content string) *Memento {
return &Memento{
title, content, time.Now().Unix(),
}
}

然后是最復雜的Editor實現(xiàn),它會實現(xiàn)上面IEditor接口中定義的所有行為,其中的Undo、Redo方法即回退、前進方法在實現(xiàn)的時候就是依賴的它內(nèi)部記錄的一組Memento對象,通過指向不同的Memento對象來實現(xiàn)回退和前進功能。

"本文使用的完整可運行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設計模式】即可領取"
// 編輯器類, 實現(xiàn)IEditor接口
type Editor struct {
title string
content string
versions []*Memento
index int
}

func NewEditor() IEditor {
return &Editor{
"", "", make([]*Memento, 0), 0,
}
}

func (editor *Editor) Title(title string) {
editor.title = title
}

func (editor *Editor) Content(content string) {
editor.content = content
}

func (editor *Editor) Save() {
it := newMemento(editor.title, editor.content)
editor.versions = append(editor.versions, it)
editor.index = len(editor.versions) - 1
}

func (editor *Editor) Undo() error {
return editor.load(editor.index - 1)
}

func (editor *Editor) load(i int) error {
size := len(editor.versions)
if size <= 0 {
return errors.New("no history versions")
}

if i < 0 || i >= size {
return errors.New("no more history versions")
}

it := editor.versions[i]
editor.title = it.title
editor.content = it.content
editor.index = i
return nil
}

func (editor *Editor) Redo() error {
return editor.load(editor.index + 1)
}

func (editor *Editor) Show() {
fmt.Printf("MockEditor.Show, title=%s, cnotallow=%s\n", editor.title, editor.content)
}

最后我們來測試一下Editor的版本記錄功能

"本文使用的完整可運行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設計模式】即可領取"
func main() {
editor := NewEditor()

// test save()
editor.Title("唐詩")
editor.Content("白日依山盡")
editor.Save()

editor.Title("唐詩 登鸛雀樓")
editor.Content("白日依山盡, 黃河入海流. ")
editor.Save()

editor.Title("唐詩 登鸛雀樓 王之渙")
editor.Content("白日依山盡, 黃河入海流。欲窮千里目, 更上一層樓。")
editor.Save()

// test show()
fmt.Println("-------------Editor 當前內(nèi)容-----------")
editor.Show()

fmt.Println("-------------Editor 回退內(nèi)容-----------")
for {
e := editor.Undo()
if e != nil {
break
} else {
editor.Show()
}
}

fmt.Println("-------------Editor 前進內(nèi)容-----------")
for {
e := editor.Redo()
if e != nil {
break
} else {
editor.Show()
}
}
}

運行程序后會有類似下面的顯示


分享文章:Go設計模式--備忘錄模式,帶暫存的業(yè)務功能可以參考它來實現(xiàn)
網(wǎng)頁路徑:http://uogjgqi.cn/article/djeiooo.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流