简介
模板方法模式是比较简单的一个设计模式。基本思想就是在将固定的流程或者逻辑 按照可能产生的变化抽象成一个方法,变化的部分放到派生类中去实现。就是在父类或抽象类中定义处理流程的框架,在子类中实现具体处理!
比如说,现在有多个server端提供服务,服务种类各不一致,但都是业务中必须用到的,我们就需要实现一个client去连接server,在每个server的连接过程中,使用的协议是一致的、操作流程也一样:
- 准备工作
- 连接server
- 处理业务
- 断开连接
- 清理工作
但是连接到不同的server 需要做的准备工作等每个个项工作内容可能都不一样,这种情况下,就可以将上面的流程抽象成一个方法connect(), 个项工作封装成ready_work(), connect_to_server(), process_work(), disconnect_to_server(), clear_work()等几个方法。并在client子类中分别进行实现。
此时的connect方法就称为模板方法;这种模式就是模板方法模式。
代码实现
本次示例是对输出内容进行不同展示的类
模板方法为display
具体处理封装为open print close三个方法
两种展示方式:
- 字符展示,以<<>>括起来
- 字符串展示,首尾行以 ±—+填充,内容行首尾以|填充
类
Class Name | Desc |
---|---|
AbstractDisplay | 实现display方法的抽象类 |
CharDisplay | 实现了具体处理的子类 |
StringDisplay | 实现具体处理的子类 |
TemplateMethodClient | 测试的client类 |
UML 类图
AbstractDisplay
"""
@Time: 2023/3/26 20:43
@Auth: CivilDog
@File: AbstractDisplay.py
@IDE: PyCharm
@Motto: Nothing is impossible
"""
import abc
class AbstractDisplay(metaclass=abc.ABCMeta):
@abc.abstractmethod
def open(self):
pass
@abc.abstractmethod
def print(self):
pass
@abc.abstractmethod
def close(self):
pass
def display(self):
self.open()
for i in range(0, 5):
self.print()
self.close()
CharDisplay
"""
@Time: 2023/3/26 20:46
@Auth: CivilDog
@File: CharDisplay.py
@IDE: PyCharm
@Motto: Nothing is impossible
"""
from DesignMode.TemplateMethodMode.AbstractDisplay import AbstractDisplay
class CharDisplay(AbstractDisplay):
def __init__(self, ch):
self.__ch = ch
def open(self):
print("<<", end="")
def print(self):
print(self.__ch, end="")
def close(self):
print(">>")
StringDisplay
"""
@Time: 2023/3/26 20:50
@Auth: CivilDog
@File: StringDisplay.py
@IDE: PyCharm
@Motto: Nothing is impossible
"""
from DesignMode.TemplateMethodMode.AbstractDisplay import AbstractDisplay
class StringDisplay(AbstractDisplay):
def __init__(self, string):
self.__string = string
def open(self):
self.print_line()
def print(self):
print("|" + self.__string + "|")
def close(self):
self.print_line()
def print_line(self):
print("+", end="")
for i in range(len(self.__string)):
print("-", end="")
print("+")
TemplateMethodClient
"""
@Time: 2023/3/26 20:54
@Auth: CivilDog
@File: TemplateMethodClient.py
@IDE: PyCharm
@Motto: Nothing is impossible
"""
from DesignMode.TemplateMethodMode.CharDisplay import CharDisplay
from DesignMode.TemplateMethodMode.StringDisplay import StringDisplay
class TemplateMethodClient(object):
@staticmethod
def run(*args, **kwargs):
char_display = CharDisplay("H")
str_display = StringDisplay("Hello World!")
char_display.display()
str_display.display()
if __name__ == '__main__':
TemplateMethodClient.run()
输出
<<HHHHH>>
+------------+
|Hello World!|
|Hello World!|
|Hello World!|
|Hello World!|
|Hello World!|
+------------+
Process finished with exit code 0
总结
模板方法模式中只有两个角色:抽象类和具体类,将统一的流程放到抽象类中独立成一个方法。这种模式可以使得逻辑处理通用化,如果再像对输出内容进行其他样式的展示,那么只需要继承AbstractDisplay,并实现open print close方法然后再调用display展示即可。
而且一旦流程变更,只需要修改模板方法即可。但是流程发生新增步骤,就需要在每个子类中去添加。
《图解设计模式》