LoginSignup
6
5

More than 5 years have passed since last update.

【デザインパターン】 Mementoパターン

Last updated at Posted at 2015-08-09

概要

データ構造に対する状態を記録しておき、以前の状態への復帰を行えるようにするパターン

以下の3種類のクラスからなる
1. Mementoクラス(2.の内部情報(フィールド値)を保持する)
2. Originatorクラス(内部状態のスナップショットを入れておくために1.オブジェクトを生成する)
3. Caretakerクラス(1.のオブジェクトを操作せずに保管する)

具体例と実装

描画ソフトを例にすると、

上記1~3はそれぞれ

  1. 描画オブジェクトクラス(DrawingObjectクラス、描画ソフトで描かれた生成物オブジェクト)
  2. 描画ソフトクラス(DrawingSoftクラス、入力にしたがって描画オブジェクトを作成)
  3. 描画物管理クラス(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機能を実装する際に便利なパターン

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5