定義
メモモードは、オブジェクトの動作モードです。メモオブジェクトは、別のオブジェクトの内部状態のスナップショットを格納するために使用されるオブジェクトです。メモモードの目的は、カプセル化を破壊することなく、オブジェクトの状態をキャプチャして外部化することです。 。保存されているため、将来の適切なタイミングでオブジェクトを保存された状態に復元できます。
意図
カプセル化を破壊しないという前提の下で、オブジェクトの内部状態をキャプチャし、この状態をオブジェクトの外部に保存します
主に問題を解決する
カプセル化を破壊しないことを前提として、オブジェクトの内部状態をキャプチャし、この状態をオブジェクトの外部に保存して、オブジェクトを将来元の状態に復元できるようにします。
いつ使用するか
多くの場合、オブジェクトの内部状態を記録する必要があります。これは、ユーザーが不確実または誤った操作をキャンセルして元の状態に戻し、「後悔の薬」を食べられるようにすることを目的としています。
長所と短所
利点:
- 一部のイニシエーターオブジェクトの内部情報は、イニシエーターオブジェクトの外部に保存する必要がある場合もありますが、イニシエーターオブジェクト自体が読み取る必要があります。この場合、メモモードを使用して、イニシエーターの複雑な内部情報を他のオブジェクトから保護できます。パッケージの境界を維持するために
- イニシエーターロールのステータスが変わると、ステータスが無効になる場合があります。このとき、一時的に保存されているメモを使用してステータスを復元できます。
短所:
リソースを消費します。クラスのメンバー変数が多すぎると、必然的に比較的大きなリソースを消費し、保存するたびに一定量のメモリが消費されます。
構造
関係する役割:
-
メメントの役割:
- オリジネーターオブジェクトの内部状態を保存します。メモは、オリジネーターオブジェクトの判断に従って、保存するオリジネーターオブジェクトの内部状態の数を決定できます。
- メモは、そのコンテンツがOriginatorオブジェクト以外のオブジェクトによって読み取られないように保護できます。メモには、次の2つの同等のインターフェイスがあります。
- 狭いインターフェース:世話人オブジェクトとイニシエーターオブジェクトを除く他のオブジェクト。表示されるのはメモの狭いインターフェースです。このインターフェースでは、メモオブジェクトを他のオブジェクトに渡すことしかできません。
- ワイドインターフェース:イニシエーターオブジェクトはワイドインターフェースを見ることができます。このワイドインターフェースにより、すべてのデータを読み取って、これらのデータに基づいてイニシエーターオブジェクトの内部状態を復元できます。
-
発信者の役割:
- 現在の内部状態でメモオブジェクトを作成する
- メモオブジェクトを使用して、その内部状態を保存します
-
世話人の役割:
- メモオブジェクトの保存を担当します
- メモオブジェクトの内容を確認しないでください
ホワイトボックスの実現
イニシエーターロールの状態は、誰もが見ることができる場所に保存されているため、カプセル化を破棄します。
ソースコードは次のとおりです。
public class Originator {
private String state;
/** 返回一个新的备忘录对象 */
public Memento createMemento() {
return new Memento(state);
}
/** 将发起人恢复到备忘录对象所记录的状态 */
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
/** 状态的取值方法 */
public String getState() {
return this.state;
}
/** 状态的赋值方法 */
public void setState(String state) {
this.state = state;
System.out.println("当前状态:" + this.state);
}
}
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
/** 状态的取值方法 */
public String getState() {
return this.state;
}
/** 状态的赋值方法 */
public void setState(String state) {
this.state = state;
}
}
public class Caretaker {
private Memento memento;
/** 备忘录的取值方法 */
public Memento getMemento() {
return this.memento;
}
/** 备忘录的赋值方法 */
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
//改变发起人对象的状态
originator.setState("On");
//创建备忘录对象,并将发起人对象的状态存储起来
caretaker.setMemento(originator.createMemento());
//修改发起人对象的状态
originator.setState("Off");
originator.restoreMemento(caretaker.getMemento());
//恢复发起人对象的状态
System.out.println("恢复状态:" + originator.getState());
}
}
ブラックボックスの実装
MementoクラスをOriginatorクラスの内部クラスとして設定し、Caretakerクラスおよびその他のオブジェクトの外部識別インターフェイスMementoIFを提供します。
ソースコードは次のとおりです。
public class Originator {
private String state;
public Originator() {
}
/** 返回一个新的备忘录对象 */
public MementoIF createMemento() {
return new Memento(this.state);
}
/** 将发起人恢复到备忘录对象所记录的状态 */
public void restoreMemento(MementoIF memento) {
Memento memento1 = (Memento) memento;
this.state = memento1.getState();
}
/** 状态的取值方法 */
public String getState() {
return this.state;
}
/** 状态的赋值方法 */
public void setState(String state) {
this.state = state;
System.out.println("当前状态:" + this.state);
}
/** 内部成员类,备忘录 */
protected class Memento implements MementoIF {
private String saveState;
private Memento(String state) {
this.saveState = state;
}
/** 状态的取值方法 */
private String getState() {
return this.saveState;
}
/** 状态的赋值方法 */
private void setState(String state) {
this.saveState = state;
}
}
}
public interface MementoIF {
}
public class Caretaker {
private MementoIF memento;
/** 备忘录的取值方法 */
public MementoIF getMemento() {
return this.memento;
}
/** 备忘录的赋值方法 */
public void setMemento(MementoIF memento) {
this.memento = memento;
}
}
public class Client {
private static Originator o = new Originator();
private static Caretaker c = new Caretaker();
public static void main(String[] args) {
//改变发起人对象的状态
o.setState("On");
//创建备忘录对象,并将发起人对象的状态存储起来
c.setMemento(o.createMemento());
//修改发起人对象的状态
o.setState("Off");
o.restoreMemento(c.getMemento());
//恢复发起人对象的状态
System.out.println("恢复状态:" + o.getState());
}
}
複数のチェックポイント
複数の状態を保存する、または複数のチェックポイントと呼ばれる
public class Originator {
private Vector states;
private int index;
public Originator() {
this.states = new Vector();
this.index = 0;
}
/** 返回一个新的备忘录对象 */
public Memento createMemento() {
return new Memento(states, index);
}
/** 将发起人恢复到备忘录对象所记录的状态 */
public void restoreMemento(Memento memento) {
this.states = memento.getStates();
this.index = memento.getIndex();
}
/** 状态的赋值方法 */
public void setState(String state) {
this.states.addElement(state);
index++;
}
/** 打印出所有的状态 */
public void printStates() {
System.out.println("总的状态数量:" + index);
for (Enumeration e = states.elements(); e.hasMoreElements();) {
System.out.println(e.nextElement());
}
}
}
public class Memento {
private Vector states;
private int index;
public Memento(Vector states, int index) {
this.states = (Vector) states.clone();
this.index = index;
}
/** 状态的取值方法 */
public Vector getStates() {
return states;
}
/** 检查点指数的取值方法 */
public int getIndex() {
return index;
}
}
public class Caretaker {
private Originator originator;
private Vector vector = new Vector();
private int current;
public Caretaker(Originator originator) {
this.originator = originator;
this.current = 0;
}
/** 创建一个新的检查点 */
public int createMemento() {
Memento memento = originator.createMemento();
vector.addElement(memento);
return current++;
}
/** 将发起人恢复到某个检查点 */
public void restoreMemento(int index) {
Memento memento = (Memento) vector.elementAt(index);
originator.restoreMemento(memento);
}
/** 将某个检查点删除 */
public void removeMemento(int index) {
vector.removeElementAt(index);
}
}
public class Client {
private static Originator o = new Originator();
private static Caretaker c = new Caretaker(o);
public static void main(String[] args) {
//改变状态
o.setState("state 0");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 1");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 2");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 3");
//建立一个检查点
c.createMemento();
//打印所有的检查点
o.printStates();
//恢复到第1个检查点
System.out.println("恢复到第1个检查点");
c.restoreMemento(1);
o.printStates();
//恢复到第3个检查点
System.out.println("恢复到第2个检查点");
c.restoreMemento(2);
o.printStates();
}
}
観世音菩薩の甘い春の生きている木の物語
Sun Dashengは、西に行くTang Sengを保護し、長寿山のWuzhuang寺院を通り過ぎ、Daotongと喧嘩し、怒って高麗人参の果樹を倒します。偉大な賢人は、GuanyinBodhisattvaに高麗人参の果樹を救うように頼まなければなりません。
ここでは、観世音菩薩の蜜に果樹の状態が保存されており、菩薩は花蜜から果樹の状態を復元することができます。果樹はイニシエーター、花蜜は覚書の役割、菩薩は人です。担当。
public class SweetSpringWater {
private String fruiterState;
public SweetSpringWater(String fruiterState) {
this.fruiterState = fruiterState;
}
/** 获取果树的状态 */
public String getFruiterState() {
return fruiterState;
}
/** 设置果树的状态 */
public void setFruiterState(String fruiterState) {
this.fruiterState = fruiterState;
}
}
public class Fruiter {
private String fruiterState;
/** 返回一个新的备忘录对象 */
public SweetSpringWater createMemento() {
return new SweetSpringWater(fruiterState);
}
/** 将发起人恢复到备忘录对象所记录的状态 */
public void restoreSweetSpringWater(SweetSpringWater springWater) {
this.fruiterState = springWater.getFruiterState();
}
/** 果树状态的取值方法 */
public String getState() {
return this.fruiterState;
}
/** 果树状态态的赋值方法 */
public void setState(String fruiterState) {
this.fruiterState = fruiterState;
System.out.println("当前果树状态:" + this.fruiterState);
}
}
public class Goddess {
private SweetSpringWater sweetSpringWater;
/** 备忘录的取值方法 */
public SweetSpringWater getSweetSpringWater() {
return this.sweetSpringWater;
}
/** 备忘录的赋值方法 */
public void setMemento(SweetSpringWater sweetSpringWater) {
this.sweetSpringWater = sweetSpringWater;
}
}
public class Client {
public static void main(String[] args) {
Fruiter f = new Fruiter();
Goddess g = new Goddess();
//改变发起人对象的状态
f.setState("果树被孙悟空推倒了");
//创建备忘录对象,并将发起人对象的状态存储起来
g.setMemento(f.createMemento());
//修改发起人对象的状态
f.setState("观世音用甘泉恢复果树状态");
//恢复发起人对象的状态
System.out.println("恢复状态:" + f.getState());
}
}