此模式通過一個模板方法來定義程式的框架或演算法,通常模板方法定義在基類中,即原始的模板,然後子類就可以根據不同的需要實現或重寫模板方法中的某些演算法步驟或者框架的某部分,最後達到使用相同模板實現不同功能的效果。 核心思想: 使用一個模板方法定義好總的演算法框架。 子類中根據需要重新定義某些操作,但是不能修 ...
此模式通過一個模板方法來定義程式的框架或演算法,通常模板方法定義在基類中,即原始的模板,然後子類就可以根據不同的需要實現或重寫模板方法中的某些演算法步驟或者框架的某部分,最後達到使用相同模板實現不同功能的效果。
核心思想:
- 使用一個模板方法定義好總的演算法框架。
- 子類中根據需要重新定義某些操作,但是不能修改原始模板方法。
- 在多個演算法或框架具有類似或相同的邏輯的時候,可以使用模板方法模式,以實現代碼重用。
- 當某些操作是強制子類必須實現的時候,此操作就可以定義為抽象方法,如果不是強制要求子類實現的話,則可以在基類中為它定義一個預設實現。
主要角色:
- 介面:通常是抽象基類,定義模板方法中需要的各項操作。
- 模板方法:即模板演算法,定義好各項操作的執行順序或演算法框架。
- 真實對象:子類通過重新實現介面中的各項操作,以便讓模板方法實現不同的功能。
優缺點:
- 優點:因為子類的實現是根據基類中的模板而來的,所以可以實現代碼重用,因為有時候我們需要修改的只是模板方法中的部分操作而已。
- 缺點:此模式的維護有時候可能會很麻煩,因為模板方法是固定的,一旦模板方法本身有修改的時候,就可能對其他的相關實現造成影響。
模板方法運用案例--鉤子
鉤子是在基類中聲明的方法,並且在模板方法中使用它,通常是給它定義好一個預設的實現,鉤子的思想是為子類提供一個按需“鉤取”的能力,因此如果子類不想使用鉤子,則可以忽略鉤子的相關實現。
簡單示例:
from abc import ABCMeta, abstractmethod class Template(metaclass=ABCMeta): """介面:模板類""" @abstractmethod def operation_1(self): pass @abstractmethod def operation_2(self): pass def template_func(self): """模板方法:定義好具體的演算法步驟或框架""" self.operation_1() self.operation_2() class SubObj1(Template): """子類1:按需重新定義模板方法中的演算法操作""" def operation_1(self): print('SubObj1.operation_1()') def operation_2(self): print('SubObj1.operation_2()') class SubObj2(Template): """子類2:按需重新定義模板方法中的演算法操作""" def operation_1(self): print('SubObj2.operation_1()') def operation_2(self): print('SubObj2.operation_2()') if __name__ == '__main__': SubObj1().template_func() SubObj2().template_func()