1. Mementoパターンとは

Mementoパターンは、オブジェクトの内部状態を保存および復元するために使用される行動デザインパターンです。オブジェクトの状態は、将来の状態にオブジェクトを復元するために使用できるMementoオブジェクトに保存されます。

2. Mementoパターンの特性と利点

Mementoパターンの特性と利点には以下が含まれます:

  • カプセル化原則を破らずにオブジェクトの内部状態を保存および復元することができます。
  • オブジェクトの履歴的な状態を柔軟に管理することができ、取り消しややり直しの操作を便利に行えます。
  • 状態を外部に保存することで、オブジェクトの内部状態を公開することを避けることができます。

3. Mementoパターンの実用例

Mementoパターンには多くの実用的な応用シナリオがあり、その例には以下が含まれます:

  • テキストエディター内の取り消しややり直し機能は、各操作の状態を保存するためにMementoパターンを使用できます。
  • ゲーム内の保存およびロード機能は、ゲームの進行状況を保存するためにMementoパターンを使用できます。
  • メールクライアントの下書き保存機能は、下書きのメールの状態を保存するためにMementoパターンを使用できます。

4. GolangでのMementoパターンの実装

4.1. UMLクラス図

GolangにおけるMementoパターン

4.2. 例の紹介

UMLクラス図に基づく説明

この例では、"state"という内部状態を持つOriginatorクラスがあります。OriginatorはSetStateメソッドを使用して状態を設定し、CreateMementoメソッドを使用してMementoオブジェクトを作成します。Mementoオブジェクトの内部状態はOriginatorのそれと同じです。Caretakerクラスは、Mementoオブジェクトを保存し、AddMementoメソッドを使用してMementoを追加する責任があります。

実装手順

  1. Mementoオブジェクトを作成します。このオブジェクトには、Originatorの内部状態を保存するGetStateメソッドが含まれます。
  2. Originatorオブジェクトを作成します。状態を設定するためのメソッドやMementoを作成するためのメソッドが含まれます。
  3. Mementoオブジェクトを保存する責任があるCaretakerオブジェクトを作成します。
  4. Originatorで状態を作成し、復元するためのメソッドを実装します:
    • Mementoオブジェクトを作成する際に、Originatorの状態をMementoに保存します。
    • 状態を復元する際には、Mementoから状態をOriginatorに復元します。
  5. CaretakerでMementoを追加し、取得するためのメソッドを実装します:
    • Mementoを保存するためにAddMementoメソッドを使用します。
    • Mementoを取得するためにGetMementoメソッドを使用します。

4.3.1. Mementoオブジェクトを作成

type Memento struct {
	state string
}

func (m *Memento) GetState() string {
	return m.state
}

4.3.2. Mementoに状態を保存

type Originator struct {
	state string
}

func (o *Originator) SetState(state string) {
	o.state = state
}

func (o *Originator) CreateMemento() *Memento {
	return &Memento{state: o.state}
}

4.3.3. Mementoから状態を復元

func (o *Originator) SetMemento(memento *Memento) {
	o.state = memento.GetState()
}

4.3.4. 取り消し操作にMementoパターンを使用

type Caretaker struct {
	mementos []*Memento
}

func (c *Caretaker) AddMemento(m *Memento) {
	c.mementos = append(c.mementos, m)
}

func (c *Caretaker) GetMemento(index int) *Memento {
	return c.mementos[index]
}

4.3.5. やり直し操作にMementoパターンを使用する

func main() {
	originator := &Originator{}
	caretaker := &Caretaker{}

	originator.SetState("状態1")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetState("状態2")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetMemento(caretaker.GetMemento(0))
	fmt.Println("状態1に復元した後のOriginatorの状態:", originator.state)

	originator.SetMemento(caretaker.GetMemento(1))
	fmt.Println("状態2に復元した後のOriginatorの状態:", originator.state)
}