热门问题
时间线
聊天
视角

模板方法模式

来自维基百科,自由的百科全书

模板方法模式
Remove ads

模板方法,是一種行為型軟件設計模式。這種設計模式是一種控制反轉的實現方式。因為高層代碼不再確定(控制)算法的處理流程。

Thumb
模板方法模式:UML類圖

模板方法是一個定義在父類別的方法,負責處理流程、算法的不變部分。模板方法會調用多個定義在父類別的其他工具方法,而這些方法是算法的可變部分,有可能只是抽象方法並沒有實作。模板方法僅決定這些抽象方法的執行順序,這些抽象方法由子類別負責實作,並且子類別不允許覆蓋模板方法(即不能重寫處理流程)。

用法

模板方法模式多用在:

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

結構

Thumb
模板模式的樣例UML類圖[1]

在上面的UML類圖中,AbstractClass定義一個模板方法templateMethod()運算,它定義了行為的骨幹即模板:

  • 實現行為的不變部份。
  • 向自身發送消息primitive1()primitive2(),由於它們實現於SubClass1,這允許了子類提供這個算法的這些部份的可變實現。

用例

C++

下面是C++的例子:

Thumb
#include <iostream>
#include <memory>

class View { // AbstractClass
public:
    // defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
    virtual void doDisplay() {}
    // 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;
private:
    void setFocus() {
        std::cout << "View::setFocus\n";
    }
    void resetFocus() {
        std::cout << "View::resetFocus\n";
    }
};

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

int main() {
    // The smart pointers prevent memory leaks
    std::unique_ptr<View> myview = std::make_unique<MyView>();
    myview->display();
}

這個程序的輸出為:

View::setFocus
MyView::doDisplay
View::resetFocus
Remove ads

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
Remove ads

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
     }
 }
Remove ads

引用

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads