您可於此 design_pattern repo 下載 Design Pattern 系列程式碼。
需求
我們的任務是設計一個文字編輯器,需求如下:
- 使用者可以輸入文字,並隨時按下
Ctrl+Z
回復上一步。 - 系統需要保存歷史狀態以供回復。
- 客戶端不需要了解狀態保存的實現細節,只需使用一個簡單的回復操作即可。
物件導向分析 (OOA)
理解需求後,讓我們來快速實作物件導向分析吧!
察覺 Forces
在未使用設計模式的情況下,我們可能面臨以下挑戰:
-
資料喪失風險 (Data Loss Risk):
- 如果我們僅保留當前狀態,將無法回復到之前的狀態。
-
高耦合性 (High Coupling):
- 客戶端需要直接操作狀態管理邏輯,導致複雜性增加。
-
難以擴展 (Hard to Extend):
- 新增功能或改變狀態保存方式時,可能需要修改大量程式碼。
套用 Memento Pattern (Solution) 得到新的 Context (Resulting Context)
做完 OOA,察覺 Forces,看清楚整個 Context 後,就可以來套用 Memento Pattern 解決這個問題
先來看一下 Memento Pattern 的 UML
備忘錄模式引入了三個角色:
- Originator (發起者):保存當前狀態到備忘錄,或從備忘錄中恢復狀態。
- Memento (備忘錄):存儲 Originator 的內部狀態。
- Caretaker (管理者):負責保存和恢復備忘錄,但不直接操作其內容。
將 Memento Pattern 套用到我們的應用吧
物件導向程式設計 (OOP)
Originator
class TextEditor {
private var text: String = ""
fun type(newText: String) {
text += newText
}
fun getText(): String = text
fun save(): Memento = Memento(text)
fun restore(memento: Memento) {
text = memento.getText()
}
data class Memento(private val state: String) {
fun getText(): String = state
}
}
Caretaker
class History {
private val mementos = mutableListOf<TextEditor.Memento>()
fun save(memento: TextEditor.Memento) {
mementos.add(memento)
}
fun undo(): TextEditor.Memento? {
if (mementos.isNotEmpty()) {
return mementos.removeAt(mementos.size - 1)
}
return null
}
}
Client
fun main() {
val textEditor = TextEditor()
val history = History()
// Typing string
textEditor.type("Hello")
history.save(textEditor.save())
textEditor.type(", World")
history.save(textEditor.save())
textEditor.type("! This is Memento Pattern.")
println("Current Text:${textEditor.getText()}") // Output: Hello, World! This is Memento Pattern.
// Pressed Ctrl+Z
textEditor.restore(history.undo()!!)
println("Excute undo Text:${textEditor.getText()}") // Output: Hello, World!
// Pressed Ctrl+Z again
textEditor.restore(history.undo()!!)
println("Excute undo Text:${textEditor.getText()}") // Output: Hello
}
Output
Current Text: Hello, World! This is Memento Pattern.
Excute undo Text: Hello, World!
Excute undo Text: Hello
結論
透過備忘錄模式,我們成功實現了文字編輯器的狀態恢復功能,讓使用者能夠輕鬆地回復到之前的操作狀態。這種模式廣泛應用於文字處理器、遊戲保存系統以及其他需要狀態恢復的場景。
Leave a comment