行为模式主要关注对象的响应性,处理对象之间的交互以实现更强大的功能。模板方法模式即为一种行为设计模式。
比如可以将制作饮料的步骤定义为模板方法中的算法,子类就能使用模板方法来实现沏茶的步骤。且步骤的改变(即子类的具体实现)并不会影响原始算法的结构。这样模板方法模式中的子类就可以通过覆盖来创建不同的行为。
模板方法模式适用于以下场景:
- 当多个算法或类实现类似或相同逻辑的时候
- 在子类中实现算法有助于减少重复代码的时候
- 子类可以通过覆盖实现多种不同行为的时候
模板方法模式的主要意图:
- 使用基本操作定义算法的框架
- 重新定义子类的某些操作,无需修改算法的结构
- 实现代码重用并避免重复工作
- 利用通用接口或功能实现
- AbstractClass:在抽象方法的帮助下定义算法的操作或步骤。这些步骤将被具体的子类覆盖
- template_method():定义算法的框架。在模板方法中调用抽象方法定义的步骤以形成序列或算法
- ConcreteClass:实现需要算法子类关注的特定步骤
from abc import ABCMeta, abstractmethod
class Compiler(metaclass=ABCMeta):
@abstractmethod
def collectSource(self):
pass
@abstractmethod
def compileToObject(self):
pass
@abstractmethod
def run(self):
pass
def compileAndRun(self):
self.collectSource()
self.compileToObject()
self.run()
class iOSCompiler(Compiler):
def collectSource(self):
print("Collecting Swift Source Code")
def compileToObject(self):
print("Compiling Swift code to LLVM bitcode")
def run(self):
print("Program runing on runtime environment")
iOS = iOSCompiler()
iOS.compileAndRun()
# => Collecting Swift Source Code
# => Compiling Swift code to LLVM bitcode
# => Program runing on runtime environment
现实中的模板方法模式
from abc import abstractmethod, ABCMeta
class Trip(metaclass=ABCMeta):
@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
def itinerary(self):
self.setTransport()
self.day1()
self.day2()
self.day3()
self.returnHome()
class VeniceTrip(Trip):
def setTransport(self):
print("Take a boat and find your way in the Grand Canal")
def day1(self):
print("Visit St Mark's Basilica in St Mark's Square")
def day2(self):
print("Appreciate Doge's Palace")
def day3(self):
print("Enjoy the food near the Rialto Bridge")
def returnHome(self):
print("Get souovenirs for friends and get back")
class 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("Don't feel like leaving the beach..")
class TravelAgency:
def arrange_trip(self):
choice = input("What kind of place you'd 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()
# => What kind of place you'd like to go historical or to a beach? beach
# => On foot, on any island, Wow!
# => Enjoy the marine life of Banana Reef
# => Go for the water sports and snorkelling
# => Relax on the beach and enjoy the sun
# => Don't feel like leaving the beach..
- 抽象类 Trip 是一个接口,定义了不同日子使用的交通方式和参观地点等细节
- setTransport 是一个抽象方法,由 ConcreteClass 实现,作用是设置交通方式
- day1()、day2()、day3() 抽象方法定义了特定日期所参观的地点
- itinerary() 模板方法则用于创建完整的行程
- VeniceTrip 类和 MaldivesTrip 类是 Trip 接口的具体实现
模板方法的优点和缺点
优点:
- 没有代码重复
- 使用继承而不是合成,只有为数不多的几个方法需要重写
- 灵活性,允许子类决定如何实现算法中的步骤
缺点:
- 调试和理解模板方法模式中的流程序列时可能会令人困惑
- 模板框架的维护可能是一个问题,任何层次(底层或高层)的变更都可能对实现造成干扰
网友评论