1. 程式人生 > >設計模式之模板方法模式(一)

設計模式之模板方法模式(一)

學習了前面的朋友都知道,目前為止,我們的議題都是繞著封裝轉;我們已經封裝了物件建立、方法呼叫、複雜介面、鴨子、比薩...那接下來呢?

我們將要深入封裝演算法塊、好讓子類可以在任何時候都可以將自己掛接進運算裡。我們甚至會在這裡學到一個受好萊塢影響而啟發的設計原則。

喝點咖啡或茶飲

有些人喜歡喝咖啡,沒有咖啡感覺生活索然無趣;有些人喜歡喝茶。那麼,同樣是茶飲,兩者有沒有什麼共同或者是啥的?其實,兩者的沖泡方式非常相似。比如

  1. 咖啡沖泡法
  • (1)把水煮沸
  • (2)用沸水沖泡咖啡
  • (3)把咖啡倒進杯子
  • (4)加糖和牛奶
  1. 茶飲沖泡法
  • (1)把水煮沸
  • (2)用沸水浸泡茶葉
  • (3)把茶倒進杯子
  • (4)加檸檬

轉換成咖啡和茶的程式碼如下:

public class Coffee {
    void prepareRecipe() {
        boilWater();
        brewCoffeeGrinds();
        pourInCup();
        addSugarAndMilk();
    }

    public void boilWater() {
        System.out.println("Boling water");
    }

    public void brewCoffeeGrinds() {
        System.out.println("Dripping Coffee through filter");
    }

    public void pourInCup() {
        System.out.print("Pouring into cup");
    }

    public void addSugarAndMilk() {
        System.out.println("Adding Sugar and Milk");
    }
}

public class Tea {
    void prepareRecipe() {
        boilWater();
        steepTeaBag();
        pourInCup();
        addLemon();
    }

    public void boilWater() {
        System.out.println("Boiling water");
    }

    public void steepTeaBag() {
        System.out.println("Steeping the tea");
    }

    public void addLemon() {
        System.out.println("Adding Lemon");
    }

    public void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

茶類也是類似的,所以就會出現程式碼又相通的地方,給我們的提示就是,第一版的設計類圖可以是如下的方式:

更進一步的設計

所以,查看了以上的程式碼和類圖,咖啡和茶還有什麼其他的共同點呢?讓我們先從沖泡法下手。

  1. 把水煮沸
  2. 用熱水泡咖啡或茶
  3. 把飲料倒進杯子
  4. 在飲料內加入適當的調料

可以看到,1和4已經被抽出來,放到了基類中。2和3並沒有抽出來,但它們本質還是一樣的,只是應用在不同的飲料上罷了。

那麼,我們有辦法將prepareRecipe()也抽象化嗎?是的,我們可以哦。

抽象prepareRecipe()

  1. 我們所遇到的第一個問題,就是咖啡使用brewCoffeeGrinds()和addSuagrAndMilk()方法,而茶使用steepTeaBag()和addLemon().

我們發現,steep和brew都是泡的動作;addSugarAndMilk和addLemon都是加調料,所以分別把他們統一成brew()和addCondiments()進行

  1. 現在我們有了新的prepareRecipe()方法,但是需要讓它能夠符合程式碼。要想這麼做,我們先從CaffeineBeveage(咖啡因飲料)超類開始
public abstract  class CaffeineBeverage {
    final void prepareRecipe() {

    }

    abstract  void brew();

    abstract  void addCondiments();

    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}
  1. 最後我們需要處理咖啡和茶類了。這兩個類現在都依賴超類(咖啡因飲料)來處理沖泡法,所以只需要自行處理沖泡和新增調料部分即可:
public class Tea extends CaffeineBeverage {
    public void brew() {
        System.out.println("Steeping the tea");
    }
    public void addCondiments() {
        System.out.println("Adding Lemon");
    }
}

public class Coffee extends CaffeineBeverage {
    public void brew() {
        System.out.println("Dripping Coffee through filter");
    }
    public void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}

那麼我們在這個過程中做了什麼呢?小編用書中給出的形象化的圖給大家解釋下:

認識模板方法

其實,我們在這個過程中已經使用了我們要學習的模板方法,prepareRecipe()就是我們的模板方法。為什麼呢?

  • 畢竟它是一個方法
  • 它用作一個演算法的模板,在這個例子中,演算法是用來製作咖啡和茶飲的

模板方法定義了一個演算法的步驟,並允許子類為一個或多個步驟提供實現。

讓我們泡茶喝吧

讓我們逐步地泡茶、追蹤這個模板方法是如何工作的。你會得知在演算法內的某些方法,該模板方法控制了演算法。它讓子類能夠提供某些步驟的實現

  1. 首先我們需要一個茶物件
Tea myTea = new Tea();
  1. 然後我們呼叫這個模板方法
myTea.prepareRecipe();
  1. 把水煮沸
boilWater();

這件事情是在超類中進行的
  1. 接下來我們需要泡茶,這件事情只有子類才能知道要怎麼做
brew();
  1. 現在把茶倒進杯子中;所有的飲料做法都一樣,所以這件事情發生在超類中
pourInCup();
  1. 最後,我們加進調料,由於調料是各個飲料獨有的,所以 由子類來實現它
addCondiments();

經過上述的流程,我們就初步模板方法模式給學會了。在今天的篇尾,我們定義下這個模板方法模式:
模板方法模式:在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。

這個模式是有從來建立一個演算法的模組。什麼是模組?如你所見,模板就是一個方法。更具體地說,這個方法將演算法定義成一組步驟,其中的任何步驟都可以是抽象的,由子類負責實現。這可以確保演算法的結構保持不變,同時由子類提供部分實現。

好啦,今天的學習就先到這裡。今天只是初步學習了模板方法模式,接下來還會有更有料的方式,下次不見不散。

愛生活,愛學習,愛感悟,愛挨踢

相關推薦

設計模式模板方法模式

學習了前面的朋友都知道,目前為止,我們的議題都是繞著封裝轉;我們已經封裝了物件建立、方法呼叫、複雜介面、鴨子、比薩...那接下來呢? 我們將要深入封裝演算法塊、好讓子類可以在任何時候都可以將自己掛接進運算裡。我們甚至會在這裡學到一個受好萊塢影響而啟發的設計原則。 喝點咖啡或茶飲 有些人喜歡喝咖啡,沒有咖啡感覺

GOF23設計模式模板方法模式template method

評分 end 抽象方法 abs 方法調用 轉移 pri spa 應用 一、模板方法模式概述   模板方法模式是編程中經常使用的模式。它定義了一種操作中的算法架構,將某些步驟延遲到子類中實現。這樣,新的子類可以在不改變一個算法結構的前提下重新定義該算法的某些特定步驟。   (

設計模式模板方法模式TemplateMethod

pla AR 應用 blog public ood 操作 () eal 模板方法模式使用繼承來實現模式的功能,在基類使用一個方法來定義算法的各個步驟,這些步驟(方法)的具體實現會放到子類中,通過這樣來實現不同算法對象的算法拼合,完成該對象整體算法的實現。 作用 模板方法

Java設計模式模板方法模式Template Method

本文繼續介紹23種設計模式系列之模板方法模式。概述模板方法模式是類的行為模式。準備一個抽象類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。這就是模板方法

淺談java 23種設計模式模板方法模式Template

模板方法模式:模板方法模式是類的行為模式的一種,符合開閉原則(對擴充套件開放,對修改關閉)。父類提取子類公共方法,並提供若干抽象方法供子類實現,以減少子類中的重複程式碼,並提高可複用性。示例:1.建立一個父類bird,每天只有吃和睡才能生活,但是必須要先進行吃,然後再進行睡:

設計模式模板方法模式Template

           模板方法模式定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。 何時應用: 1、需要一次性實現演算法的不變部分,並

Head First設計模式模板方法模式

names 去除 缺點 ide 個數 write ima 父類 public 一、定義 在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中,使得子類可以不改變算法結構的情況下,重定義該算法中的某些特定步驟。 比較通俗的說法,子類決定如何實現算法中的某些步驟,比如兩

java設計模式模板方法模式

java 設計模式宋丹丹姐的一個小品,說把大象放入冰箱分為幾步驟,三步、第一步:把冰箱門打開,第二步:把大象裝進去,第三步:把冰箱門關上。就是這樣的一個小品,可以說是其實簡化的一個模板方法。把雞蛋裝進冰箱分為幾步,同樣也是這個道理。模板方法模式概念:把一些共同的行為抽象出來,作為父類公共使用,一些具體的步驟

23種設計模式模板方法模式

技術分享 cnblogs ati strac void package com rim div 模板方法模式(TemplateMethod):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

設計模式模板方法模式

nbsp outline 依次 print 繪畫 false 鉤子方法 註意 div (文章的部分內容參考了《設計模式之禪》一書,大家也可以讀讀看,內容寫的非常好) 什麽是模板方法模式 它的定義如下: 定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變

設計模式的藝術 行為型模式模板方法模式

前言 生活中有許多事情可以理解成分步驟執行的東西,比如請客吃飯,無論吃什麼,一般都包含著點單,吃東西,買單幾個步驟,不論吃麵還是吃大餐,其他步驟不會變,最多變變點單,在軟體開發中,也會有類似的情況出現,我們可以有個點單的基類,然後子類裡面具體實現是吃麵還是點大餐,這就是模板方法模式,這種模式利用

JAVA設計模式模板方法模式和建造者模式

一、前期回顧 上一篇《Java 設計模式之工廠方法模式與抽象工廠模式》介紹了三種工廠模式,分別是工廠方法模式,簡單工廠方法模式,抽象工廠模式,文中詳細根據實際場景介紹了三種模式的定義,實踐,最後總結了三種方式的區別,以及各個模式的適用場景。這一篇博文我們來學習下模板方法模式和建造者模式。

每天學點設計模式---模板方法模式

模板方法模式的定義理解: 模板方法:父類中定義好演算法的的完整執行框架,子類根據自身需求實現具體的演算法步驟; 比如珍珠奶茶的製作流程,可以總結出一套固定的執行流程, 1.先準備一杯清水河一個塑料杯子 2.在準備好的塑料杯中新增珍珠奶茶需要的原

Android原始碼設計模式模板方法模式

在面向物件開發中,通常會遇到這樣一個問題,我們知道一個演算法所需的關鍵步驟,並確定了這些步驟的執行順序,但是某些步驟的具體實現是未知的,或者說某些步驟的實現是會隨著環境的變化而改變的,例如,執行程式的流程大致如下: 1.檢查程式碼的正確性; 2.連結相關的類庫; 3.編譯相關的程式碼;

設計模式模板方法模式(行為型)

目錄 一、模式定義 二、模式角色 三、模式分析 四、具體例子 五、模式應用場景 一、模式定義 模板方法模式就是在一個抽象類中定義一些骨架方法,然後通過類繼承的方法,將一些方法延遲到繼承類裡。模板方法模式是一種類行為型模式,是一種比較常用的方法。不屬於物件行為型模式,因為只是通過

設計模式-模板方法模式

角色 抽象類(AbstractClass):實現了模板方法,定義了演算法的骨架。 具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的演算法 舉個例子,以準備去學校所要做的工作(prepareGotoSchool)為例,假設需要分三

面向物件設計模式---模板方法模式(Template Method Pattern)

這幾天遇到了一些事,生活中有太多的不確定性,我所能做的就是做最好的自己。爭取能把這本《大話設計模式》的讀書筆記做完吧,說真的雖然現在只是Cover到知識點,還並沒有實戰,不過我想這就是一種積累。就像之前剛閱讀完的《深入淺出MySQL》高階部分一樣,雖然蠻多還是看不懂,畢竟我不是專

設計模式模板方法模式、策略模式、命令設計模式

一、模板方法模式 模板方法模式需要開發抽象類和具體子類的設計師之間的協作。一個設計師負責給出一個演算法的輪廓和骨架,另一些設計師則負責給出這個演算法的各個邏輯步驟。代表這些具體邏輯步驟的方法稱做基本方法(primitive method);而將這些基本方法彙總起來的方法叫做

行為型模式模板方法模式java版

1.引入 模板方法模式就是當我們需要把某些細節層次,但器個別步驟的更詳細的實現卻是不同的時候,就需要用模板方法模式。實際上就是把一些更詳細的資訊在子類中去實現,這裡更詳細的資訊就是可變的資訊,因為每個

設計模式模板方法模式(Template Method)

            本來打算按照書上的講的設計模式一個一個學下來,但是讀spring原始碼的時候遇到模板方法模式,不懂,就提前先學一下。 模板方法模式就是定義一個演算法執行的骨架,而具體的演算法被延遲到子類中去實現,在spring中很多地方都使用到了模板方法模式,比如s