平時你們上班都很累,爲了增長工做中的歡樂氣氛,黃頁組準備搞個遊戲。python
遊戲的名字是把大象關進冰箱。遊戲很簡單,須要把指定的物品放進冰箱。算法
咱們都知道,把大象放進冰箱,分3步。spa
第一步,打開冰箱門,第二步,把大象放進去,第三步,關上冰箱。3d
可是,首先你的有一頭大象,因此,人爲又加了第零步,準備一隻大象。code
爲了保證遊戲的歡樂性,咱們規定遊戲者,在第二步把大象放進去的時候,須要有不一樣的表情動做等。blog
好,我並無逗你玩。繼承
遊戲開始。three
大雁同窗頗有興趣。因而,咱們編寫一個簡單的程序來實現這個過程。遊戲
寫一個類.實現這個過程。it
class PlayerDaisy: s_object = None def __init__(self): pass def set_up(self): PlayerDaisy.s_object = "大象" print '準備一隻大象 daisy 去了泰國買了一隻', PlayerDaisy.s_object def step_one(self): print '打開冰箱門' def step_two(self): print '蹦蹦跳跳哭着,把大象放進冰箱' def step_three(self): print '關上冰箱門'
if __name__ == "__main__": daisy = PlayerDaisy() daisy.set_up() daisy.step_one() daisy.step_two() daisy.step_three()
運行結果:
菜菜,以爲挺好玩的因而也加入了遊戲...
因而,咱們繼續編寫代碼
class PlayerYicai: s_object = None def __init__(self): pass def set_up(self): PlayerDaisy.s_object = "老虎" print 'caicai 去了孟加拉買了一隻', PlayerYicai.s_object def step_one(self): print '打開冰箱門' def step_two(self): print '歪歪扭扭笑着,把%s進冰箱' % PlayerYicai.s_object def step_three(self): print '關上冰箱門'
而後高峯,羞羞....都以爲挺好玩的,都紛紛加入了遊戲...
愈來愈多的人加入,因而,咱們開始抄代碼。。。複製,粘貼
狀況有所不妙,抄得過程當中,高峯忘記抄了step1, 沒打開冰箱門。
結果鱷魚,無法放進去了.....
羞羞忘記抄step3了,獅子,關進去,又出來了...
相似的狀況愈來愈糟。
DRY:don't repeat yourself.
在這個繽紛的世界上,是否有東西,會永遠不變?
諺語:
the only thing in the world that doesn't change is change itself.
因此,please DRY,也叫 DIE (duplication is evil)
上面的話,是我抄的。
重複是醜陋的,也是bug的溫牀。
ok, 那麼咱們能夠嘗試用模板方法模式來避免這種壞味道。
1. 概述
定義一個操做中的算法的骨架,而將步驟延遲到子類中。模板方法使得子類能夠不改變一個算法的結構便可重定義算法的某些特定步驟。
2. 模式中的角色
2.1 抽象類(AbstractClass):實現了模板方法,定義了算法的骨架。
2.2 具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的算法。
3. 模板方法類圖:
那麼,咱們嘗試改造代碼。
首先,須要寫一個基類。
因爲開冰箱門和關冰箱門是固定的。因此定義抽象方法或虛方法第二步放物品。和準備物品。
咱們還需定義一個公共的playgame方法。規定遊戲的步驟,這樣的話,就不再會抄錯啦。
子類必須實現父類的抽象方法。父類又定義了完成遊戲的模板。
簡直完美。
在python中 abc 模塊(咦?爲啥用個衛生巾的名字)實現了 抽象類和方法的功能。(我也是bing後才知道的)
使用了
@abc.abstractmethod裝飾器的方法必需要在子類中實現
代碼以下:
class PlayerBase(object): s_object = "未知東東" def __init__(self): pass @abc.abstractmethod def set_up(self): pass def step_one(self): print '打開冰箱門' @abc.abstractmethod def step_two(self): pass def step_three(self): print '關上冰箱門' def play_game(self): self.set_up() self.step_one() self.step_two() self.step_three()
繼承類。
class PlayerDaisy2(PlayerBase): def __init__(self): pass def set_up(self): PlayerDaisy.s_object = "大象" print '準備物品 去了買了一隻', PlayerDaisy.s_object def step_two(self): print '%s,把%s放進冰箱' % ('蹦蹦跳跳哭着', PlayerDaisy.s_object)
if __name__ == "__main__": daisy = PlayerDaisy2() daisy.play_game()
運行結果:
恩恩。。。太完美了。。。
模板方法模式就到這裏。。
花了我幾個小時寫這篇文章。
構思都是在地鐵上。
to be continued