设计模式实战:模板方法模式(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

十、优缺点

✅ 优点

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

❌ 缺点

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

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

适合:

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

不适合:

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

十二、一句话总结

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

换句话说:

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


相关推荐
m0_7164300721 小时前
mysql数据库表名区分大小写吗_通过lower case table names配置
jvm·数据库·python
Rsun0455121 小时前
15、Java 观察者模式从入门到实战
java·python·模板方法模式
2401_8359568121 小时前
如何利用SQL子查询进行实时监控数据分析_性能优化
jvm·数据库·python
百锦再21 小时前
使用JavaScript获取和解析页面内容的完整指南
开发语言·前端·javascript·python·flask·fastapi
a95114164221 小时前
如何在Bootstrap中实现响应式的统计数据卡片
jvm·数据库·python
Shorasul1 天前
golang如何实现设备数据采集网关_golang设备数据采集网关实现要点
jvm·数据库·python
慕涯AI1 天前
Agent 30 课程开发指南 - 第19课
人工智能·python
妙蛙种子3111 天前
【Java设计模式 | 创建者模式】建造者模式
java·开发语言·后端·设计模式·建造者模式
2301_764150561 天前
如何用 some 检测数组中是否存在至少一个满足条件的项
jvm·数据库·python
我是无敌小恐龙1 天前
线下班第一课
python·考研·django·ai编程