【ITニュース解説】Memento Design Pattern in Python...

2025年09月07日に「Dev.to」が公開したITニュース「Memento Design Pattern in Python...」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

Mementoデザインパターンは、オブジェクトの状態を保存し後で復元する手法。ワープロの「元に戻す」機能などが代表例だ。オブジェクトの内部を隠したまま、ある時点の状態をスナップショットとして保存し、いつでもその状態に戻せる。(117文字)

出典: Memento Design Pattern in Python... | Dev.to公開日:

ITニュース解説

ソフトウェア開発において、ユーザーが操作を間違えた際に一つ前の状態に戻せる「元に戻す(Undo)」機能は、アプリケーションの使いやすさを大きく向上させる重要な要素である。このような機能を実現するための一つの設計手法として「Memento(メメント)デザインパターン」が存在する。このパターンは、オブジェクトのある時点の状態を、その内部構造を外部に公開することなく保存し、後でその状態に復元することを目的としている。例えるなら、オブジェクトの状態を「写真」として撮影し、その写真を安全な場所に保管しておくようなイメージである。

Mementoパターンを理解するには、主に3つの登場人物の役割を把握することが重要だ。一つ目は「Originator(オリジネーター)」であり、これは状態を持つ本体のオブジェクトを指す。文章作成ソフトにおける「文書」そのものに相当し、自身の状態が時々刻々と変化する。Originatorは、現在の状態を保存する責任と、過去の状態から復元する責任を負う。二つ目は「Memento(メメント)」である。これはOriginatorのある一瞬の内部状態を保存するためのオブジェクトで、「記念品」や「記憶」といった意味を持つ。重要なのは、MementoはOriginatorの状態をカプセル化、つまり外部から直接中身を覗いたり変更したりできないように隠蔽している点である。これにより、Originatorの内部実装に依存せずに状態の保存・復元が可能となる。三つ目は「Caretaker(ケアテイカー)」で、「世話人」を意味する。Caretakerは、Originatorから受け取ったMementoオブジェクトを安全に保管・管理する役割を担う。文章作成ソフトの「編集履歴」リストのような存在であり、どのMementoがどの順番で保存されたかを記録する。CaretakerはMementoの中身が具体的に何であるかを知る必要はなく、単に預かり、必要に応じてOriginatorに返すだけの役割に徹する。

この3つの役割が連携して、状態の保存と復元が行われる。まず、状態を保存する際の処理の流れを見てみよう。アプリケーションがOriginatorの状態を保存する必要が生じると、Caretakerに対して保存を指示する。指示を受けたCaretakerは、Originatorに「現在の状態をMementoとして作成してほしい」と依頼する。Originatorは自身の現在の状態、例えばテキストが「State1」であるという情報をコピーし、その情報を持った新しいMementoオブジェクトを生成してCaretakerに渡す。Caretakerは受け取ったMementoを、後で取り出せるようにリストなどの形式で保管する。この一連の処理を繰り返すことで、Caretakerの元には複数の時点の状態を記録したMementoが時系列で蓄積されていく。

次に、状態を復元する、つまり「元に戻す」際の処理の流れである。ユーザーが「元に戻す」操作を行うと、Caretakerが動き出す。Caretakerは、保管しているMementoのリストから、一番最後に追加されたもの(=直前の状態)を取り出す。そして、その取り出したMementoをOriginatorに渡し、「このMementoが記録している状態に戻してほしい」と依頼する。依頼を受けたOriginatorは、Mementoから状態の情報を取り出し、自身の内部状態をその情報で上書きする。これにより、Originatorは一つ前の状態に見事に戻ることができる。CaretakerがリストからMementoを取り出す際に、そのMementoをリストから削除すれば、連続して「元に戻す」操作を実現することも可能だ。

Mementoパターンを採用する大きな利点は、カプセル化を維持できる点にある。Originatorの内部状態やその実装の詳細は、Caretakerを含む外部のオブジェクトから隠蔽される。CaretakerはMementoの中身を知らないため、将来的にOriginatorの内部構造が変更されたとしても、Caretakerのコードを修正する必要はない。これにより、コンポーネント間の依存関係が低く保たれ、保守性の高いソフトウェアを構築できる。また、状態を持つOriginator、状態の記録であるMemento、そしてその履歴を管理するCaretakerというように、それぞれの責任が明確に分離されるため、コードの構造が整理され、理解しやすくなる。Originator自身は過去の全履歴を管理する必要がなくなり、自身の現在の状態管理に集中できるため、クラスの設計がシンプルになるというメリットもある。

以上のように、Mementoデザインパターンは、オブジェクトの状態を安全に保存し、後から復元するための洗練された設計手法である。「元に戻す」機能や、ゲームのチェックポイント機能など、特定の時点の状態を記録しておきたい場合に非常に有効だ。Originator、Memento、Caretakerの三者がそれぞれの役割を果たすことで、オブジェクトの独立性を保ちながら、柔軟な状態管理を実現することができるのである。

関連コンテンツ

【ITニュース解説】Memento Design Pattern in Python... | いっしー@Webエンジニア