備忘錄模式 給你一瓶後悔藥

2021-07-26 05:04:25 字數 3744 閱讀 1105

在生活中,每個人都應該有這樣的經歷:如果我當初那樣做就好了,也不會出現現在的情況。這裡的如果怎樣都是對當初所選擇的做法的後悔,

如果當初多看點書,如果當初都努力下,如果......太多太多的如果了,可是現實世界沒有後悔藥,過去了就已經成為事實,改變不了。在現實世界

雖然沒有後悔藥,但是在**中有,而這也是今天要介紹的主角——備忘錄模式。其中又可以分為:標準版備忘錄、clone版備忘錄、多狀態備忘錄、

多備份的備忘錄、私有備忘錄等。

這裡先描述下場景,然後將各種情況的備忘錄給實現出來。場景:a的同事生日了,a要送份禮物,可是a不知道同事喜歡什麼,如果送了同事喜歡的禮物

首先是標準版的備忘錄:

public

class choosegift

}class aperson

public

void

setgiftname(string giftname)

public memento creatememento()

public

void

restore(memento memento)

}class memento

public string getgiftname()

public

void

setgiftname(string giftname)

}class mementomanager

public

void

setmemento(memento memento)

}

客戶端輸出:

未送禮前的狀態:禮物未選擇

送錯了禮物的狀態:不喜歡的禮物

發現了送錯了禮物,吃下後悔藥,回到開始狀態 :禮物未選擇

clone版備忘錄:
public

class choosegift

}class aperson implements cloneable

public

void

setgiftname(string giftname)

public

void

creatememento()

public

void

restore()

@override

protected aperson clone() catch (clonenotsupportedexception e)

}}

控制台輸出:

未送禮前的狀態:禮物未選擇

送錯了禮物的狀態:不喜歡的禮物

clone版備忘錄模式相比較於標準版**是簡潔了一些,不過其中有兩點問題,一是、clone是整個物件的複製,而有時,只需儲存一兩個狀態值,

私有備忘錄:

public

class

choosegift

}class aperson

public

void

setgiftname(string giftname)

public mementoimpl creatememento()

public

void

restore(mementoimpl mementoimpl)

private

class

memento

implements

mementoimpl

private string getgiftname()

}}inte***ce mementoimpl

class mementomanager

public

void

setmemento(mementoimpl memento)

}

控制台輸出:

未送禮前的狀態:禮物未選擇

送錯了禮物的狀態:不喜歡的禮物

發現了送錯了禮物,吃下後悔藥,回到開始狀態 :禮物未選擇

這裡使用了乙個新的設計模式:雙介面設計,我們設計的乙個類可以實現多個介面,在系統設計時,如果考慮物件的安全問題,則可以提供兩個介面,

乙個是業務的正常介面,實現必要的業務邏輯(平時使用的普通介面),叫做寬介面;另乙個介面是空介面,什麼方法都沒有,其目的是提供給子系統外的模組訪問,

比如容器物件,這個叫做窄介面,由於窄介面沒有提供任何操縱資料的方法,因此相對來說比較安全。(這一段引自設計模式之禪)

上述描述的都是依賴當前的場景而給出的解決辦法,但是需要知道一點是需求是會變的,如果同事要求來的時候順便帶個蛋糕,而a又忘了要到什麼口味的,

這時就要求a同時存在兩個初始資訊,蛋糕資訊和禮物資訊。雖然可以參考原先的繼續構建乙個蛋糕的備忘錄,但如果後續還增加,那增加的備忘錄就太多了,

這時多狀態的備忘錄就派上用處了。

多狀態備忘錄模式:

public

class

choosegift

}class aperson

public

void

setgiftname(string giftname)

public string getcakeinfo()

public

void

setcakeinfo(string cakeinfo)

public memento creatememento()

public

void

restore(memento memento)

}class memento

public mapgetmap()

}class mementomanager

public

void

setmemento(memento memento)

}class beanutil

return map;

}/**

*@introduce:根據屬性名獲取相應的值

*/private

static object getvalue(string fieldname, object obj) );

object object = method.invoke(obj, new object {});

return object;

} catch (exception e)

}/**

*@introduce:獲取物件的所有屬性名

*/private

static string getfieldnamearray(object obj)

return fieldnamearray;

}}

控制台輸出:

未送禮前的狀態:禮物未選擇—蛋糕未選擇

送錯了禮物的狀態:不喜歡的禮物—錯誤口味的蛋糕

發現了送錯了禮物,吃下後悔藥,回到開始狀態 :禮物未選擇—蛋糕未選擇

多備份的備忘錄模式就是a買了乙個禮物,就儲存乙個備忘錄,可能一開始這些禮物,同事都不喜歡,後來同事都其中乙個感興趣了,只要回到當初儲存的備忘錄

中即可,這個比較簡單只是在mementomanager中本來儲存的資訊改為儲存乙個map,將各個需要的備忘都存放進去,用的時候取相應的即可。

這裡有個問題就是記憶體可能溢位,所以儲存備忘錄時要注意。

備忘錄模式

備忘錄模式 memento 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。originator 發起人 負責建立乙個備忘錄memento,用以記錄當前時刻它的內部狀態,並可以使用備忘錄恢復內部狀態。originator可根據需要...

備忘錄模式

先從物件導向的三大特徵之一封裝說起。物件導向的封裝簡單點說就是把狀態 資料 和行為 操作這些資料的方法 放到一起,構成乙個單元,通常叫做類。乙個物件的行為是事先確定好的 靜態 一些指令碼,如果物件的狀態相同,物件看起來就是一樣的。所以當我們需要把乙個物件的某一時刻儲存起來,那麼只需要儲存它在那個時刻...

備忘錄模式

面臨問題 物件狀態的變化無端,如何回溯恢復物件在某個點的狀態?在軟體構建過程中,某些物件的狀態在轉換過程中,可能由於某種需要,要求程式能夠回溯到物件之前處於某個點時的狀態。如果使用一些公用介面來讓其他物件得到物件的狀態,便會暴露物件的細節實現。如何實現物件狀態的良好儲存與恢復?但同時又不會因此而破壞...