<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    人在江湖

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks

    備忘錄(Memento Pattern)模式
    備忘錄模式又叫做快照模式(Snapshot Pattern)或Token模式,是對象的行為模式。
    備忘錄對象是一個用來存儲另外一個對象內(nèi)部狀態(tài)的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態(tài)捕捉住,并外部化
    存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態(tài)。備忘錄模式常常與命令模式和迭代子模式一同使用。
    常見的軟件系統(tǒng)往往不止存儲一個狀態(tài),而是需要存儲多個狀態(tài)。這些狀態(tài)常常是一個對象歷史發(fā)展的不同階段的快照,存儲這些快照的備忘錄對象
    叫做此對象的歷史,某一個快照所處的位置叫做檢查點。
    備忘錄角色:
    備忘錄角色有如下的責(zé)任。
    1、將發(fā)起人(Originator)對象的內(nèi)部狀態(tài)存儲起來,備忘錄可以根據(jù)發(fā)起人對象的判斷來決定存儲多少
         發(fā)起人(Originator)對象的內(nèi)部狀態(tài)。
    2、備忘錄可以保護其內(nèi)容不被發(fā)起人對象之外的任何對象所讀取。備忘錄有兩個等效的接口:
    1、窄接口:負(fù)責(zé)人(Caretaker)對象(和其他除發(fā)起人對象之外的任何對象)看到的是備忘錄的窄
       接(narrow interface),這個窄接口只允許它把備忘錄對象傳給其他的對象;
    2、寬接口:與負(fù)責(zé)人對象看到的窄接口相反的是,發(fā)起人對象可以看到一個寬接口(wide interface),
       這個寬接口允許它讀取所有的數(shù)據(jù),以便根據(jù)數(shù)據(jù)恢復(fù)這個發(fā)起人對象的內(nèi)部狀態(tài)。853P
    發(fā)起人角色:
    發(fā)起人角色有如下責(zé)任:
    1、創(chuàng)建一個含有當(dāng)前的內(nèi)部狀態(tài)的備忘錄對象。
    2、使用備忘錄對象存儲其內(nèi)部狀態(tài)。
    負(fù)責(zé)人角色:
    負(fù)責(zé)人角色有如下的責(zé)任:
    1、負(fù)責(zé)保存?zhèn)渫泴ο?br>2、不檢查備忘錄對象的內(nèi)容。

    Java代碼

       1: 寬接口和白箱:
       2:         發(fā)起人角色
       3:         public class Originator{
       4:             private String state;
       5:             
       6:             //工廠方法,返還一個新的備忘錄對象
       7:             public Memento createMemento(){
       8:                 return new Memento(state);
       9:             }
      10:             
      11:             //將發(fā)起人恢復(fù)到備忘錄對象所記載的狀態(tài)
      12:             public void restoreMemento(Memento memento){
      13:                 this.state = memento.getState();
      14:             }
      15:             
      16:             //狀態(tài)的取值方法
      17:             public String getState(){
      18:                 return this.state;
      19:             }
      20:             
      21:             //狀態(tài)的賦值方法
      22:             public void setState(String state){
      23:                 this.state = state;
      24:                 System.out.println("Current state = " + this.state);
      25:             }
      26:         }
      27:         
      28:         備忘錄模式要求備忘錄對象提供兩個不同的接口:一個寬接口提供給發(fā)起人對象,另一個窄接口提供給所有其他的對象,包括負(fù)責(zé)人對象。
      29:         寬接口允許發(fā)起人讀取到所有的數(shù)據(jù);窄接口只允許它把備忘錄對象傳給其他的對象而看不到內(nèi)部的數(shù)據(jù)。
      30:         //備忘錄角色
      31:         public class Memento{
      32:             private String state;
      33:             
      34:             public Memento(String state){
      35:                 this.state = state;
      36:             }
      37:             
      38:             public String getState(){
      39:                 return this.state;
      40:             }
      41:             
      42:             public void setState(String state){
      43:                 this.state = state;
      44:             }
      45:         }
      46:         
      47:         負(fù)責(zé)人角色負(fù)責(zé)保存?zhèn)渫泴ο螅菑牟恍薷模ㄉ踔敛徊榭矗﹤渫泴ο蟮膬?nèi)容(一個更好的實現(xiàn)是負(fù)責(zé)人對象根本無法從備忘錄
      48:         對象中讀取個修改其內(nèi)容)
      49:         
      50:         //負(fù)責(zé)人角色
      51:         public class Caretaker{
      52:             private Memento memento;
      53:             
      54:             //備忘錄的取值方法
      55:             public Memento retrieveMemento(){
      56:                 return this.memento;
      57:             }
      58:             
      59:             //備忘錄的賦值方法
      60:             public void saveMemento(Memento memento){
      61:                 this.memento = memento;
      62:             }
      63:         }
      64:         
      65:         //客戶端
      66:         public class Client{
      67:             private static Originator o = new Originator();
      68:             private static Caretaker c= new Caretaker();
      69:             private static void main(String[] args){
      70:                 //該負(fù)責(zé)人對象的狀態(tài)
      71:                 o.setState("On");
      72:                 //創(chuàng)建備忘錄對象,并將發(fā)起人對象的狀態(tài)存儲起來
      73:                 c.saveMemento(o.createMemento());
      74:                 //修改發(fā)起人對象的狀態(tài)
      75:                 o.setState("Off");
      76:                 //恢復(fù)發(fā)起人對象的狀態(tài)
      77:                 o.restoreMemento(c.retrieveMemento());
      78:             }
      79:         }
      80:         首先將發(fā)起人對象的狀態(tài)設(shè)置成“On”(或者任何有效狀態(tài)),并且創(chuàng)建一個備忘錄對象將這個狀態(tài)存儲起來;然后將發(fā)起人對象
      81:         的狀態(tài)改成“Off”(或者任何狀態(tài));最后又將發(fā)起人對象恢復(fù)到備忘錄對象所存儲起來的狀態(tài),即“On”狀態(tài)(或者先前所
      82:         存儲的任何狀態(tài))
      83:         
      84:         備忘錄系統(tǒng)運行的時序是這樣的:
      85:             (1)將發(fā)起人對象的狀態(tài)設(shè)置成“On”。
      86:             (2)調(diào)用發(fā)起人角色的createMemento()方法,創(chuàng)建一個備忘錄對象將這個狀態(tài)存儲起來。
      87:             (3)將備忘錄對象存儲到負(fù)責(zé)人對象中去。
      88:         備忘錄系統(tǒng)恢復(fù)的時序是這樣的:
      89:             (1)將發(fā)起人對象的狀態(tài)設(shè)置成“Off”;
      90:             (2)將備忘錄對象從負(fù)責(zé)人對象中取出;
      91:             (3)將發(fā)起人對象恢復(fù)到備忘錄對象所存儲起來的狀態(tài),“On”狀態(tài)。
      92:         
      93:         白箱實現(xiàn)的優(yōu)缺點
      94:             白箱實現(xiàn)的一個明顯的好處是比較簡單,因此常常用做教學(xué)目的。白箱實現(xiàn)的一個明顯的缺點是破壞對發(fā)起人狀態(tài)的封裝。
      95:             
      96:     窄接口或者黑箱實現(xiàn)
      97:         //發(fā)起人角色
      98:         public class Originator{
      99:             private String state;
     100:             
     101:             public Originator(){
     102:             }
     103:             
     104:             //工廠方法,返還一個新的備忘錄對象
     105:             public MementoIF createMemento(){
     106:                 return new Memento(this.state);    
     107:             }
     108:             
     109:             //將發(fā)起人恢復(fù)到備忘錄對象記錄的狀態(tài)
     110:             public void restoreMemento(MementoIF memento){
     111:                 Memento aMemento = (Memento)memento;
     112:                 this.setState(aMemento.getState());
     113:             }
     114:             
     115:             public String getState(){
     116:                 return this.state;
     117:             }
     118:             
     119:             public void setState(){
     120:                 this.state = state;
     121:                 System.out.println("state = " + state);
     122:             }
     123:             
     124:             protected class Memento implements MementoIF{
     125:                 private String savedState;
     126:                 private Mememto(String someState){
     127:                     savedState = someState;
     128:                 }
     129:                 
     130:                 private void setState(String someState){
     131:                     savedState = someState;
     132:                 }
     133:                 
     134:                 private String getState(){
     135:                     return savedState;
     136:                 }
     137:             }
     138:         }
     139:         
     140:         public interface MementoIF{}
     141:         
     142:         public class Caretaker{
     143:             private MementoIF memento;
     144:             
     145:             public MementoIF retrieveMemento(){
     146:                 return this.memento;
     147:             }
     148:             
     149:             public void saveMemento(MementoIF memento){
     150:                 this.memento = memento;
     151:             }
     152:         }
     153:         
     154:         public class Client{
     155:             private static Originator o = new Originator();
     156:             private static Caretaker c = new Caretaker();
     157:             
     158:             public static void main(String args[]){
     159:                 //改變負(fù)責(zé)人對象的狀態(tài)
     160:                 o.setState("On");
     161:                 //創(chuàng)建備忘錄對象,并將發(fā)起人對象的狀態(tài)存儲起來
     162:                 c.saveMemento(o.createMemento());
     163:                 //修改發(fā)起人對象的狀態(tài)
     164:                 o.setState("Off");
     165:                 //恢復(fù)發(fā)起人對象的狀態(tài)
     166:                 o.restoreMemento(c.retrieveMemento());
     167:             }
     168:         }
     169:         
     170:         黑箱實現(xiàn)運行時的時序為;
     171:             (1)將發(fā)起人對象的狀態(tài)設(shè)置成“On”。
     172:             (2)調(diào)用發(fā)起人角色的 createMemento()方法,創(chuàng)建一個備忘錄對象將這個狀態(tài)存儲起來。
     173:             (3)將備忘錄對象存儲到負(fù)責(zé)人對象中去。由于負(fù)責(zé)人對象拿到的僅是 MementoIF類型,因此無法讀出備忘錄內(nèi)部的狀態(tài)。
     174:         恢復(fù)時的時序為:
     175:             (1)將發(fā)起人對象的狀態(tài)設(shè)置成“Off”;
     176:             (2)將備忘錄對象從負(fù)責(zé)人對象中取出。注意此時僅能得到 MementoIF接口,因此無法讀出此對象的內(nèi)部狀態(tài)
     177:             (3)將發(fā)起人對象的狀態(tài)恢復(fù)成備忘錄對象所存儲起來的狀態(tài),,由于發(fā)起人對象的內(nèi)部類Memento實現(xiàn)了MementoIF接口
     178:                  這個內(nèi)部類是傳入的備忘錄對象的真實類型,因此發(fā)起人對象可以利用內(nèi)部類Memento 的私有 接口讀出此對象的內(nèi)部狀態(tài)
     179:                  
     180: 存儲多個狀態(tài)的備忘錄模式:
     181:         //發(fā)起人角色
     182:         import java.util.Vector;
     183:         import java.util.Enumeration;
     184:         
     185:         public class Originator{
     186:             private Vector states;
     187:             private int index;
     188:             
     189:             public Originator(){
     190:                 states = new Vector();
     191:                 index = 0;
     192:             }
     193:             
     194:             public Memento createMementor(){
     195:                 return new Mementor(states,index);
     196:             }
     197:             
     198:             public void restoreMementor(Mementor memento){
     199:                 states = memento.getStates();
     200:                 index = memento.getIndex();
     201:             }
     202:             
     203:             public void setState(String state){
     204:                 this.states.addElement(state);
     205:                 index ++;
     206:             }
     207:             
     208:             //輔助方法,打印出所有的狀態(tài)
     209:             public void printStates(){
     210:                 System.out.println("Total number of states: " + index);
     211:                 for(Enumeration e = states.elements();e.hasMoreElements();){
     212:                     system.out.println(e.nextElement());
     213:                 }
     214:             }
     215:         } 
     216:         
     217:         //備忘錄角色
     218:         import java.util.Vector;
     219:         
     220:         public class Memento{
     221:             private Vector states;
     222:             private int index;
     223:             
     224:             public Memento(Vector states,int index){
     225:                 this.states = (Vector)states.clone();
     226:                 this.index = index;
     227:             }
     228:             
     229:             //狀態(tài)取值方法
     230:             Vector getStates(){
     231:                 return states;
     232:             }
     233:             
     234:             //檢查點取值方法
     235:             int getIndex(){
     236:                 return this.index;
     237:             }
     238:         }
     239: ******************備忘錄的構(gòu)造子克隆了傳入的states,然后將克隆存入到備忘錄對象內(nèi)部,這是一個重要的細(xì)節(jié),因為不這樣的話,將會
     240:           將會造成客戶端和備忘錄對象持有對同一個Vector對象的引用,也可以同時修改這個Vector對象,會造成系統(tǒng)崩潰。
     241:           
     242:         //負(fù)責(zé)人角色
     243:         import java.util.Vector;
     244:         
     245:         public class Caretaker{
     246:             private Originator o;
     247:             private Vector mementos = new Vector();
     248:             private int current;
     249:             
     250:             public Caretaker(Originator o){
     251:                 this.o = o;
     252:                 current = 0;
     253:             }
     254:             
     255:             public int createMemento(){
     256:                 Memento memento = o.createMemento();
     257:                 mementos.addElement(memento);
     258:                 return current ++;
     259:             }
     260:             
     261:             //將發(fā)起人恢復(fù)到某個檢查點
     262:             public void restoreMemento(int index){
     263:                 Memento memento = (Memento)mementos.elementAt(index);
     264:                 o.restoreMemento(memento);
     265:             }
     266:             
     267:             //某個檢查點刪除
     268:             public void removeMemento(int index){
     269:                 mementos.removeElementAt(index);
     270:             }
     271:         }
     272:         
     273:         //客戶端
     274:         public class Client{
     275:             private static Originator o = new Originator();
     276:             private static Caretaker c = new Caretaker(o);
     277:             public static void main(String[] args){
     278:                 //改變狀態(tài)
     279:                 o.setState("state 0");
     280:                 //建立一個檢查點
     281:                 c.createMemento();
     282:                 //改變狀態(tài)
     283:                 o.setState("state 1");
     284:                 
     285:                 c.createMemento();
     286:                 
     287:                 o.setState("state 2");
     288:                 
     289:                 c.createMemento();
     290:                 
     291:                 o.setState("state 3");
     292:                 
     293:                 c.createMemento();
     294:                 
     295:                 o.setState("state 4");
     296:                 
     297:                 c.createMemento();
     298:                 
     299:                 o.printStates();
     300:                 
     301:                 //恢復(fù)到第二個檢查點
     302:                 System.out.println("Restoring to 2");
     303:                 
     304:                 c.restoreMemento(2);
     305:                 
     306:                 o.printStates();
     307:                 
     308:                 System.out.println("Restoring to 0");
     309:                 
     310:                 c.restoreMemento(0);
     311:                 
     312:                 o.printStates();
     313:                 
     314:                 System.out.println("Restoring to 3");
     315:                 
     316:                 c.restoreMemento(3);
     317:                 
     318:                 o.printStates();
     319:                 
     320:                 
     321:             }
     322:         }
     323:         
     324: 自述歷史模式(備忘錄模式的一個變種):
     325:         //窄接口
     326:         public interface MementoIF{}
     327:         
     328:         //發(fā)起人角色
     329:         public class Originator{
     330:             public String state;
     331:             
     332:             public Originator(){}
     333:             
     334:             public void changeState(String state){
     335:                 this.state = state;
     336:                 System.out.println("State has been changed to : " + state);
     337:             }
     338:             
     339:             public Memento createMemento(){
     340:                 return new Memento(this);
     341:             }
     342:             
     343:             public void restoreMemento(MementoIF memento){
     344:                 Memento m = (Memento)memento;
     345:                 changeState(m.state);
     346:             }
     347:             
     348:             class Memento implements MementoIF{
     349:                 private String state;
     350:                 
     351:                 private String getState(){
     352:                     return state;
     353:                 }
     354:                 
     355:                 private Memento(Originator o){
     356:                     this.state = o.state;
     357:                 }
     358:             }
     359:         }
     360:         
     361:         //客戶端
     362:         public class Client{
     363:             private static Originator o;
     364:             private static MementoIF memento;
     365:             
     366:             public static void main(String args[]){
     367:                 o = new Originator();
     368:                 o.changeState("State 1");
     369:                 memento = o.createMemento();
     370:                 o.changeState("State 2");
     371:                 o.restoreMemento(memento);
     372:             }
     373:         }
     374:         

    模式的優(yōu)缺點:
    由于“自述歷史”作為一個備忘錄模式的特殊實現(xiàn)形式非常簡單易懂,它可能是備忘錄模式最為流行的實現(xiàn)形式。
    備忘錄模式的操作過程
    1、客戶端為發(fā)起人角色創(chuàng)建一個備忘錄對象。
    2、調(diào)用發(fā)起人對象的某個操作,這個操作是可以撤銷的。
    3、檢查發(fā)起人對象所出狀態(tài)的有效性。檢查的方式可以是發(fā)起人對象的內(nèi)部自查,也可以由某個外部對象進行檢查。
    4、如果需要的話,將發(fā)起人的操作撤銷,也就是說根據(jù)備忘錄對象的記錄,將發(fā)起人對象的狀態(tài)恢復(fù)過來。
    “假如”協(xié)議模式的操作過程:
    1、將發(fā)起人對象做一個拷貝。
    2、在拷貝上執(zhí)行某個操作。
    3、檢查這個拷貝的狀態(tài)是否有效和自恰。
    4、如果檢查結(jié)果是無效或者不自恰的,那么扔掉這個拷貝,并觸發(fā)異常處理程序;相反,如果檢查是有效和自恰的,那么在原對象上執(zhí)行這個操作
    顯然這一做法對于撤銷一個操作并恢復(fù)操作前狀態(tài)較為復(fù)雜和困難的發(fā)起人對象來說是一個較為謹(jǐn)慎和有效的做法。
    “假如”協(xié)議模式的優(yōu)點和缺點
    具體來說,這個做法的長處是可以保證發(fā)起人對象永遠(yuǎn)不會處于無效或不自恰的狀態(tài)上,這樣作的短處是成功的操作必須執(zhí)行兩次。
    如果操作的成功率較低的話,這樣做就比較劃算,反之就不太劃算。
    使用備忘錄模式的優(yōu)點和缺點
    一、備忘錄模式的優(yōu)點
    1、有時一些發(fā)起人對象的內(nèi)部信息必須保存在發(fā)起人對象以外的地方,但是必須要由發(fā)起人對象自己讀取,這時,
       使用備忘錄模式可以把復(fù)雜的發(fā)起人內(nèi)部信息對其他的對象屏蔽起來,從而可以恰當(dāng)?shù)乇3址庋b的邊界。
    2、本模式簡化了發(fā)起人類。發(fā)起人不再需要管理和保存其內(nèi)部狀態(tài)的一個個版本,客戶端可以自行管理他們所需
       要的這些狀態(tài)的版本。
    3、當(dāng)發(fā)起人角色的狀態(tài)改變的時候,有可能這個狀態(tài)無效,這時候就可以使用暫時存儲起來的備忘錄將狀態(tài)復(fù)原。
    二、備忘錄模式的缺點:
    1、如果發(fā)起人角色的狀態(tài)需要完整地存儲到備忘錄對象中,那么在資源消耗上面?zhèn)渫泴ο髸馨嘿F。
    2、當(dāng)負(fù)責(zé)人角色將一個備忘錄 存儲起來的時候,負(fù)責(zé)人可能并不知道這個狀態(tài)會占用多大的存儲空間,從而無法
       提醒用戶一個操作是否很昂貴。882——P
    3、當(dāng)發(fā)起人角色的狀態(tài)改變的時候,有可能這個協(xié)議無效。如果狀態(tài)改變的成功率不高的話,不如采取“假如”協(xié)議模式。

    posted on 2011-02-08 16:48 人在江湖 閱讀(3541) 評論(0)  編輯  收藏 所屬分類: design pattern
    主站蜘蛛池模板: 亚洲丰满熟女一区二区v| 亚洲中文字幕无码中文字在线 | 亚洲啪啪免费视频| 伊人免费在线观看高清版| 在线免费观看一级毛片| 亚洲成人激情小说| 国产成人精品免费午夜app| 亚洲情XO亚洲色XO无码| 国产在线观看免费av站| 亚洲天堂在线视频| 菠萝菠萝蜜在线免费视频| 国产免费黄色大片| 免费VA在线观看无码| 国产av无码专区亚洲国产精品| wwwxxx亚洲| 日韩免费电影在线观看| 亚洲av日韩专区在线观看| 四虎影视永久免费观看网址| 深夜福利在线视频免费| 亚洲AV无码专区国产乱码4SE| 大地影院MV在线观看视频免费| 久久久久亚洲Av片无码v| 91精品国产免费| 色欲aⅴ亚洲情无码AV蜜桃| 亚洲国产主播精品极品网红 | 亚洲综合在线另类色区奇米| 免费91麻豆精品国产自产在线观看 | 91在线视频免费91| 亚洲国产午夜精品理论片在线播放| 全黄a免费一级毛片人人爱| aaa毛片视频免费观看| 亚洲春黄在线观看| 免费真实播放国产乱子伦| 日韩精品免费在线视频| 亚洲国产欧美国产综合一区| 亚洲综合色视频在线观看| 男女做羞羞的事视频免费观看无遮挡| 性色av极品无码专区亚洲| 亚洲国产天堂在线观看| 国产精品免费看久久久无码| 嫩草成人永久免费观看|