python设计模式之模板方法

来源:互联网 发布:查询别人淘宝购买记录 编辑:程序博客网 时间:2024/06/05 15:44

一、定义模板方法模式

         1.场景:

                        1.1 当多个算法或类实现类似或相同逻辑的时候。

                        1.2 在子类中实现算法有助于减少重复代码的时候。

                        1.3 可以让子类利用覆盖实现行为来定义多个算法的时候。

         2.目的:

                        2.1 使用基本操作定义算法的框架。

                        2.2 重新定义子类的某些操作,而无需修改算法的结构。

                        2.3 实现代码重用并避免重复工作

                        2.4 利用通用接口或实现

         3.模板方法UML类图


                   3.1 AbstractClass : 在抽象方法的帮助下定义算法的操作或步骤。这些步骤将被具体子类覆盖。

                   3.2 tmplate_method():定义算法的框架。在模板方法中调用抽象方法定义的多个步骤来定义序列或算法本身。

                   3.3 ConcreteClass:实现(由抽象方法定义的)步骤,来执行算法子类的特定步骤。

                   3.4 代码

# -*- coding: UTF-8 -*-from abc import ABCMeta,abstractmethod# 抽象方法 AbstractClassclass AbstractClass():    def __init__(self):        pass    @abstractmethod    def operation1(self):        pass    @abstractmethod    def operation2(self):        pass    #  模板方法 tmplate_method()    def template_method(self):        print ("Defining the Algorithm.Operation1 follows Operation2")        self.operation2()        self.operation1()# 具体类 ConcreteClassclass ConcreteClass(AbstractClass):    def operation1(self):        print ("My Concrete Operation1")    def operation2(self):        print ("Operation 2 remains same")# 客户端class Client:    def mian(self):        self.concreate = ConcreteClass()        self.concreate.template_method()client = Client()client.mian()




二、现实世界中的模板方法模式

        1.案例:旅行社安排出游

# -*- coding: UTF-8 -*-from abc import ABCMeta,abstractmethod# 抽象方法 Tripclass Trip():    def __init__(self):        pass    @abstractmethod    def setTransport(self):        pass    @abstractmethod    def day1(self):        pass    @abstractmethod    def day2(self):        pass    @abstractmethod    def day3(self):        pass    @abstractmethod    def returnHome(self):        pass    #  模板方法 tmplate_method()    def itinerary(self):        self.setTransport()        self.day1()        self.day2()        self.day3()        self.returnHome()# 具体类 VeniceTripclass VeniceTrip(Trip):    def setTransport(self):        print ("Take a boat and find your way in the Grand Canal")    def day1(self):        print ("Visit St Mark Basilica in St Mark Square")    def day2(self):        print ("Enjoy the food near the Rialto Bridge")    def day3(self):        print ("Get souvenirs for friends and get back")    def returnHome(self):        print ("Get souvenirs for friends and get back")# 具体类 MaldivesTripclass MaldivesTrip(Trip):    def setTransport(self):        print ("On foot,on any island,Wow")    def day1(self):        print ("Enjoy the marine life of Banana Reef")    def day2(self):        print ("Go for the water sports and snorkelling")    def day3(self):        print ("Relax on the beach and enjoy the sun")    def returnHome(self):        print ("Dont feel like leaving the beach..")# 客户端class TravelAgency:    def arrange_trip(self):        choice =raw_input("What kind of place you like to go historical or to a beach")        if choice =="historical":            self.trip = VeniceTrip()            self.trip.itinerary()        if choice == "beach":            self.trip = MaldivesTrip()            self.trip.itinerary()TravelAgency().arrange_trip()



三、模板方法模式-钩子

         1.1 钩子是在抽象类中声明的方法,它通常被赋予一个默认实现。

         1.2 通常情况下,当子类必须提供实现时,我们会使用抽象方法,并且当子类的实现不是强制的时候,我们就会使用钩子。


四、好莱坞原则与模板方法

          1.1 好莱坞原则:不要给我们打电话,我们会打给你。好莱坞哲学:如果有合适演员的角色,影棚会给演员打电话。

          1.2 面向对象中的好莱坞原则:允许底层组件使用好莱坞原则将自己挂入系统中,高层组件确定底层系统的使用方式,以及何时需要他们。


五、模板方法模式的优点和缺点

           优点:

                   1.1 代码没有重复

                   1.2 模板方法用的继承而非合成,代码可以重用。

                   1.3 灵活性允许子类决定如何实现算法中的步骤。

         缺点:

                   2.1 调试和理解模板方法中的流程序列有时会令人困惑。

                   2.2 维护难度大


六、常见问题解答

        1.1 是否应该禁止底层组件调用更高层组件中的方法:

                   不,底层组件当然通过继承来调用高层组件。然而,程序员需要注意的是,不要出现循环依赖性,即高层组件和底层组件彼此依赖。

        1.2 策略模式是否类似于模板模式?

                   模板取决于继承,而策略使用组合。模板方法模式是通过子类化在编译时进行算法选择,而策略模式是运行时进行选择。