定義:
在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態,這樣以後就可以將該物件恢復到原先儲存的狀態。
備忘錄模式主要是對某個物件的狀態的備份,備份的主要是物件當前的屬性值,即成員變數的值,成員變數可以有多個,而且可以備份同乙個物件的多種不同狀態,即同乙個物件可以同時有多個備份,先來看最簡單的情況,即乙個物件只有乙個成員變數:
其通用類圖為:
源**如下:
/*
* 單屬性的備忘錄模式,本類即是需要被備份的類
*/public class originator
public void setstate(string state)
public void changestate()
public memento creatememento()
public void restorememento(memento memento)
}
/*
* 備忘錄類
*/public class memento
public string getstate()
public void setstate(string state)
}
/*
* 備忘錄管理類
*/public class caretaker
public void setmemento(memento memento)
}
public class client
}
要是遇到多屬性怎麼辦?要是乙個物件不僅僅只需要備份一次,而需要備份很多次,又該如何呢?看下面改進原始碼:
/*
* 多屬性的備忘錄模式
*/public class originator
public void setstate1(string state1)
public string getstate2()
public void setstate2(string state2)
public string getstate3()
public void setstate3(string state3)
//將本物件的各個屬性以hashmap型別儲存到memento物件中
public memento creatememento()
//從memento物件中取出儲存的物件的屬性狀態,並賦值給本物件的各個屬性
public void restorememento(memento memento)
public string tostring()
}
//memento的成員變數為乙個hashmap型別的,是為了儲存源目標物件的各個屬性的名和值
public class memento
public hashmapgetstatemap()
public void setstatemap(hashmapstatemap)
}
/**
* 多備份備份,即可以備份乙個物件的多種狀態,
* 注意這種多備份,不要用於備份特別頻繁的地方,容易出現記憶體溢位,
* 或者增加map的上限,防止出現記憶體的洩漏。
*/public class caretaker
public void setmemento(string key, memento memento)
}
/*
* 使用此類是為了操作方便
*/public class beanutils );//讀取屬性值
if(!fieldname.equalsignorecase("class"))
}}catch(exception e)
return result; }
//把hashmap的值放到bean中
public static void hashtobean(object bean, hashmapresult));//將值寫入到屬性中}}
}catch(exception e)
}}
public class client
}
多個屬性,多個備份嘛,那就把備忘錄類和備忘錄管理類換成集合型別就可以了。但是這種做法要特別注意記憶體溢位的問題,不要在備份頻繁的地方使用這種備忘錄模式,可以設定map的上限,來防止記憶體洩露。
另外,備份還可以有另外一種實現方式,備份嘛,自然會聯想到複製,也就聯想到原型模型了,可以使用轉殖的方法來實現備忘錄,如下原始碼:
/*
* 通過轉殖物件的方式實現備忘錄
*/public class originator implements cloneable
public void setstate(string state)
public void changestate()
public originator creatememento()
public void restorememento(originator originator)
@override
protected originator clone()catch(clonenotsupportedexception e)
return null;
}}
public class caretaker
public void setmemento(originator originator)
}
還有,如果需要想要增加安全性,即備份的東西是不可以隨便改變的,除了原發起物件之外,其他的物件是都不可訪問這個備忘錄的,我個人現在淺薄的觀點認為,只要在備忘錄類中不實現那個setmemento()方法,不就可以避免這個類的物件被修改了嗎?反正這個方法沒有被用到,不知道這樣做對不對,《設計模式之禪》的作者有他的做法,即把備忘錄類作為原發起物件的乙個內部類,這樣就可以實現只有發起物件可以訪問這個備忘錄類了,再讓這個內部類實現乙個空的介面,讓其可以在外和其他類建立關聯關係,其實現**如下:
public inte***ce imemento
/*
* 使用內部類,增強安全性
*/public class originator
public void setstate(string state)
public void changestate()
public memento creatememento()
public void restorememento(imemento memento)
//把備忘錄類寫成內部類,這樣只有發起人才能訪問備忘錄,其他物件都不可以訪問,這就增加了備忘錄的安全性
//實現了乙個空的介面,以便於在外邊和其他類產生關聯關係。
private class memento implements imemento
private string getstate()
}}
//在原發起類的外部使用備忘錄類的空介面建立和其他物件的關聯
public class caretaker
public void setmemento(imemento memento)
}
《設計模式》學習筆記 備忘錄模式
備忘錄模式 memento pattern 儲存乙個物件的某個狀態,以便在適當的時候恢復物件。備忘錄模式屬於行為型模式。意圖 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。主要解決 所謂備忘錄模式就是在不破壞封裝的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀...
設計模式筆記 備忘錄模式
在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態,便於將該物件恢復到原先儲存的狀態。originator 發起人角色 記錄當前時刻的內部狀態,負責定義哪些屬於備份範圍的狀態,負責建立和恢復被萬福路資料 public class originator public void ...
設計模式學習 備忘錄模式
備忘錄模式 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態,這樣以後就可以將該物件恢復到原先儲存的狀態 originator 發起人,負責建立乙個備忘錄memento,用以記錄當前時刻他的內部狀態,並可使用備忘錄恢復內部狀態,originator可根據需要覺得mement...