1. 程式人生 > >面向物件設計模式之---模板方法模式(Template Method Pattern)

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

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

今天要介紹的設計模式叫做模板方法模式。說到模板,很多高階的程式語言都有,比如C++有函式模板、類模板;Java有泛型等等。這些模板的作用就是最大化地提高程式碼的利用率,減少重複寫同樣的東西,這就應驗了程式設計界的那句Don’t repeat by yourself!

對於這個模板方法模式應用場景,我就用書上的例子吧,真的太形象了!比如考場考試,每一位同學都有一份一模一樣的卷子,假設只有選擇題,但是每個同學所做的回答卻不一樣。如果要把這個場景用程式設計來還原的話,我想最初的思路會是這樣的。

import java.util.*;

//同學1回答問題
class Student1
{
  public void answer()
  {
    System.out.println("Q1:What's your favourite star?\nA1:Jessie J");
    System.out.println("Q2:Where are you come from?\nA1:China"
); System.out.println("Q3:What's your name?\nA1:Jack"); } } //同學2回答問題 class Student2 { public void answer() { System.out.println("Q1:What's your favourite star?\nA2:Angela Zhang"); System.out.println("Q2:Where are you come from?\nA2:China"); System.out.println("Q3:What's your name?\nA2:Martin"
); } } public class Main { public static void main(String[] args) { Student1 stu1 = new Student1(); System.out.println("這是同學1的作答:"); stu1.answer(); Student2 stu2 = new Student2(); System.out.println("這是同學2的作答"); stu2.answer(); } }

這裡有兩個同學,他們分別回答了3個問題,可以發現,重複的程式碼 實在是太多了。這時我們可以考慮將它們共同的部分(卷子上的題目)進行抽象,變成一個父類,學生繼承它回答題目就好了。比如我們可以這樣修改程式碼:

import java.util.*;
//抽象類
abstract class Paper
{
  //這個是模板方法,即方法骨架
  public void answer()
  {
    System.out.println("Q1:What's your favourite star?\n"+"A1:"+reply1());
    System.out.println("Q2:Where are you come from?\n"+"A2:"+reply2());
    System.out.println("Q3:What's your name?\n"+"A3:"+reply3());
  }
  //方法實現中的某一些細節,因子類不同而不同
  protected abstract String reply1();
  protected abstract String reply2();
  protected abstract String reply3();
}

//同學1回答問題 父類抽象方法具體實現
class Student1 extends Paper
{
    protected String reply1()
   {
        return "Jessie J";
   }

   protected String reply2()
   {
        return "China";
   }

   protected String reply3()
   {
        return "Jack";
   }
}

//同學2回答問題 父類抽象方法具體實現
class Student2 extends Paper
{
    protected String reply1()
   {
        return "Angela Zhang";
   }

   protected String reply2()
   {
        return "China";
   }

   protected String reply3()
   {
        return "Martin";
   }
}

public class Main
{
  public static void main(String[] args)
  {
    //繼承、重寫、父類引用指向子類物件 =》 多型
    Paper p1 = new Student1();
    System.out.println("這是同學1的作答:");
    p1.answer();
    Paper p2 = new Student2();
    System.out.println("這是同學2的作答");
    p2.answer();
  }
}

從以上程式碼我們不難發現,在父類抽象的時候,把每個問題回答的具體過程變成了一個個返回字串型別抽象方法,具體方法由子類去實現。這個就叫做模板方法模式

模板方法模式,定義一個操作中的演算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重新定義該演算法的某些特定步驟。

所以,模板方法模式的核心就是在基類中定義好方法的骨架,讓子類在這個骨架下參與方法的某一部分具體實現。

模板方法模式的UML類圖如下:

  • 另:以上兩個程式的最後執行效果是一致的,如下:
    這是同學1的作答:
    Q1:What's your favourite star?
    A1:Jessie J
    Q2:Where are you come from?
    A2:China
    Q3:What's your name?
    A3:Jack
    這是同學2的作答
    Q1:What's your favourite star?
    A1:Angela Zhang
    Q2:Where are you come from?
    A2:China
    Q3:What's your name?
    A3:Martin