您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎樣深入理解Java設(shè)計(jì)模式的備忘錄模式,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
定義:在不破壞封閉的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。
該模式用于保存對(duì)象當(dāng)前狀態(tài),并且在之后可以再次恢復(fù)到此狀態(tài)。備忘錄模式實(shí)現(xiàn)的方式需要保證被保存的對(duì)象狀態(tài)不能被對(duì)象從外部訪問(wèn),
目的是為了保護(hù)被保存的這些對(duì)象狀態(tài)的完整性以及內(nèi)部實(shí)現(xiàn)不向外暴露
涉及角色:
1.Originator
(發(fā)起人):負(fù)責(zé)創(chuàng)建一個(gè)備忘錄Memento,用以記錄當(dāng)前時(shí)刻自身的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)。Originator可以根據(jù)需要決定Memento存儲(chǔ)自己的哪些內(nèi)部狀態(tài)。
2.Memento
(備忘錄):負(fù)責(zé)存儲(chǔ)Originator對(duì)象的內(nèi)部狀態(tài),并可以防止Originator以外的其他對(duì)象訪問(wèn)備忘錄。備忘錄有兩個(gè)接口:Caretaker只能看到備忘錄的窄接口,他只能將備忘錄傳遞給其他對(duì)象。Originator卻可看到備忘錄的寬接口,允許它訪問(wèn)返回到先前狀態(tài)所需要的所有數(shù)據(jù)。
3.Caretaker
(管理者):負(fù)責(zé)備忘錄Memento,不能對(duì)Memento的內(nèi)容進(jìn)行訪問(wèn)或者操作。
1.需要保存和恢復(fù)數(shù)據(jù)的相關(guān)狀態(tài)場(chǎng)景。
2.提供一個(gè)可回滾(rollback)的操作。
3.數(shù)據(jù)庫(kù)連接的事務(wù)管理就是用的備忘錄模式。
優(yōu)點(diǎn):
1、有時(shí)一些發(fā)起人對(duì)象的內(nèi)部信息必須保存在發(fā)起人對(duì)象以外的地方,但是必須要由發(fā)起人對(duì)象自己讀取,這時(shí),使用備忘錄模式可以把復(fù)雜的發(fā)起人內(nèi)部信息對(duì)其他的對(duì)象屏蔽起來(lái),從而可以恰當(dāng)?shù)乇3址庋b的邊界。
2、本模式簡(jiǎn)化了發(fā)起人類。發(fā)起人不再需要管理和保存其內(nèi)部狀態(tài)的一個(gè)個(gè)版本,客戶端可以自行管理他們所需要的這些狀態(tài)的版本。
3、當(dāng)發(fā)起人角色的狀態(tài)改變的時(shí)候,有可能這個(gè)狀態(tài)無(wú)效,這時(shí)候就可以使用暫時(shí)存儲(chǔ)起來(lái)的備忘錄將狀態(tài)復(fù)原。
缺點(diǎn):
1、如果發(fā)起人角色的狀態(tài)需要完整地存儲(chǔ)到備忘錄對(duì)象中,那么在資源消耗上面?zhèn)渫泴?duì)象會(huì)很昂貴。
2、當(dāng)負(fù)責(zé)人角色將一個(gè)備忘錄 存儲(chǔ)起來(lái)的時(shí)候,負(fù)責(zé)人可能并不知道這個(gè)狀態(tài)會(huì)占用多大的存儲(chǔ)空間,從而無(wú)法提醒用戶一個(gè)操作是否很昂貴。
3、當(dāng)發(fā)起人角色的狀態(tài)改變的時(shí)候,有可能這個(gè)協(xié)議無(wú)效。如果狀態(tài)改變的成功率不高的話,不如采取“假如”協(xié)議模式。
實(shí)例:備份電話本
聯(lián)系人--需要備份的數(shù)據(jù),是狀態(tài)數(shù)據(jù),沒(méi)有操作
public sealed class ContactPerson { //姓名 public string Name { get; set; } //電話號(hào)碼 public string MobileNumber { get; set; } }
發(fā)起人--相當(dāng)于【發(fā)起人角色】Originator
public sealed class MobileBackOriginator { // 發(fā)起人需要保存的內(nèi)部狀態(tài) private List<ContactPerson> _personList; public List<ContactPerson> ContactPersonList { get { return this._personList; } set { this._personList = value; } } //初始化需要備份的電話名單 public MobileBackOriginator(List<ContactPerson> personList) { if (personList != null) { this._personList = personList; } else { throw new ArgumentNullException("參數(shù)不能為空!"); } } // 創(chuàng)建備忘錄對(duì)象實(shí)例,將當(dāng)期要保存的聯(lián)系人列表保存到備忘錄對(duì)象中 public ContactPersonMemento CreateMemento() { return new ContactPersonMemento(new List<ContactPerson>(this._personList)); } // 將備忘錄中的數(shù)據(jù)備份還原到聯(lián)系人列表中 public void RestoreMemento(ContactPersonMemento memento) { this.ContactPersonList = memento.ContactPersonListBack; } public void Show() { Console.WriteLine("聯(lián)系人列表中共有{0}個(gè)人,他們是:", ContactPersonList.Count); foreach (ContactPerson p in ContactPersonList) { Console.WriteLine("姓名: {0} 號(hào)碼: {1}", p.Name, p.MobileNumber); } } }
備忘錄對(duì)象,用于保存狀態(tài)數(shù)據(jù),保存的是當(dāng)時(shí)對(duì)象具體狀態(tài)數(shù)據(jù)--相當(dāng)于【備忘錄角色】Memeto
public sealed class ContactPersonMemento { // 保存發(fā)起人創(chuàng)建的電話名單數(shù)據(jù),就是所謂的狀態(tài) public List<ContactPerson> ContactPersonListBack { get; private set; } public ContactPersonMemento(List<ContactPerson> personList) { ContactPersonListBack = personList; } }
管理角色,它可以管理【備忘錄】對(duì)象,如果是保存多個(gè)【備忘錄】對(duì)象,當(dāng)然可以對(duì)保存的對(duì)象進(jìn)行增、刪等管理處理---相當(dāng)于【管理者角色】Caretaker
public sealed class MementoManager { //如果想保存多個(gè)【備忘錄】對(duì)象,可以通過(guò)字典或者堆棧來(lái)保存,堆棧對(duì)象可以反映保存對(duì)象的先后順序 //比如:public Dictionary<string, ContactPersonMemento> ContactPersonMementoDictionary { get; set; } public ContactPersonMemento ContactPersonMemento { get; set; } }
客戶端代碼
class Program { static void Main(string[] args) { List<ContactPerson> persons = new List<ContactPerson>() { new ContactPerson() { Name="黃飛鴻", MobileNumber = "13533332222"}, new ContactPerson() { Name="方世玉", MobileNumber = "13966554433"}, new ContactPerson() { Name="洪熙官", MobileNumber = "13198765544"} }; //手機(jī)名單發(fā)起人 MobileBackOriginator mobileOriginator = new MobileBackOriginator(persons); mobileOriginator.Show(); // 創(chuàng)建備忘錄并保存?zhèn)渫泴?duì)象 MementoManager manager = new MementoManager(); manager.ContactPersonMemento = mobileOriginator.CreateMemento(); // 更改發(fā)起人聯(lián)系人列表 Console.WriteLine("----移除最后一個(gè)聯(lián)系人--------"); mobileOriginator.ContactPersonList.RemoveAt(2); mobileOriginator.Show(); // 恢復(fù)到原始狀態(tài) Console.WriteLine("-------恢復(fù)聯(lián)系人列表------"); mobileOriginator.RestoreMemento(manager.ContactPersonMemento); mobileOriginator.Show(); Console.Read(); } }
上述內(nèi)容就是怎樣深入理解Java設(shè)計(jì)模式的備忘錄模式,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。