成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

python設(shè)計(jì)模式-模板方法模式

jzzlee / 3378人閱讀

摘要:?jiǎn)栴}如何重新設(shè)計(jì)這兩個(gè)類(lèi)來(lái)讓代碼更簡(jiǎn)潔呢首先看一下兩個(gè)類(lèi)的類(lèi)圖每個(gè)類(lèi)中都有方法。模板方法定義了一個(gè)算法的步驟,并且允許子類(lèi)為一個(gè)或多個(gè)步驟提供實(shí)現(xiàn)。好萊塢原則模板方法使用到了一個(gè)原則,好萊塢原則。


date: 2018-12-02T17:23:56+08:00
description: python 設(shè)計(jì)模式 模板方法模式
draft: false
slug: "python-design-pattern-template-pattern"
categories: ["development", "python", "設(shè)計(jì)模式"]
tags: ["python", "讀書(shū)筆記", "設(shè)計(jì)模式"]

title: "python設(shè)計(jì)模式-模板方法模式"

首先先介紹一下咖啡和茶的沖泡方法:

1. 把水煮沸
2. 用沸水浸泡茶葉
3. 把茶放到杯子里

咖啡

1. 把水煮沸
2. 用沸水沖泡咖啡
3. 把咖啡倒進(jìn)杯子
4. 加糖和牛奶

用python代碼實(shí)現(xiàn)沖泡方法大概是這個(gè)樣子:

# 茶的制作方法
class Tea:

    def prepare_recipe(self):
        # 在下邊實(shí)現(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):
        # 在下邊實(shí)現(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")

仔細(xì)看上邊兩端代碼會(huì)發(fā)現(xiàn),茶和咖啡的實(shí)現(xiàn)方式基本類(lèi)似,都有prepare_recipe,boil_waterpour_in_cup 這三個(gè)方法。

問(wèn)題:如何重新設(shè)計(jì)這兩個(gè)類(lèi)來(lái)讓代碼更簡(jiǎn)潔呢?

首先看一下兩個(gè)類(lèi)的類(lèi)圖:

每個(gè)類(lèi)中都有 prepare_recipe() boil_water() pour_in_cup()方法。

每個(gè)類(lèi)中prepare_recipe()方法的實(shí)現(xiàn)都不一樣。

現(xiàn)在把prepare_recipe() boil_water() pour_in_cup()三個(gè)方法抽取出來(lái)做成一個(gè)父類(lèi)CoffeineBeverage(),TeaCoffee 都繼自CoffeineBeverage()

因?yàn)槊總€(gè)類(lèi)中prepare_recipe()實(shí)現(xiàn)的方法不一樣,所以TeaCoffee 類(lèi)都分別實(shí)現(xiàn)了 prepare_recipe()。
問(wèn)題: 那么,有沒(méi)有辦法將prepare_recipe()也抽象化?

對(duì)比 TeaCoffeeprepare_recipe() 方法會(huì)發(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

這里的實(shí)現(xiàn)思路是,將兩處差異分別用新的方法名代替,替換后結(jié)果如下:

def prepare_recipe(self):
    # 新的實(shí)現(xiàn)方法
    self.boil_water()
    self.brew() # 差異1 使用brew 代替 brew_tea_bag 和 brew_coffee_grinds
    self.pour_in_cup()
    self.add_condiments() # 差異2 Tea 不需要此方法,可以用空的實(shí)現(xiàn)代替

新的類(lèi)圖如下:

現(xiàn)在,類(lèi) TeaCoffee 只需要實(shí)現(xiàn)具體的 brew()add_condiments() 方法即可。代碼實(shí)現(xiàn)如下:

class CoffeineBeverage:

    def prepare_recipe(self):
        # 新的實(shí)現(xiàn)方法
        self.boil_water()
        self.brew() 
        self.pour_in_cup()
        self.add_condiments()
        
    def boil_water(self):
        print("Boiling water")
        
    def brew(self):
        # 需要在子類(lèi)實(shí)現(xiàn)
        raise NotImplementedError
        
    def pour_in_cup(self):
        print("Pouring into cup")
        
    def add_condiments(self):
        # 這里其實(shí)是個(gè)鉤子方法,子類(lèi)可以視情況選擇是否覆蓋
        # 鉤子方法是一個(gè)可選方法,也可以讓鉤子方法作為某些條件觸發(fā)后的動(dòng)作
        pass

# 茶的制作方法
class Tea(CoffeineBeverage):
        
    def brew(self):
        # 父類(lèi)中聲明了 raise NotImplementedError,這里必須要實(shí)現(xiàn)此方法
        print("Steeping the tea")
        
    # Tea 不需要 add_condiments 方法,所以這里不需要實(shí)現(xiàn)

# 咖啡的制作方法
class Coffee(CoffeineBeverage):
        
    def brew(self):
        # 父類(lèi)中聲明了 raise NotImplementedError,這里必須要實(shí)現(xiàn)此方法
        print("Dripping Coffee through filter")
        
    def add_condiments(self):
        print("Adding Sugar and Milk")
模板方法

上述抽象過(guò)程使用的就是模板方法。模板方法定義了一個(gè)算法的步驟,并且允許子類(lèi)為一個(gè)或多個(gè)步驟提供實(shí)現(xiàn)。在這個(gè)例子中,prepare_recipe 就是一個(gè)模板方法。

定義:模板方法牧師在一個(gè)方法中定義一個(gè)算法的骨架,而將一些步驟延遲到子類(lèi)中。模板方法使得子類(lèi)可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。
優(yōu)點(diǎn)

使用模板方法可以將代碼的復(fù)用最大化

子類(lèi)只需要實(shí)現(xiàn)自己的方法,將算法和實(shí)現(xiàn)的耦合降低。

好萊塢原則

模板方法使用到了一個(gè)原則,好萊塢原則。

好萊塢原則,別調(diào)用我,我會(huì)調(diào)用你。


在這個(gè)原則之下,允許低層組件將自己掛鉤到系統(tǒng)上,但是由高層組件來(lái)決定什么時(shí)候使用這些低層組件。

在上邊的例子中,CoffeineBeverage 是高層組件,Coffee和Tea 是低層組件,他們不會(huì)之間調(diào)用抽象類(lèi)(CoffeineBeverage)。

一個(gè)例子

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/42730.html

相關(guān)文章

  • django官方文檔1.11編翻:1-1-1概述

    摘要:您的應(yīng)用程序的目錄,它包含模式和回調(diào)函數(shù)之間的簡(jiǎn)單映射。更性感自動(dòng)生成的管理功能這個(gè)概述幾乎沒(méi)有觸及表面。 django概述 因?yàn)閐jango是在快節(jié)奏的編輯環(huán)境下開(kāi)發(fā)的,它旨在使常見(jiàn)的Web開(kāi)發(fā)任務(wù)變得快速而簡(jiǎn)單。 這是一個(gè)關(guān)于如何用django編寫(xiě)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的Web應(yīng)用程序的非正式概述。 本文檔的目的是為您提供足夠的技術(shù)細(xì)節(jié)來(lái)了解django的工作原理,但這不是一個(gè)教程或參考 - ...

    阿羅 評(píng)論0 收藏0
  • python設(shè)計(jì)模式

    摘要:在本節(jié)實(shí)驗(yàn)中,我們學(xué)習(xí)了四種設(shè)計(jì)模式策略模式,觀察者模式,命令模式以及模板方法模式。這四種設(shè)計(jì)模式都是行為型模式。這就是適配器模式。下面讓我們看看適配器模式在實(shí)驗(yàn)樓中使用吧。準(zhǔn)確來(lái)說(shuō),裝飾者模式能動(dòng)態(tài)的給對(duì)象添加行為。 1、策略模式 策略模式將各種操作(算法)進(jìn)行封裝,并使它們之間可以互換。互換的意思是說(shuō)可以動(dòng)態(tài)改變對(duì)象的操作方式(算法)。 -- coding: utf-8 -- im...

    array_huang 評(píng)論0 收藏0
  • 基于Linux環(huán)境的Web.py框架介紹

    摘要:前言在文章基于環(huán)境搭建框架方法介紹中介紹了客戶端和服務(wù)器的交互過(guò)程,服務(wù)器接收客戶端的請(qǐng)求后,由應(yīng)用服務(wù)器對(duì)瀏覽器的請(qǐng)求進(jìn)行處理,將生成的響應(yīng)傳遞給服務(wù)器,再由服務(wù)器返回給客戶端。 前言 在文章《基于Linux環(huán)境搭建Nginx+uWSGI+Python框架方法介紹》中介紹了客戶端和Web服務(wù)器的交互過(guò)程,Web服務(wù)器接收客戶端的請(qǐng)求后,由Web應(yīng)用服務(wù)器對(duì)瀏覽器的請(qǐng)求進(jìn)行處理,將生成...

    caikeal 評(píng)論0 收藏0
  • Lunar, 一個(gè)Python網(wǎng)絡(luò)框架的實(shí)現(xiàn)

    摘要:核心的幾個(gè)組件模板引擎,框架,請(qǐng)求和應(yīng)答的處理還是有一些難度,但是經(jīng)過(guò)一步步的分析和編碼還是能夠完成功能。模板引擎模板引擎是另外一個(gè)比較大和的模塊。 前前后后,大概兩個(gè)月的時(shí)間,lunar這個(gè)項(xiàng)目終于達(dá)到了一個(gè)很高的完整度。 Lunar是一個(gè)Python語(yǔ)言的網(wǎng)絡(luò)框架,類(lèi)似于Django,F(xiàn)lask,Tornado等當(dāng)下流行的web framework。最初有這個(gè)想法是在大二下學(xué)期,...

    邱勇 評(píng)論0 收藏0
  • flask文檔學(xué)習(xí)筆記1-快速入門(mén)

    摘要:示例如下靜態(tài)路由使用動(dòng)態(tài)變量的路由未指定變量類(lèi)型使用動(dòng)態(tài)變量的路由指定變量類(lèi)型指定的路由變量,可以作為被裝飾的函數(shù)參數(shù)傳入進(jìn)來(lái)。 開(kāi)始決定認(rèn)真的在網(wǎng)上寫(xiě)一些東西,主要原因還是在于希望能提升學(xué)習(xí)效果。雖說(shuō)python寫(xiě)了有幾年,但是web后端框架的確沒(méi)怎么接觸過(guò),買(mǎi)了本狗書(shū)寥寥草草的過(guò)了一遍,發(fā)現(xiàn)很多東西還是理解不深,真的是好記性不如爛筆頭,知識(shí)也要從基礎(chǔ)開(kāi)始,退回來(lái)好好看看官方文檔,再...

    lingdududu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<