python 設計模式之備忘錄模式

 1.爲何用備忘錄模式

 假設大戰殭屍遊戲共10關,越是日後關卡越難,越難就越是費時間費錢費精力。html

 

開始大戰殭屍,玩了很久很久終於玩到了第9關,真是不容易。python

這個時候開始玩第9關了,哇,好難啊,真不幸,輸掉了。app

好沮喪,只能從第一關再來一輪了。dom

 

要是第9關玩輸了之後,直接再從第9關開始玩,而不是從頭再來。那該多好呀,會省很多時間的。ide

 

那能不能把玩到第9關這個遊戲進度給保存下來orm

xml

用備忘錄模式htm

 

 

 

 

2. 定義

在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該對象恢復到原先保存的狀態。對象

 在備忘錄模式中,若是要保存的狀態多,能夠創造一個備忘錄管理者角色來管理備忘錄blog

 

3.備忘錄模式的優勢

 一、有時一些發起人對象的內部信息必須保存在發起人對象之外的地方,可是必需要由發起人對象本身讀取,這時,
使用備忘錄模式能夠把複雜的發起人內部信息對其餘的對象屏蔽起來,從而能夠恰當地保持封裝的邊界。
二、本模式簡化了發起人類。發起人再也不須要管理和保存其內部狀態的一個個版本,客戶端能夠自行管理他們所需
要的這些狀態的版本。
三、當發起人角色的狀態改變的時候,有可能這個狀態無效,這時候就可使用暫時存儲起來的備忘錄將狀態復原。

 

4.備忘錄模式的缺點:

 一、若是發起人角色的狀態須要完整地存儲到備忘錄對象中,那麼在資源消耗上面備忘錄對象會很昂貴。
二、當負責人角色將一個備忘錄 存儲起來的時候,負責人可能並不知道這個狀態會佔用多大的存儲空間,從而沒法提醒用戶一個操做是否很昂貴。
三、當發起人角色的狀態改變的時候,有可能這個協議無效。若是狀態改變的成功率不高的話,不如採起「假如」協議模式。

 

5.例子

import random

class zombie:
    goldCoin=0  #金幣數量
    sun=0        #陽光數量
    teWuBean=0   #特務豌豆射手數量
    goldenSunflower=0  #金屬向日葵數量
    icyIceCactus=0    #寒冰仙人掌數量

    def disState(self):
        print('zombie game current status is as below:')
        print('goldCoin : {}'.format(self.goldCoin))
        print('sun : {}'.format(self.sun))
        print('teWuBean : {}'.format(self.teWuBean))
        print('goldenSunflower : {}'.format(self.goldenSunflower))
        print('icyIceCactus : {}'.format(self.icyIceCactus))

    def initState(self,goldCoin,sun,teWuBean,goldenSunflower,icyIceCactus):
        self.goldCoin=goldCoin
        self.sun=sun
        self.teWuBean=teWuBean
        self.goldenSunflower=goldenSunflower
        self.icyIceCactus=icyIceCactus

    def saveState(self):
        return memo(self.goldCoin,self.sun,self.teWuBean,self.goldenSunflower,self.icyIceCactus)

    def recoverState(self,memo):
        self.goldCoin=memo.goldCoin
        self.sun=memo.sun
        self.teWuBean=memo.teWuBean
        self.goldenSunflower=memo.goldenSunflower
        self.icyIceCactus=memo.icyIceCactus

class fightState(zombie):
    def fight(self):
        self.goldCoin=random.randint(1000,100000)
        self.sun=random.randint(1000,100000)
        self.teWuBean=random.randint(1,10)
        self.goldenSunflower=random.randint(1,10)
        self.icyIceCactus=random.randint(1,10)     
    
class memo():
    goldCoin=0  
    sun=0        
    teWuBean=0   
    goldenSunflower=0  
    icyIceCactus=0

    def __init__(self,goldCoin,sun,teWuBean,goldenSunflower,icyIceCactus):
        self.goldCoin=goldCoin
        self.sun=sun
        self.teWuBean=teWuBean
        self.goldenSunflower=goldenSunflower
        self.icyIceCactus=icyIceCactus

        

if __name__ == "__main__":
    curState=fightState()
    curState.initState(10000,9000,10,10,10)
    print('如今植物大戰殭屍遊戲第8關已通關,立刻開始打第9關了,目前遊戲參數值以下:')
    curState.disState()
    state8=curState.saveState()  
    curState.fight()
    print('越是日後關卡越難,第9關打完了了,真是慘不忍睹,目前參數值以下:')
    curState.disState()
    print('完敗呀,只能重打了,恢復到第8關通關的參數吧,恢復以下')
    curState.recoverState(state8)
    curState.disState()
    print('恢復完了,再開始第9關吧')

 運行結果以下:

 

 

 6.涉及角色

1.Originator(發起人):負責建立一個備忘錄Memento,用以記錄當前時刻自身的內部狀態,並可以使用備忘錄恢復內部狀態。Originator能夠根據須要決定Memento存儲本身的哪些內部狀態。
2.Memento(備忘錄):負責存儲Originator對象的內部狀態,並能夠防止Originator之外的其餘對象訪問備忘錄。備忘錄有兩個接口:Caretaker只能看到備忘錄的窄接口,他只能將備忘錄傳遞給其餘對象。Originator卻可看到備忘錄的寬接口,容許它訪問返回到先前狀態所須要的全部數據。
3.Caretaker(管理者):負責備忘錄Memento,不能對Memento的內容進行訪問或者操做。

 

參考

https://baike.baidu.com/item/%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F/1430849?fr=aladdin

https://www.cnblogs.com/qq_841161825/articles/10144601.html(例子參考)

 https://baike.baidu.com/item/%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F/1430849?fr=aladdin

相關文章
相關標籤/搜索