摘要:問題如何重新設計這兩個類來讓代碼更簡潔呢首先看一下兩個類的類圖每個類中都有方法。模板方法定義了一個算法的步驟,并且允許子類為一個或多個步驟提供實現(xiàn)。好萊塢原則模板方法使用到了一個原則,好萊塢原則。
date: 2018-12-02T17:23:56+08:00
description: python 設計模式 模板方法模式
draft: false
slug: "python-design-pattern-template-pattern"
categories: ["development", "python", "設計模式"]
tags: ["python", "讀書筆記", "設計模式"]
首先先介紹一下咖啡和茶的沖泡方法:
茶
1. 把水煮沸 2. 用沸水浸泡茶葉 3. 把茶放到杯子里
咖啡
1. 把水煮沸 2. 用沸水沖泡咖啡 3. 把咖啡倒進杯子 4. 加糖和牛奶
用python代碼實現(xiàn)沖泡方法大概是這個樣子:
# 茶的制作方法 class Tea: def prepare_recipe(self): # 在下邊實現(xiàn)具體步驟 self.boil_water() self.brew_tea_bag() self.pour_in_cup() def boil_water(self): print("Boiling water") def brew_tea_bag(self): print("Steeping the tea") def pour_in_cup(self): print("Pouring into cup")
# 咖啡的制作方法 class Coffee: def prepare_recipe(self): # 在下邊實現(xiàn)具體步驟 self.boil_water() self.brew_coffee_grinds() self.pour_in_cup() self.add_sugar_and_milk() def boil_water(self): print("Boiling water") def brew_coffee_grinds(self): print("Dripping Coffee through filter") def pour_in_cup(self): print("Pouring into cup") def add_sugar_and_milk(self): print("Adding Sugar and Milk")
仔細看上邊兩端代碼會發(fā)現(xiàn),茶和咖啡的實現(xiàn)方式基本類似,都有prepare_recipe,boil_water,pour_in_cup 這三個方法。
問題:如何重新設計這兩個類來讓代碼更簡潔呢?
首先看一下兩個類的類圖:
每個類中都有 prepare_recipe() boil_water() pour_in_cup()方法。
每個類中prepare_recipe()方法的實現(xiàn)都不一樣。
現(xiàn)在把prepare_recipe() boil_water() pour_in_cup()三個方法抽取出來做成一個父類CoffeineBeverage(),Tea 和 Coffee 都繼自CoffeineBeverage()。
因為每個類中prepare_recipe()實現(xiàn)的方法不一樣,所以Tea 和 Coffee 類都分別實現(xiàn)了 prepare_recipe()。
問題: 那么,有沒有辦法將prepare_recipe()也抽象化?
對比 Tea 和 Coffee 的prepare_recipe() 方法會發(fā)現(xiàn),他們之間的差異主要是:
def prepare_recipe(self): # 相同部分隱藏 # self.boil_water() self.brew_tea_bag() # 差異1 #self.pour_in_cup() def prepare_recipe(self): # 相同部分隱藏 # self.boil_water() self.brew_coffee_grinds() # 差異1 # self.pour_in_cup() self.add_sugar_and_milk() # 差異2
這里的實現(xiàn)思路是,將兩處差異分別用新的方法名代替,替換后結(jié)果如下:
def prepare_recipe(self): # 新的實現(xiàn)方法 self.boil_water() self.brew() # 差異1 使用brew 代替 brew_tea_bag 和 brew_coffee_grinds self.pour_in_cup() self.add_condiments() # 差異2 Tea 不需要此方法,可以用空的實現(xiàn)代替
新的類圖如下:
現(xiàn)在,類 Tea 和 Coffee 只需要實現(xiàn)具體的 brew()和 add_condiments() 方法即可。代碼實現(xiàn)如下:
class CoffeineBeverage: def prepare_recipe(self): # 新的實現(xiàn)方法 self.boil_water() self.brew() self.pour_in_cup() self.add_condiments() def boil_water(self): print("Boiling water") def brew(self): # 需要在子類實現(xiàn) raise NotImplementedError def pour_in_cup(self): print("Pouring into cup") def add_condiments(self): # 這里其實是個鉤子方法,子類可以視情況選擇是否覆蓋 # 鉤子方法是一個可選方法,也可以讓鉤子方法作為某些條件觸發(fā)后的動作 pass # 茶的制作方法 class Tea(CoffeineBeverage): def brew(self): # 父類中聲明了 raise NotImplementedError,這里必須要實現(xiàn)此方法 print("Steeping the tea") # Tea 不需要 add_condiments 方法,所以這里不需要實現(xiàn) # 咖啡的制作方法 class Coffee(CoffeineBeverage): def brew(self): # 父類中聲明了 raise NotImplementedError,這里必須要實現(xiàn)此方法 print("Dripping Coffee through filter") def add_condiments(self): print("Adding Sugar and Milk")模板方法
上述抽象過程使用的就是模板方法。模板方法定義了一個算法的步驟,并且允許子類為一個或多個步驟提供實現(xiàn)。在這個例子中,prepare_recipe 就是一個模板方法。
定義:模板方法牧師在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。優(yōu)點
使用模板方法可以將代碼的復用最大化
子類只需要實現(xiàn)自己的方法,將算法和實現(xiàn)的耦合降低。
好萊塢原則模板方法使用到了一個原則,好萊塢原則。
好萊塢原則,別調(diào)用我,我會調(diào)用你。
在這個原則之下,允許低層組件將自己掛鉤到系統(tǒng)上,但是由高層組件來決定什么時候使用這些低層組件。
在上邊的例子中,CoffeineBeverage 是高層組件,Coffee和Tea 是低層組件,他們不會之間調(diào)用抽象類(CoffeineBeverage)。
一個例子文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42730.html
摘要:您的應用程序的目錄,它包含模式和回調(diào)函數(shù)之間的簡單映射。更性感自動生成的管理功能這個概述幾乎沒有觸及表面。 django概述 因為django是在快節(jié)奏的編輯環(huán)境下開發(fā)的,它旨在使常見的Web開發(fā)任務變得快速而簡單。 這是一個關于如何用django編寫數(shù)據(jù)庫驅(qū)動的Web應用程序的非正式概述。 本文檔的目的是為您提供足夠的技術細節(jié)來了解django的工作原理,但這不是一個教程或參考 - ...
摘要:在本節(jié)實驗中,我們學習了四種設計模式策略模式,觀察者模式,命令模式以及模板方法模式。這四種設計模式都是行為型模式。這就是適配器模式。下面讓我們看看適配器模式在實驗樓中使用吧。準確來說,裝飾者模式能動態(tài)的給對象添加行為。 1、策略模式 策略模式將各種操作(算法)進行封裝,并使它們之間可以互換。互換的意思是說可以動態(tài)改變對象的操作方式(算法)。 -- coding: utf-8 -- im...
摘要:前言在文章基于環(huán)境搭建框架方法介紹中介紹了客戶端和服務器的交互過程,服務器接收客戶端的請求后,由應用服務器對瀏覽器的請求進行處理,將生成的響應傳遞給服務器,再由服務器返回給客戶端。 前言 在文章《基于Linux環(huán)境搭建Nginx+uWSGI+Python框架方法介紹》中介紹了客戶端和Web服務器的交互過程,Web服務器接收客戶端的請求后,由Web應用服務器對瀏覽器的請求進行處理,將生成...
摘要:核心的幾個組件模板引擎,框架,請求和應答的處理還是有一些難度,但是經(jīng)過一步步的分析和編碼還是能夠完成功能。模板引擎模板引擎是另外一個比較大和的模塊。 前前后后,大概兩個月的時間,lunar這個項目終于達到了一個很高的完整度。 Lunar是一個Python語言的網(wǎng)絡框架,類似于Django,F(xiàn)lask,Tornado等當下流行的web framework。最初有這個想法是在大二下學期,...
摘要:示例如下靜態(tài)路由使用動態(tài)變量的路由未指定變量類型使用動態(tài)變量的路由指定變量類型指定的路由變量,可以作為被裝飾的函數(shù)參數(shù)傳入進來。 開始決定認真的在網(wǎng)上寫一些東西,主要原因還是在于希望能提升學習效果。雖說python寫了有幾年,但是web后端框架的確沒怎么接觸過,買了本狗書寥寥草草的過了一遍,發(fā)現(xiàn)很多東西還是理解不深,真的是好記性不如爛筆頭,知識也要從基礎開始,退回來好好看看官方文檔,再...
閱讀 2733·2023-04-25 14:21
閱讀 1167·2021-11-23 09:51
閱讀 4001·2021-09-22 15:43
閱讀 606·2019-08-30 15:55
閱讀 1550·2019-08-29 11:28
閱讀 2439·2019-08-26 11:44
閱讀 1675·2019-08-23 18:15
閱讀 2875·2019-08-23 16:42