登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
每日签到
每天签到奖励2圆-6圆
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
VIP申请
VIP网盘
网盘
联系我们
每日签到
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语 ...
【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
[ 复制链接 ]
阜逐忍
2025-6-6 09:47:41
简介
模板方法模式(Template Method Pattern)也叫模板模式,是一种行为型模式。它定义了一个抽象公开类,包含基本的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。不同的子类以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。以此基于公共的模板,来实现实现不同的功能。
模板模式适用于一些复杂操作进行步骤分割、抽取公共部分由抽象父类实现、将不同的部分在父类中定义抽象实现、而将具体实现过程由子类完成。对于有多个子类具有共有的方法,且逻辑相同,可以考虑作为模板方法。
作用
相同的部分父类给出统一的模板,子类大量复用,从而节省代码,复用逻辑。
封装不变部分,扩展可变部分,行为由父类控制,子类灵活实现,便于维护和扩展。
实现步骤
创建一个抽象的模板类,定义基本流程,同时定义一些基本方法供子类去实现。
创建多个子类继承抽象模板,覆盖父类的相关动作和方法。
UML
template-pattern.png
Java代码
抽象模板类
// GameTemplate.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();
}
}
复制代码
具体业务类,继承抽象模板
// Basketball.java 定义子类覆写父类抽象方法
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!]");
}
}
复制代码
// Football.java 定义子类覆写父类抽象方法
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!]");
}
}
复制代码
// Tennis.java 定义子类覆写父类抽象方法
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!]");
}
// 在调用父类play之前,如果要执行自己的行为,也可以覆盖父类方法
// 先执行自己的,再调用父类的方法
@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);
复制代码
抽象模板类
// game_template.c 定义抽象模板类,有抽象方法和具体方法
#include "func.h"
// 定义抽象模板类的公共部分,这里用struct替代
// 抽象方法待子类来实现
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)
{
// printf("\r\n game_template_constructor() [构建GameTemplate]");
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;
}
复制代码
具体业务类,继承抽象模板
// basketball.c 定义子类覆写父类抽象方法
#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->start = &basketball_start;
game->end = &basketball_end;
return game;
}
复制代码
// football.c 定义子类覆写父类抽象方法
#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;
}
复制代码
// tennis.c 定义子类覆写父类抽象方法
#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!]");
}
// 在调用父类play之前,如果要执行自己的行为,也可以覆盖父类方法
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
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
模板
方法
设计模式
详解
Java
相关帖子
泛目录20个模板_crPAeZ
ORA-01720 错误及解决方法
Java 8 终于要被淘汰了!带你速通 Java 8~24 新特性 | 又能跟面试官吹牛皮了
技术面:Java并发(线程池、ForkJoinPool)
无GC的Java创新设计思路:作用域引用式自动内存管理
【分享+1】HarmonyOS官方模板优秀案例(第6期:商务办公 · 笔记应用)
漏洞实战--java反序列化--用友NC UserAuthenticationServlet
技术面:Java并发(线程同步、死锁、多线程编排)
JWT攻击详解与CTF实战
泛目录新模板完整版_NcfWt
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
程序
泛目录20个模板_crPAeZ
1
31
新程序
2025-09-04
安全
ORA-01720 错误及解决方法
0
789
万妙音
2025-09-04
安全
Java 8 终于要被淘汰了!带你速通 Java 8~24 新特性 | 又能跟面试官吹牛皮了
0
730
任修
2025-09-05
业界
技术面:Java并发(线程池、ForkJoinPool)
0
146
揉幽递
2025-09-05
业界
无GC的Java创新设计思路:作用域引用式自动内存管理
0
865
昝梓菱
2025-09-05
安全
【分享+1】HarmonyOS官方模板优秀案例(第6期:商务办公 · 笔记应用)
0
532
轧岔
2025-09-09
安全
漏洞实战--java反序列化--用友NC UserAuthenticationServlet
0
653
锦惺
2025-09-09
业界
技术面:Java并发(线程同步、死锁、多线程编排)
0
972
丧血槌
2025-09-10
业界
JWT攻击详解与CTF实战
0
329
癖艺泣
2025-09-10
程序
泛目录新模板完整版_NcfWt
0
1
新程序
2025-09-12
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
安全
签约作者
程序园优秀签约作者
发帖
阜逐忍
2025-6-6 09:47:41
关注
0
粉丝关注
17
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
杭环
9988
凶契帽
9988
4
氛疵
9988
5
黎瑞芝
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多