##概要
データ構造に対する状態を記録しておき、以前の状態への復帰を行えるようにするパターン
以下の3種類のクラスからなる
- Mementoクラス(2.の内部情報(フィールド値)を保持する)
- Originatorクラス(内部状態のスナップショットを入れておくために1.オブジェクトを生成する)
- Caretakerクラス(1.のオブジェクトを操作せずに保管する)
##具体例と実装
描画ソフトを例にすると、
上記1~3はそれぞれ
- 描画オブジェクトクラス(DrawingObjectクラス、描画ソフトで描かれた生成物オブジェクト)
- 描画ソフトクラス(DrawingSoftクラス、入力にしたがって描画オブジェクトを作成)
- 描画物管理クラス(DrawingCaretakerクラス、クリップボードの状態を管理する)
が対応する。
コードの詳細は以下
drawing_object.rb
class DrawingObject
def initialize(drawing)
@drawing = drawing
end
def get_drawing_object
@drawing
end
end
drawing_soft.rb
class DrawingSoft
def initialize
@drawing = nil
end
def draw(drawing)
# 絵を描く
@drawing = drawing
end
def get_drawing_object
return @drawing
end
def save_drawing_object
@clipboard = DrawingObject.new(@drawing)
end
def load_drawing_object(clipboard)
@clipboard = clipboard
@drawing = clipboard.get_drawing_object
end
end
drawing_caretaker.rb
class DrawingCaretaker
def initialize()
@clipboard = []
end
def add_to_clipboard(drawing)
@clipboard << drawing
end
def get_from_clipboard
@clipboard.pop
end
end
クライアントコード
drawing_caretaker = DrawingCaretaker.new
drawing_soft = DrawingSoft.new
drawing_soft.draw(#{適当な絵})
# save
drawing_caretaker.add_to_clipboard(drawing_soft.save_drawing_object)
puts(drawing_soft.get_drawing_object) # 適当な絵
drawing_soft.draw(#{綺麗な絵})
puts(drawing_soft.get_drawing_object) # 綺麗な絵
# undo
drawing_soft.load_drawing_object(drawing_caretaker.get_from_clipboard)
puts(drawing_soft.get_drawing_object) # 適当な絵
##メリット
- Originatorオブジェクトのみが管理すべき情報を外部から隠蔽し、カプセル化の境界を保つことができる
##まとめ
内部状態を保存しundo機能を実装する際に便利なパターン