読者です 読者をやめる 読者になる 読者になる

プログラミングの魔物

エラー、バグ、仕様変更と戦うブログ

18.Memento 状態を保存する

アンドゥ(もとに戻す)、リドゥ(やり直し)、ヒストリー(履歴)、スナップショット(現在の状態の保存)の提供。
インスタンスを復元するには内部の情報にアクセスする必要がある。しかし不用意にアクセスを許可すると内部構造に依存したコードが散乱する。これをカプセル化の破壊という。
状態を保存する役割を用意して、カプセル化を破壊せずに保存と復元を行う。

f:id:p-monster:20121218195818p:plain

Originator・・・自分の状態を保存したい時にMementoを作る。Mementoを渡されるとその時の状態に戻る。
Memento・・・Originatorの内部情報をまとめる。誰にでも情報を公開するわけではない。2種類のAPIを持つ。
広いAPI・・・Originatorだけが使える、状態を元に戻すために必要な情報。
狭いAPI・・・Caretakerに見せてもいいAPI
Caretaker・・・OriginatorにMementoを作らせ、それを保持しておく役。

アクセス制御にスコープを利用し、カプセル化の破壊を防ぐ。
Mementoを複数持ったり、ファイルに保存したり。
CaretakerとOriginatorを分ける意味・・・CaretakerはMementoを保持し、使うタイミングを決める。一方OriginatorはMementoを作ったりMementoから復元したりする。
複数ステップのアンドゥを行うように変更したい
アンドゥするだけではなく、現在の状態をファイルに保存したい
このような修正を行う場合でも、Originatorの変更は不要。

関連しているパターン

Command・・・命令を処理する場合にMementoパターンを使ってアンドゥやリドゥを行える
Prototype・・・Mementoパターンはスナップショットとアンドゥのために必要な情報のみを保存する。Prototypeパターンはインスタンスのコピーを作る。
State・・・Mementoパターンではインスタンスが「状態」を表す。Stateパターンはクラスが「状態」を表す。

参考:

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門