Design Patterns - Template Method

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

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

适用场景

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

UML 图

在这里插入图片描述

效果

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

实现

几个问题:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值