模板方法(英語:template method),是一種行为型软件设计模式。这种设计模式是一种控制反转的实现方式。因为高层代码不再确定(控制)算法的处理流程。

模板方法模式:UML類圖

概述

编辑

模板方法是一個定義在父類別的方法,负责处理流程、算法的不变部分。模板方法會调用多個定義在父類別的其他工具方法,而這些方法是算法的可变部分,有可能只是抽象方法並沒有實作,或者是只有空体的钩子方法。模板方法僅決定這些抽象方法的執行順序,這些抽象方法由子類別負責實作,並且子類別不允許覆盖模板方法(即不能重写处理流程)。

模板方法模式多用在:某些類別的演算法中,實做了相同的方法,造成程式碼的重複;控制子類別必須遵守的一些事項。

结构

编辑
 
模板模式的样例UML类图[1]

在上面的UML类图中,AbstractClass定义一个模板方法templateMethod()运算,它定义了行为的骨干即模板:

  • 实现行为的不变部份。
  • 向自身发送消息primitive1()primitive2(),由于它们实现于SubClass1,这允许了子类提供这个算法的这些部份的可变实现。

用例

编辑

C++

编辑

下面是基于《设计模式》书中前C++98实现的C++23实现例子:

 
import std;

using std::unique_ptr;

// abstract class
class View {
private:
    void setFocus() {
        std::println("View::setFocus called");
    }

    void resetFocus() {
        std::println("View::resetFocus called");
    }
public:
    // defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
    virtual void doDisplay() = 0;

    // implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.
    void display() {
        setFocus();
        doDisplay();
        resetFocus();
    }

    virtual ~View() = default;
};

// concrete class
class MyView : public View {
public:
    // implements the primitive operations to carry out subclass-specific steps of the algorithm.
    void doDisplay() override {
        // render the view's contents
        std::println("MyView::doDisplay called");
    }
};

int main(int argc, char* argv[]) {
    unique_ptr<View> myview = std::make_unique<MyView>();
    myview->display();
}

这个程序的输出为:

View::setFocus called
MyView::doDisplay called
View::resetFocus called

Python

编辑

下面是Python的例子:

from abc import ABC, abstractmethod

class View(ABC):
    @abstractmethod
    def do_display(self): pass
    def display(self):
        self.__set_focus()
        self.do_display()
        self.__reset_focus()
    def __set_focus(self):
        print("View: set focus")
    def __reset_focus(self):
        print("View: reset focus")

class MyView(View):
    def do_display(self):
        print("View: do display")

其执行:

>>> view = MyView()
>>> view.display()
View: set focus
View: do display
View: reset focus

Java

编辑

下面是Java的例子:

 /**
  * An abstract class that is common to several games in
  * which players play against the others, but only one is
  * playing at a given time.
  */
 abstract class Game {
     private int playersCount;
     abstract void initializeGame();
     abstract void makePlay(int player);
     abstract boolean endOfGame();
     abstract void printWinner();
 
     /* A template method : */
     final void playOneGame(int playersCount) {
         this.playersCount = playersCount;
         initializeGame();
         int j = 0;
         while (!endOfGame()){
             makePlay(j);
             j = (j + 1) % playersCount;
         }
         printWinner();
     }
 }

//Now we can extend this class in order to implement actual games:
 class Chess extends Game {
     /* Implementation of necessary concrete methods */
     void initializeGame() {
         // ...
     }
 
     void makePlay(int player) {
         // ...
     }
 
     boolean endOfGame() {
         // ...
     }
 
     void printWinner() {
         // ...
     }
  
     /* Specific declarations for the chess game. */
     // ...
 }

 public class Player {
     public static void main(String[] args) {
         Game chessGame = new Chess();
         chessGame.initializeGame();
         chessGame.playOneGame(1); //call template method
     }
 }

引用

编辑
  1. ^ The Template Method design pattern - Structure. w3sDesign.com. [2017-08-12]. 

📚 Artikel Terkait di Wikipedia

设计模式:可复用面向对象软件的基础

pattern) 观察者(Observer pattern) 状态(State pattern) 策略(Strategy pattern) 模板方法(Template method pattern) 访问者(Visitor pattern) Gang Of Four (页面存档备份,存于互联网档案馆), Content

模板元編程

定,無需變動的多型行為。那麼一來,奇怪的遞迴模板樣式(Curiously Recurring Template Pattern;CRTP)便可被用來達成靜態多型。如下例: template <class Derived> struct base { void interface() { // ...

惰性初始化

惰性初始化技術:使用惰性初始化,實例化物件於其第一次被要求之時。 在軟件設計實踐中經常還會結合上第三個構想: 多例模式(英语:Multiton pattern):將實例存儲在一個映射中,在以“相同”的參數要求一個實例之時,返回“同一個”單例,有人將這種參數化或為單例註冊類型名字的“惰性工廠”稱為惰性初始化模式。

函数对象

(页面存档备份,存于互联网档案馆) Description from the Portland Pattern Repository(页面存档备份,存于互联网档案馆) C++ Advanced Design Issues - Asynchronous C++ (页面存档备份,存于互联网档案馆) by

Python

(原始内容存档于2023-03-21).  Why must 'self' be used explicitly in method definitions and calls?. Design and History FAQ. Python Software Foundation. [2012-02-19]