11

Python 设计模式——模板方法模式

 3 years ago
source link: https://rollingstarky.github.io/2020/12/29/python-design-patterns-template-pattern/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python 设计模式——模板方法模式

发表于 2020-12-29

| 分类于 Python

| 0

| 阅读次数: 1

字数统计: 3.7k

|

阅读时长 ≈ 0:04

行为模式主要关注对象的响应性,处理对象之间的交互以实现更强大的功能。模板方法模式即为一种行为设计模式。
比如可以将制作饮料的步骤定义为模板方法中的算法,子类就能使用模板方法来实现沏茶的步骤。且步骤的改变(即子类的具体实现)并不会影响原始算法的结构。这样模板方法模式中的子类就可以通过覆盖来创建不同的行为。

模板方法模式适用于以下场景:

  • 当多个算法或类实现类似或相同逻辑的时候
  • 在子类中实现算法有助于减少重复代码的时候
  • 子类可以通过覆盖实现多种不同行为的时候

模板方法模式的主要意图:

  • 使用基本操作定义算法的框架
  • 重新定义子类的某些操作,无需修改算法的结构
  • 实现代码重用并避免重复工作
  • 利用通用接口或功能实现

UML

  • 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 接口的具体实现

模板方法的优点和缺点

  • 没有代码重复
  • 使用继承而不是合成,只有为数不多的几个方法需要重写
  • 灵活性,允许子类决定如何实现算法中的步骤
  • 调试和理解模板方法模式中的流程序列时可能会令人困惑
  • 模板框架的维护可能是一个问题,任何层次(底层或高层)的变更都可能对实现造成干扰

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK