简介
模板方法模式(Template Method Pattern)也叫模板模式,是一种行为型模式。它定义了一个抽象公开类,包含基本的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。不同的子类以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。以此基于公共的模板,来实现实现不同的功能。
模板模式适用于一些复杂操作进行步骤分割、抽取公共部分由抽象父类实现、将不同的部分在父类中定义抽象实现、而将具体实现过程由子类完成。对于有多个子类具有共有的方法,且逻辑相同,可以考虑作为模板方法。
作用
- 相同的部分父类给出统一的模板,子类大量复用,从而节省代码,复用逻辑。
- 封装不变部分,扩展可变部分,行为由父类控制,子类灵活实现,便于维护和扩展。
实现步骤
- 创建一个抽象的模板类,定义基本流程,同时定义一些基本方法供子类去实现。
- 创建多个子类继承抽象模板,覆盖父类的相关动作和方法。
UML
template-pattern.png
Java代码
抽象模板类
| |
| public abstract class GameTemplate { |
| |
| |
| abstract void init(); |
| |
| abstract void start(); |
| |
| abstract void end(); |
| |
| |
| public void play() { |
| |
| System.out.println(this.getClass().getSimpleName() + "::play()"); |
| |
| |
| init(); |
| |
| |
| start(); |
| |
| |
| end(); |
| } |
| |
| } |
具体业务类,继承抽象模板
| |
| public class Basketball extends GameTemplate { |
| |
| @Override |
| void init() { |
| System.out.println("Basketball::init() [Basketball Game Initialized! Start playing.]"); |
| } |
| |
| @Override |
| void start() { |
| System.out.println("Basketball::start() [Basketball Game Started. Enjoy the game!]"); |
| } |
| |
| @Override |
| void end() { |
| System.out.println("Basketball::end() [Basketball Game Finished!]"); |
| } |
| |
| } |
| |
| public class Football extends GameTemplate { |
| |
| @Override |
| void init() { |
| System.out.println("Football::init() [Football Game Initialized! Start playing.]"); |
| } |
| |
| @Override |
| void start() { |
| System.out.println("Football::start() [Football Game Started. Enjoy the game!]"); |
| } |
| |
| @Override |
| void end() { |
| System.out.println("Football::end() [Football Game Finished!]"); |
| } |
| |
| } |
| |
| public class Tennis extends GameTemplate { |
| |
| @Override |
| void init() { |
| System.out.println("Tennis::init() [Tennis Game Initialized! Start playing.]"); |
| } |
| |
| @Override |
| void start() { |
| System.out.println("Tennis::start() [Tennis Game Started. Enjoy the game!]"); |
| } |
| |
| @Override |
| void end() { |
| System.out.println("Tennis::end() [Tennis Game Finished!]"); |
| } |
| |
| |
| |
| @Override |
| public void play() { |
| System.out.println("Tennis::play() [Tennis Game play!]"); |
| super.play(); |
| } |
| } |
测试调用
| |
| |
| |
| |
| GameTemplate football = new Football(); |
| football.play(); |
| |
| System.out.println("==="); |
| GameTemplate basketball = new Basketball(); |
| basketball.play(); |
| |
| System.out.println("==="); |
| GameTemplate tennis = new Tennis(); |
| tennis.play(); |
C语言代码
头文件
// func.h
| #include <stdio.h> |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <stdbool.h> |
| #include <string.h> |
| |
| typedef struct GameTemplate GameTemplate; |
| typedef struct Football Football; |
| typedef struct Basketball Basketball; |
| typedef struct Tennis Tennis; |
| |
| |
| typedef struct GameTemplate |
| { |
| char name[50]; |
| void (*init)(GameTemplate *game); |
| void (*start)(GameTemplate *game); |
| void (*end)(GameTemplate *game); |
| void (*play)(GameTemplate *game); |
| } GameTemplate; |
| void template_play(GameTemplate *game); |
| GameTemplate *game_template_constructor(char *name); |
| |
| |
| typedef struct Football |
| { |
| char name[50]; |
| void (*init)(Football *game); |
| void (*start)(Football *game); |
| void (*end)(Football *game); |
| void (*play)(Football *game); |
| } Football; |
| Football *football_constructor(char *name); |
| |
| |
| typedef struct Basketball |
| { |
| char name[50]; |
| void (*init)(Basketball *game); |
| void (*start)(Basketball *game); |
| void (*end)(Basketball *game); |
| void (*play)(Basketball *game); |
| } Basketball; |
| Basketball *basketball_constructor(char *name); |
| |
| |
| typedef struct Tennis |
| { |
| char name[50]; |
| void (*init)(Tennis *game); |
| void (*start)(Tennis *game); |
| void (*end)(Tennis *game); |
| void (*play)(Tennis *game); |
| } Tennis; |
| Tennis *tennis_constructor(char *name); |
| |
抽象模板类
| |
| #include "func.h" |
| |
| |
| |
| |
| void template_init(GameTemplate *game) {} |
| void template_start(GameTemplate *game) |
| { |
| printf("\r\n GameTemplate::start() [GameTemplate Initialized! Start playing.]"); |
| } |
| void template_end(GameTemplate *game) {} |
| |
| |
| void template_play(GameTemplate *game) |
| { |
| printf("\r\n GameTemplate::play() [name=%s]", game->name); |
| |
| |
| game->init(game); |
| |
| |
| game->start(game); |
| |
| |
| game->end(game); |
| } |
| |
| GameTemplate *game_template_constructor(char *name) |
| { |
| |
| GameTemplate *game = (GameTemplate *)malloc(sizeof(GameTemplate)); |
| strcpy(game->name, name); |
| game->init = &template_init; |
| game->start = &template_start; |
| game->end = &template_end; |
| game->play = &template_play; |
| return game; |
| } |
具体业务类,继承抽象模板
| |
| #include "func.h" |
| |
| |
| void basketball_init(Basketball *game) |
| { |
| printf("\r\n Basketball::init() [Basketball Game Initialized! Start playing.]"); |
| } |
| |
| void basketball_start(Basketball *game) |
| { |
| printf("\r\n Basketball::start() [Basketball Game Started. Enjoy the game!]"); |
| } |
| |
| void basketball_end(Basketball *game) |
| { |
| printf("\r\n Basketball::end() [Basketball Game Finished!]"); |
| } |
| |
| Basketball *basketball_constructor(char *name) |
| { |
| printf("\r\n basketball_constructor() [构建Basketball]"); |
| GameTemplate *template = game_template_constructor(name); |
| Basketball *game = (Basketball *)template; |
| game->init = &basketball_init; |
| |
| |
| game->end = &basketball_end; |
| return game; |
| } |
| |
| #include "func.h" |
| |
| |
| void football_init(Football *game) |
| { |
| printf("\r\n Football::init() [Football Game Initialized! Start playing.]"); |
| } |
| |
| void football_start(Football *game) |
| { |
| printf("\r\n Football::start() [Football Game Started. Enjoy the game!]"); |
| } |
| |
| void football_end(Football *game) |
| { |
| printf("\r\n Football::end() [Football Game Finished!]"); |
| } |
| |
| Football *football_constructor(char *name) |
| { |
| printf("\r\n football_constructor() [构建Football]"); |
| GameTemplate *template = game_template_constructor(name); |
| Football *game = (Football *)template; |
| game->init = &football_init; |
| game->start = &football_start; |
| game->end = &football_end; |
| return game; |
| } |
| |
| #include "func.h" |
| |
| |
| void tennis_init(Tennis *game) |
| { |
| printf("\r\n Tennis::init() [Tennis Game Initialized! Start playing.]"); |
| } |
| |
| void tennis_start(Tennis *game) |
| { |
| printf("\r\n Tennis::start() [Tennis Game Started. Enjoy the game!]"); |
| } |
| |
| void tennis_end(Tennis *game) |
| { |
| printf("\r\n Tennis::end() [Tennis Game Finished!]"); |
| } |
| |
| |
| void tennis_play(Tennis *game) |
| { |
| |
| printf("\r\n Tennis::play() [Tennis Game Play!]"); |
| template_play((GameTemplate *)game); |
| } |
| |
| Tennis *tennis_constructor(char *name) |
| { |
| printf("\r\n tennis_constructor() [构建Tennis]"); |
| GameTemplate *template = game_template_constructor(name); |
| Tennis *game = (Tennis *)template; |
| game->init = &tennis_init; |
| game->start = &tennis_start; |
| game->end = &tennis_end; |
| game->play = &tennis_play; |
| return game; |
| } |
测试调用
| #include "../src/func.h" |
| |
| int main(void) |
| { |
| printf("test start:\r\n"); |
| |
| |
| |
| |
| Football *football = football_constructor("football"); |
| football->play(football); |
| |
| printf("\r\n ==="); |
| Basketball *basketball = basketball_constructor("basketball"); |
| basketball->play(basketball); |
| |
| printf("\r\n ==="); |
| Tennis *tennis = tennis_constructor("basketball"); |
| tennis->play(tennis); |
| } |
| |
更多语言版本
不同语言设计模式源码:https://github.com/microwind/design-pattern
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南