1.メモモード
日常生活では、文書を編集するときに現在の操作を元に戻すために Ctrl + Z キーの組み合わせを使用することがあります。Web を閲覧するときは、クリックして前のページに戻ります。プログラムでは、データベースのトランザクション管理などで、データを以前の状態に復元するためにロールバック操作をよく使用します。
長年にわたって、この機能は非常に一般的になり、すべてのアプリケーションがフォールバック操作をサポートすることを誰もが期待しています。今日学習するメモ パターンは、これを行うために使用されます。
1.1、メモモードとは
-
意味
Memento モードは、スナップショット モードとも呼ばれる動作設計モードです。これは、カプセル化を破ることなくオブジェクトの内部状態をキャプチャし、この状態をオブジェクトの外部に保存して、後で必要になったときにオブジェクトを元の保存された状態に復元できるようにすることを指します。
平たく言えば、メモ モードはプログラム データのバックアップ方法を提供するオブジェクトのバックアップ モードであり、オブジェクトの状態を保存するために使用される具体的な方法は、オブジェクトの保存に必要な時間の長さに依存します。
memento パターンの構造:
1) 発信者の役割: 現時点での内部状態を記録し、どの状態がバックアップ範囲に属するかを定義する責任を負い、メモ データの作成と復元を担当し、メモ内のすべての情報にアクセスできます。
2) メメントの役割: イニシエーターの内部状態を保存し、必要に応じてこれらの内部状態をイニシエーターに提供する責任があります。
3) マネージャー (管理者) 役割: メモを管理、保存、提供しますが、メモの内容にアクセスしたり変更したりすることはできません。
memento パターンの目的は、オブジェクトの状態の保存および回復機能を提供することであり、オブジェクトの保存された状態データにはオブジェクトの外部からアクセスできません。
1.2. メモモードのメリットとデメリット
-
アドバンテージ
1) オブジェクトのスナップショットは、カプセル化に違反することなく生成できます。
2) イニシエータのコードを簡素化し、イニシエータは内部状態のバックアップを管理・保存する必要がなく、すべての情報はメモに保存され、管理者が管理します。
-
欠点がある
メモを頻繁に作成しすぎると、アプリケーションのメモリ消費量が増加します。
1.3. 作成方法
リーグ・オブ・レジェンドのヒーロー属性を例に挙げると、レッドバフを摂取するとヒーローの戦闘能力が向上し、効果が切れると元の状態に戻ります。
1) オリジネーターの役割
//发起人角色,即原始对象,需要备份的对象
public class LolOriginator {
private String name; //英雄名字
private String type; //英雄类型
private Integer fightingNum; //英雄战斗力
public LolOriginator(String name,String type,Integer fightingNum){
this.name = name;
this.type = type;
this.fightingNum = fightingNum;
}
//创建一个备忘录,进行备忘操作
public LolMemento createMemento(){
return new LolMemento(this);
}
//恢复成指定备忘录
public void restoreMemento(LolMemento memento){
this.name = memento.getName();
this.type = memento.getType();
this.fightingNum = memento.getFightingNum();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getFightingNum() {
return fightingNum;
}
public void setFightingNum(Integer fightingNum) {
this.fightingNum = fightingNum;
}
@Override
public String toString() {
return this.getName()+"-"+this.getType()+"-"+this.getFightingNum();
}
}
2) 思い出の役割
//备忘录
public class LolMemento {
private String name; //英雄名字
private String type; //英雄类型
private Integer fightingNum; //英雄战斗力
public LolMemento(LolOriginator lol){
this.name=lol.getName();
this.type=lol.getType();
this.fightingNum = lol.getFightingNum();
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public Integer getFightingNum() {
return fightingNum;
}
}
3) 世話人の役割
//管理者,负责管理备忘录对象
public class LolCaretaker {
private LolMemento memento;
//如果有一连串的状态加成,可以保存多个状态
//private List<LolMemento> mementoList = new ArrayList<LolMemento>();
public LolMemento getMemento() {
return memento;
}
public void setMemento(LolMemento memento) {
this.memento = memento;
}
}
4) クライアント
public class Client {
public static void main(String[] args) {
//备忘录管理者
LolCaretaker taker = new LolCaretaker();
//创建一个英雄
System.out.println("当前的英雄信息:");
LolOriginator lol = new LolOriginator("德玛西亚之力", "战士", 666);
System.out.println(" "+lol.toString());
//进行一次备忘
taker.setMemento(lol.createMemento());
System.out.println("吃了一个红buff:");
lol.setFightingNum(700);
System.out.println(" "+lol.toString());
System.out.println("红buff已经失效:");
lol.restoreMemento(taker.getMemento()); //恢复到之前的状态
System.out.println(" "+lol.toString());
}
}
ケース効果:
この時点での UML 図は次のとおりです。
1.4. 要約と提案
メモ モードでは、オブジェクトの状態をキャプチャでき、オブジェクトの保存された状態データにはオブジェクトの外部からアクセスできないため、保存された状態データの整合性が保護されます。これはメモ モードの利点でもあります。
さらに使用できるのは、オブジェクトの状態を別のオブジェクトに保存するか、複数のセッションにわたるオブジェクトの永続的な保存をサポートし、オブジェクトのシリアル化を使用してオブジェクト情報を保存することです。これは、前に学んだプロトタイプ モードです。プロトタイプ モードは、メモ モードの代わりに使用できます。したがって、メモパターンは一般的には使用されません。
アプリケーションシナリオ:
1) memento パターンは、オブジェクトの以前の状態を復元できるように、オブジェクトの状態のスナップショットを生成する場合に使用できます。
2) オブジェクトのフィールドのゲッターおよびセッターに直接アクセスすることがそのカプセル化に違反する場合、メモ モードを使用できます。
JDKでのメモモードの適用:
すべての java.io.Serializable 実装は Memento をモックできます
javax.faces.component.StateHolderの実装