23デザインパターン第18章:Javaメモパターン
定義:カプセル化を破壊せずにオブジェクトの内部状態をキャプチャし、この状態をオブジェクトの外側に保存します。これにより、オブジェクトが元の保存された状態に復元されます。
タイプ:動作クラス
クラス図:
プログラミングをしているときは、オブジェクトの中間状態を保存する必要があることがよくあり、必要に応じてこの状態に復元できます。たとえば、Eclipseを使用してプログラムを使用する場合、書面で間違いを犯した場合(たとえば、誤って数行のコードを削除しました)、削除前にステータスを返して、CTRL+Zを使用して返すことができます。この時点で、メモモードを使用してそれを実現できます。
メモモードの構造
イニシエーター:現在の瞬間の内部ステータスを記録し、どの州がバックアップ範囲に属するかを定義する責任を負い、覚書データの作成と復元に責任を負います。
メモ:イニシエーターオブジェクトの内部状態を保存し、必要に応じてイニシエーターが必要とする内部状態を提供する責任があります。
管理の役割:覚書を管理し、保存して覚書を提供します。
一般的なコードの実装
class originator {private string state = ""; public string getState(){return state; } public void setState(string state){this.state = state; } public memento creatememento(){return new Memento(this.state); } public void restorememento(memento memento){this.setState(memento.getState()); }} class memento {private string state = ""; Public Memento(String state){this.state = state; } public string getState(){return state; } public void setState(string state){this.state = state; }} class Caretaker {private memento memento; public memento getMemento(){return memento; } public void setMemento(memento memento){this.memento = memento; }} public class client {public static void main(string [] args){originator originator = new Originator(); Originator.setState( "ステータス1"); System.out.println( "Initial State:"+Originator.getState());世話人の世話人= new Caretaker(); CARETAKER.SETMEMENTO(Originator.creatememento()); Originator.setState( "status2"); System.out.println( "変更後のステータス:"+originator.getState()); Originator.restorememento(caretaker.getmemento()); system.out.println( "復旧後のステータス:"+originator.getState()); }}コードは、単一の州の単一バックアップの例を示しています。ロジックは非常に単純です。Originatorクラスの状態変数は、必要に応じて復元できるようにバックアップする必要があります。 Mementoクラスでは、Originatorクラスに一時的な状態変数を保存するために使用される状態変数もあります。世話人クラスは、覚書クラスの管理に使用されます。メモクラスは、状態を書き込むか、状態を覚書オブジェクトに取得するために使用されます。
マルチステートマルチバックアップメモ
一般的なコードのデモンストレーションの例では、オリジネータークラスにはバックアップする必要がある状態変数が1つしかありませんが、通常、イニシエーターの役割は通常Javabeanであり、オブジェクトにバックアップする必要がある変数が複数あり、バックアップする必要がある複数の状態があります。これは、マルチステートマルチバックアップメモです。
メモを実装するには多くの方法があります。メモには多くの変形と処理方法があります。一般的に一般的なコードのような方法は使用されません。ほとんどの場合、メモはマルチステートと複数のバックアップです。実際、マルチステートとマルチバックアップを実装することも非常に簡単です。最も一般的に使用される方法は、Memementoにマップコンテナを追加してすべての状態を保存し、世話人クラスのマップコンテナを使用してすべてのバックアップを保存することです。以下に、マルチステートとマルチバックアップの例を示します。
class originator {private string state1 = ""; private string state2 = ""; private string state3 = ""; public string getState1(){return state1; } public void setState1(string state1){this.state1 = state1; } public string getState2(){return state2; } public void setState2(string state2){this.state2 = state2; } public string getState3(){return state3; } public void setState3(string state3){this.state3 = state3; } public memento creatememento(){return new memento(beanutils.backupprop(this)); } public void restorememento(memento memento){beanutils.restoreProp(this、memento.getStateMap()); } public String toString(){return "state1 ="+state1+"state2 ="+state2+"state3 ="+state3; }} class memento {private map <string、object> statemap; Public Memento(Map <String、Object> Map){this.statemap = map; } public Map <string、object> getStateMap(){return statemap; } public void setStateMap(map <string、object> statemap){this.statemap = statemap; }} class beanutils {public static map <string、object> backupprop(object bean){map <string、object> result = new hashmap <string、object>(); try {beaninfo beaninfo = introspector.getBeanInfo(bean.getClass()); PropertyDescriptor [] Descriptors = beaninfo.getPropertyDescriptors(); for(propertydescriptor des:descriptors){string fieldname = des.getname();メソッドgetter = des.GetReadMethod(); object fieldvalue = getter.invoke(bean、new object [] {}); if(!fieldname.equalsignorecase( "class")){result.put(fieldname、fieldvalue); }}}} catch(Exception e){e.printstacktrace(); } return result; } public static void restoreProp(object bean、map <string、object> propmap){try {beaninfo beaninfo = introspector.getBeaninfo(bean.getClass()); PropertyDescriptor [] Descriptors = beaninfo.getPropertyDescriptors(); for(propertydescriptor des:descriptors){string fieldname = des.getname(); if(propmap.containskey(fieldname)){method setter = des.getWriteMethod(); setter.invoke(bean、new object [] {propmap.get(fieldname)}); }}} catch(例外e){e.printstacktrace(); }}} class Caretaker {private map <string、memento> memmap = new Hashmap <String、Memento>(); Public Memento getMemento(String Index){return memmap.get(index); } public void setMemento(String Index、Memento Memento){this.memmap.put(index、memento); }} class client {public static void main(string [] args){originator ori = new Originator();世話人の世話人= new Caretaker(); ori.setState1( "中国"); ori.setstate2( "strong"); ori.setState3( "繁栄"); System.out.println( "===初期化ステータス===/n"+ori); CARETAKER.SETMEMENTO( "001"、ori.creatememento()); ori.setState1( "ソフトウェア"); ori.setState2( "構造"); ori.setState3( "優れた"); System.out.println( "=== modified status ===/n"+ori); ori.restorememento(caretaker.getmemento( "001")); System.out.println( "===復元状態===/n"+ori); }}覚書モードと適用可能なシナリオの利点と短所
メモモードの利点は次のとおりです。
イニシエーターの役割のステータスが変更されると、間違った変更になる可能性があります。メモモードを使用して、この間違った変更を復元できます。
バックアップのステータスは、イニシエーターの役割の外側に保存されるため、イニシエーターの役割は各バックアップのステータスを管理する必要はありません。
メモモードの欠点は次のとおりです。
実際のアプリケーションでは、覚書モードはマルチステートおよびマルチバックアップです。イニシエーターの役割の状態は、比較的ひどくリソースを消費する覚書オブジェクトに保存する必要があります。
ロールバック操作を提供する必要がある場合、JDBCトランザクション操作、CTRL+Zテキストエディターの回復など、メモモードを使用することが非常に適しています。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。