Mementoパターン
Mementoパターンは、ある時点のオブジェクトの状態を保存し、アンドゥ・ロールバックを行えるようにするデザインパターンです。
自分なりにMementoパターンをクラス図にまとめてみました。
Mementoパターンのクラス図
Mementoパターンのクラス図の解説
クラス図のOriginatorクラスが状態を保存しておきたいオブジェクトです。保存したいタイミングで、createMementoメソッドを実行し、Mementoオブジェクトを生成します。このとき、属性stateの値をMementoオブジェクトの属性stateにセットしておきます。生成したMementoオブジェクトをCareTakerのsetMementoメソッドに渡すと、CareTakerオブジェクトのmemento属性にセットされます。
その後Originatorのstateの値が変化し、先ほど保存した状態に戻したくなったとします。
その場合は、CareTakerのgetMementoメソッドを実行すると、保存していたmementoを返します。そのmementoをOriginatorのrestoreFromMementoの引数に渡すと、引数のMementoオブジェクトのstate属性がOriginatorのstate属性に代入され、もとの状態に戻すことができます。
上記例のクラス図では属性がstateだけでしたが、他にも属性があれば、その属性を各々セットし直す必要があります。また、CareTakerのmemento属性をMementoの配列型にすれば、複数履歴を保持しておくことができます。
Mementoオブジェクトの属性が勝手に外部から変更されては保存した意味が無くなってしまうので、OriginatorしかMementoオブジェクトを変更できないようにしておく必要がある点に注意する必要があります。
Mementoパターンをどういう場合に使うか
ドキュメントツールのアンドゥやゲームの状態をセーブしておきたい時など、ある時点の状態に戻したい時に使用することができます。
PlantUMLでMementoパターンのクラス図を記述する
Mementoパターンのクラス図をPlantUMLで書いたときのソースです。
@startuml Memento
class Originator{
- state
--
+ setState() : void
+ createMemento() : Memento //Mementoオブジェクトを生成し返す
+ restoreFromMemento(Memento) : void //引数のMementoのstateを、属性stateにセット
}
class Memento{
- state
}
class CareTaker{
- memento : Memento
+ setMemento(Memento) : void //属性mementoに引数のMementoオブジェクトを格納
+ getMemento : Memento //属性mementoオブジェクトを返す
}
Originator -d-> Memento : creates >
CareTaker o-u-> Memento
@enduml
参考サイトURL
Memento パターン – Wikipedia
デザインパターン ~Memento~ – Qiita
PHPによるデザインパターン入門 – Memento〜スナップショットを取る – Do You PHP はてブロ