模板方法模式

定义

用一种通用的框架和步骤定义算法,但是具体每一步骤的实现由子类来完成。

用途

对模板继承可以重用代码,只需要重写需要改变的方法,灵活性高。

例如:旅行社旅游方案。对于不同的景点,内容可能会不一样,但是其流程和“套路”都是一样的(讲解,参观,自由参观,集和,吃饭)。
这个流程和套路就是一种模板方法。

缺点

模板的变动会对其所有的子类造成干扰,维护会变得非常困难。

示例:

1. 模板方法模式

模拟旅行社旅游方案。TripTemplate提供了旅行方案(模板),包括交通方式、解说、自由活动、吃饭、返回等方法。
其具体内容由其子类TheGreatWallTripTheImperialPalaceTrip来实现。

>>> from abc import abstractmethod, ABCMeta
>>> class TripTemplate(metaclass=ABCMeta):
        @abstractmethod
        def setTransport(self):
            pass
            
        @abstractmethod  
        def explain(self):
            pass
           
        @abstractmethod
        def freetime(self):
            pass
        
        @abstractmethod
        def dining(self):
            pass
               
        @abstractmethod
        def returnHome(self):
            pass
            
        def setOut(self):
            self.setTransport()
            self.explain()
            self.freetime()
            self.dining()
            self.returnHome()
            
>>> class TheGreatWallTrip(TripTemplate):
        def setTransport(self):
            print("乘坐缆车")
            
        def explain(self):
            print("八达岭长城,位于北京市延庆区军都山关沟古道北口。是中国古代伟大的防御工程万里长城的重要组成部分,是明长城的一个隘口......")
           
        def freetime(self):
            print("自由活动!买纪念品,买零食......")
        
        def dining(self):
            print("集和吃饭.....")
               
        def returnHome(self):
            print("乘坐大巴返回")   
            
>>> class TheImperialPalaceTrip(TripTemplate):
        def setTransport(self):
            print("乘坐公交车")
            
        def explain(self):
            print("北京故宫是中国明清两代的皇家宫殿,旧称为紫禁城,位于北京中轴线的中心,是中国古代宫廷建筑之精华。北京故宫以三大殿为中心......")
           
        def freetime(self):
            print("自由活动!参观分殿")
        
        def dining(self):
            print("品尝特色小吃.....")
               
        def returnHome(self):
            print("步行返回")     

>>> class Agent(object):
    def arrange(self, choice):
        if choice == "TheGreatWall":
            self.trip = TheGreatWallTrip()
        if choice == "TheImperialPalace":
            self.trip = TheImperialPalaceTrip()
        
        self.trip.setOut()
        
>>> agent = Agent()
>>> agent.arrange("TheImperialPalace")
乘坐公交车
北京故宫是中国明清两代的皇家宫殿,旧称为紫禁城,位于北京中轴线的中心,是中国古代宫廷建筑之精华。北京故宫以三大殿为中心......
自由活动!参观分殿
品尝特色小吃.....
步行返回

子类只需要重写部分方法就可以实现整个流程和步骤。用这种方法生成多种子类时,模板类会被大量的重用,提高效率。