当前位置: 代码迷 >> 综合 >> Design Patterns - Template Method
  详细解决方案

Design Patterns - Template Method

热度:97   发布时间:2023-10-21 04:54:42.0

Template Method(模板方法) — 类行为型模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

适用场景

  1. 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
  2. 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。也就是重分解以一般化。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用新的操作的模板方法来替换不同的代码。

UML 图

Design Patterns - Template Method

效果

  1. 提取了类库中公共的行为。模板方法导致一种反向的控制结构,即父类调用子类的操作,而不是相反。模板方法调用下列类型的操作:
    1. 具体的操作(ConcreteClass 或对客户类的操作)
    2. 具体的 AbstractClass 的操作(即通常对子类有用的操作)
    3. 原语操作(即抽象操作)
    4. 钩子操作,它提供了缺省的行为,子类可以在必要时进行扩展,钩子操作在缺省情况下通常是空操作。

实现

几个问题:

  1. 尽量减少原语操作:定义模板方法的一个重要目的是尽量减少一个子类具体实现该算法时必须重定义的原语操作的数目。需要重定义的操作越多,客户程序就越冗长。
  2. 命名约定:可以给应被重定义的操作的名字加上一个前缀以识别它们。例如,用于 Macintosh 应用的 MacApp 框架给模板方法加上前缀 “Do-”,如“DoCreateDocument”“DoRead”。
import abcclass Cooking(object):"""炒菜基类,实现了几个抽象方法,及炒菜顺序调用方法cook"""__metaclass__ = abc.ABCMeta@abc.abstractmethoddef clean_vegetables(self, *args, **kwargs):"""准备蔬菜:param args: :param kwargs: :return: """pass@abc.abstractmethoddef prepare_accessories(self, *args, **kwargs):"""准备辅料:param args: :param kwargs: :return: """pass@abc.abstractmethoddef stir_fry(self, *args, **kwargs):"""炒菜:param args: :param kwargs: :return: """pass@abc.abstractmethoddef put_flavoring(self, *args, **kwargsl):"""放入调味料:param args: :param kwargsl: :return: """pass@abc.abstractmethoddef end_pot(self, *args, **kwargs):"""出锅:param args: :param kwargs: :return: """passdef cook(self):"""炒菜顺序执行方法:return: """self.clean_vegetables().\prepare_accessories().\stir_fry().\put_flavoring().\end_pot()class Dish_a(Cooking):"""(豆腐+白菜)+ (葱+姜)+ (炒5分钟)+(盐+鸡精)+(玻璃容器)"""def __init__(self):self.dish = ""def clean_vegetables(self):self.dish += '白菜+豆腐' + ', 'return selfdef prepare_accessories(self):self.dish += '葱+姜' + ', 'return selfdef stir_fry(self):self.dish += '炒5分钟' + ', 'return selfdef put_flavoring(self):self.dish += '盐+鸡精' + ', 'return selfdef end_pot(self):self.dish += '玻璃容器' + ', 'class Dish_b(Cooking):"""(辣椒+肉) + (葱+八角+姜)+ (炒10分钟) + (盐+十三香+味精) + (陶瓷容器)"""def __init__(self):self.dish = ""def clean_vegetables(self):self.dish += '辣椒+肉' + ', 'return selfdef prepare_accessories(self):self.dish += '葱+八角+姜' + ', 'return selfdef stir_fry(self):self.dish += '炒10分钟' + ', 'return selfdef put_flavoring(self):self.dish += '盐+十三香+味精' + ', 'return selfdef end_pot(self):self.dish += '陶瓷容器' + ', '

client

if __name__ == '__main__':dish_a = Dish_a()dish_b = Dish_b()dish_a.cook()dish_b.cook()print('第一道菜:', dish_a.dish)print('第二道菜:', dish_b.dish)
"""output 第一道菜: 白菜+豆腐, 葱+姜, 炒5分钟, 盐+鸡精, 玻璃容器, 第二道菜: 辣椒+肉, 葱+八角+姜, 炒10分钟, 盐+十三香+味精, 陶瓷容器, """
  相关解决方案