设计模式实战:模板方法模式(Template Method)

在开发中,你是否写过这样的代码:

python 复制代码
def process():
    step1()
    step2()
    step3()

然后在另一个地方:

python 复制代码
def process_v2():
    step1()
    step2_new()
    step3()

再后来:

python 复制代码
def process_v3():
    step1()
    step2_new()
    step3_new()

你会发现:

  • 整体流程是固定的
  • 只有某些步骤会变化
  • 代码开始出现大量重复

这正是 模板方法模式(Template Method) 要解决的问题。


一、模板方法模式解决什么问题?

一句话:

定义一个算法的骨架,将某些步骤延迟到子类中实现。

关键词:

  • 固定流程
  • 可变步骤
  • 代码复用
  • 控制流程

二、一个典型场景:数据处理流程

假设我们要实现一个"数据处理流程":

步骤如下:

1️⃣ 读取数据

2️⃣ 数据处理

3️⃣ 输出结果

不同场景:

  • CSV 文件处理
  • JSON 数据处理
  • 数据库数据处理

如果直接写:

python 复制代码
def process_csv():
    read_csv()
    handle_csv()
    output()

def process_json():
    read_json()
    handle_json()
    output()

问题:

  • 流程重复
  • 难维护
  • 修改流程需要改多处

三、模板方法模式的核心思想

把"流程骨架"固定在父类中,把"可变步骤"交给子类。

结构:

id="mwv8nu" 复制代码
AbstractClass
     |
ConcreteClass

关键点:

  • 父类定义流程(模板方法)
  • 子类实现具体步骤

四、Python 实现模板方法模式

1️⃣ 定义抽象类

python 复制代码
from abc import ABC, abstractmethod

class DataProcessor(ABC):

    def process(self):
        self.read()
        self.handle()
        self.output()

    @abstractmethod
    def read(self):
        pass

    @abstractmethod
    def handle(self):
        pass

    def output(self):
        print("输出结果")

说明:

  • process() 是模板方法(固定流程)
  • read/handle 是可变步骤
  • output 是默认实现

2️⃣ 具体实现类

python 复制代码
class CSVProcessor(DataProcessor):

    def read(self):
        print("读取 CSV")

    def handle(self):
        print("处理 CSV 数据")
python 复制代码
class JSONProcessor(DataProcessor):

    def read(self):
        print("读取 JSON")

    def handle(self):
        print("处理 JSON 数据")

3️⃣ 使用方式

python 复制代码
processor = CSVProcessor()
processor.process()

输出:

复制代码
读取 CSV
处理 CSV 数据
输出结果

五、模板方法模式的核心价值

模板方法模式本质是:

把流程固定,把变化隔离。

它解决的是:

  • 重复代码
  • 流程一致但实现不同
  • 控制执行顺序

六、钩子方法(Hook)

模板方法中常见一个扩展点 ------ Hook(钩子方法)

python 复制代码
class DataProcessor(ABC):

    def process(self):
        self.read()
        self.handle()

        if self.need_output():
            self.output()

    def need_output(self):
        return True

子类可以选择覆盖:

python 复制代码
class SilentProcessor(DataProcessor):

    def read(self):
        print("读取数据")

    def handle(self):
        print("处理数据")

    def need_output(self):
        return False

作用:

  • 提供可选扩展点
  • 控制流程分支

七、模板方法 vs 策略模式

很多人会混淆。

区别很关键:

对比点 模板方法 策略模式
实现方式 继承 组合
控制流程 父类控制 客户端控制
是否可动态切换

一句话总结:

模板方法是"流程写死,步骤可变",

策略模式是"步骤可替换"。


八、Python 中的"轻量实现"

Python 中有时候不需要严格用抽象类。

也可以用"约定"实现:

python 复制代码
class BaseProcessor:

    def process(self):
        self.read()
        self.handle()
        self.output()

    def output(self):
        print("输出")

子类只要实现:

python 复制代码
class MyProcessor(BaseProcessor):

    def read(self):
        ...

    def handle(self):
        ...

这就是 Python 的灵活性。


九、真实项目中的应用

模板方法模式非常常见:

1️⃣ Web 框架

Django / Flask 请求流程:

id="f8yv54" 复制代码
请求 → 中间件 → 视图 → 响应

流程固定,细节可扩展。


2️⃣ 爬虫框架

id="gsz9p3" 复制代码
请求 → 解析 → 存储

不同网站实现不同解析逻辑。


3️⃣ 数据处理管道

ETL 流程:

id="3d5c6q" 复制代码
Extract → Transform → Load

4️⃣ 测试框架

id="7kq6o1" 复制代码
setup → test → teardown

十、优缺点

✅ 优点

  • 提高代码复用
  • 固定流程,降低出错概率
  • 符合开闭原则

❌ 缺点

  • 依赖继承
  • 灵活性不如策略模式
  • 子类过多时复杂

十一、什么时候使用模板方法?

适合:

  • 流程固定
  • 步骤可变
  • 多个类似算法

不适合:

  • 需要动态切换逻辑
  • 流程变化频繁

十二、一句话总结

模板方法模式的本质是:
固定流程,开放步骤。

换句话说:

把"骨架"写在父类,把"细节"交给子类。


相关推荐
FreakStudio2 小时前
ESP32居然能当 DNS 服务器用?内含NCSI欺骗和DNS劫持实现
python·单片机·嵌入式·面向对象·并行计算·电子diy
乐观勇敢坚强的老彭2 小时前
2026全国青少年信息素养大赛考纲
python·数学建模
YMWM_3 小时前
【问题】thor上的cubLas
linux·python·thor
wefly20173 小时前
免安装!m3u8live.cn在线 M3U8 播放器,小白也能快速上手
java·开发语言·python·json·php·m3u8·m3u8在线转换
2401_873544923 小时前
使用Python进行PDF文件的处理与操作
jvm·数据库·python
爱学习的程序媛3 小时前
【Web前端】JavaScript设计模式全解析
前端·javascript·设计模式·web
程序员小远3 小时前
软件测试常见Bug清单
自动化测试·软件测试·python·功能测试·测试工具·测试用例·bug
小仙女的小稀罕4 小时前
听不清重要会议录音急疯?这款常见AI工具听脑AI精准转译
开发语言·人工智能·python