本文目录导读:

Java模板方法模式案例
模板方法模式是一种行为设计模式,它定义一个操作中的算法骨架,而将一些步骤延迟到子类中,下面通过几个实际案例来演示。
案例1:游戏制作模板
基础模板类
// 游戏模板
public abstract class Game {
// 模板方法 - 定义游戏流程
public final void play() {
// 初始化游戏
initGame();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
// 可选钩子方法
if (isAddBonus()) {
addBonus();
}
}
// 抽象方法 - 子类必须实现
protected abstract void initGame();
protected abstract void startPlay();
protected abstract void endPlay();
// 钩子方法 - 子类可选覆盖
protected boolean isAddBonus() {
return false;
}
protected void addBonus() {
System.out.println("添加额外奖励");
}
}
具体子类实现
// 足球游戏
public class FootballGame extends Game {
@Override
protected void initGame() {
System.out.println("足球游戏初始化:创建22名球员,准备足球场");
}
@Override
protected void startPlay() {
System.out.println("足球游戏开始:开球,比赛进行中");
}
@Override
protected void endPlay() {
System.out.println("足球游戏结束:裁判吹响终场哨");
}
// 覆盖钩子方法
@Override
protected boolean isAddBonus() {
return true;
}
@Override
protected void addBonus() {
System.out.println("足球游戏特殊奖励:最佳球员额外获得10分");
}
}
// 篮球游戏
public class BasketballGame extends Game {
@Override
protected void initGame() {
System.out.println("篮球游戏初始化:创建10名球员,准备篮球场");
}
@Override
protected void startPlay() {
System.out.println("篮球游戏开始:跳球,比赛开始");
}
@Override
protected void endPlay() {
System.out.println("篮球游戏结束:计时器响铃");
}
}
测试代码
public class TemplateMethodDemo {
public static void main(String[] args) {
System.out.println("=== 足球游戏 ===");
Game football = new FootballGame();
football.play();
System.out.println("\n=== 篮球游戏 ===");
Game basketball = new BasketballGame();
basketball.play();
}
}
输出结果
=== 足球游戏 ===
足球游戏初始化:创建22名球员,准备足球场
足球游戏开始:开球,比赛进行中
足球游戏结束:裁判吹响终场哨
足球游戏特殊奖励:最佳球员额外获得10分
=== 篮球游戏 ===
篮球游戏初始化:创建10名球员,准备篮球场
篮球游戏开始:跳球,比赛开始
篮球游戏结束:计时器响铃
案例2:数据导出系统
导出模板类
// 数据导出模板
public abstract class DataExporter {
// 模板方法 - 定义导出流程
public final void exportData(String data) {
System.out.println("===== 开始导出数据 =====");
// 1. 验证数据
if (!validateData(data)) {
System.out.println("数据验证失败,导出终止");
return;
}
// 2. 处理数据
String processedData = processData(data);
// 3. 写入文件
writeToFile(processedData);
// 4. 发送通知
sendNotification();
System.out.println("===== 导出完成 =====");
}
// 抽象方法
protected abstract boolean validateData(String data);
protected abstract String processData(String data);
protected abstract void writeToFile(String data);
// 具体方法
protected void sendNotification() {
System.out.println("发送导出完成通知");
}
// 钩子方法
protected boolean needValidation() {
return true;
}
}
具体导出类
// CSV导出器
public class CSVExporter extends DataExporter {
@Override
protected boolean validateData(String data) {
System.out.println("CSV格式验证:检查逗号分隔格式");
return data != null && data.contains(",");
}
@Override
protected String processData(String data) {
System.out.println("CSV数据处理:添加表头和数据行");
return "ID,名称,价格\n" + data;
}
@Override
protected void writeToFile(String data) {
System.out.println("写入CSV文件:export.csv");
System.out.println("文件内容:\n" + data);
}
}
// PDF导出器
public class PDFExporter extends DataExporter {
@Override
protected boolean validateData(String data) {
System.out.println("PDF格式验证:检查数据完整性");
return data != null && !data.isEmpty();
}
@Override
protected String processData(String data) {
System.out.println("PDF数据处理:添加PDF标记和字体信息");
return "%PDF-1.4\n" + data + "\n%%EOF";
}
@Override
protected void writeToFile(String data) {
System.out.println("写入PDF文件:export.pdf");
System.out.println("文件内容:\n" + data);
}
}
测试代码
public class ExportDemo {
public static void main(String[] args) {
// CSV导出
System.out.println("=== CSV导出 ===");
DataExporter csvExporter = new CSVExporter();
csvExporter.exportData("1,苹果,5.5\n2,香蕉,3.2");
System.out.println("\n=== PDF导出 ===");
DataExporter pdfExporter = new PDFExporter();
pdfExporter.exportData("商品列表\na. 苹果 - 5.5元\nb. 香蕉 - 3.2元");
}
}
案例3:银行取款流程
银行模板类
// 银行取款模板
public abstract class BankTransaction {
// 模板方法 - 定义取款流程
public final void withdraw(String account, double amount) {
System.out.println("===== 取款流程开始 =====");
// 1. 验证账户
if (!verifyAccount(account)) {
System.out.println("账户验证失败");
return;
}
// 2. 验证余额
if (!verifyBalance(account, amount)) {
System.out.println("余额不足");
return;
}
// 3. 执行取款
double fee = calculateFee(amount);
double actualAmount = amount - fee;
executeWithdrawal(account, actualAmount);
// 4. 记录交易
logTransaction(account, actualAmount, fee);
// 5. 可选发送短信
if (needSendSMS()) {
sendSMS("取款成功:" + actualAmount + "元,手续费:" + fee + "元");
}
System.out.println("===== 取款流程结束 =====");
}
// 抽象方法
protected abstract boolean verifyAccount(String account);
protected abstract boolean verifyBalance(String account, double amount);
protected abstract void executeWithdrawal(String account, double amount);
protected abstract double calculateFee(double amount);
// 通用方法
protected void logTransaction(String account, double amount, double fee) {
System.out.println("记录交易:" + account + " 取款" + amount + "元,手续费" + fee + "元");
}
// 钩子方法
protected boolean needSendSMS() {
return true;
}
protected void sendSMS(String message) {
System.out.println("发送短信通知:" + message);
}
}
具体银行类
// 普通银行取款
public class NormalBank extends BankTransaction {
@Override
protected boolean verifyAccount(String account) {
System.out.println("普通银行验证账户:" + account);
return account.startsWith("SAV");
}
@Override
protected boolean verifyBalance(String account, double amount) {
System.out.println("普通银行检查余额");
// 假设余额充足
return amount <= 10000;
}
@Override
protected void executeWithdrawal(String account, double amount) {
System.out.println("普通银行执行取款:" + amount + "元");
}
@Override
protected double calculateFee(double amount) {
// 普通银行手续费1%
return amount * 0.01;
}
@Override
protected boolean needSendSMS() {
return true;
}
}
// VIP银行取款
public class VIPBank extends BankTransaction {
@Override
protected boolean verifyAccount(String account) {
System.out.println("VIP银行验证账户:" + account);
return account.startsWith("VIP");
}
@Override
protected boolean verifyBalance(String account, double amount) {
System.out.println("VIP银行检查余额");
// VIP客户可透支
return amount <= 100000;
}
@Override
protected void executeWithdrawal(String account, double amount) {
System.out.println("VIP银行执行取款:" + amount + "元");
}
@Override
protected double calculateFee(double amount) {
// VIP客户免手续费
return 0;
}
// 覆盖钩子方法
@Override
protected boolean needSendSMS() {
return false; // VIP客户不需要短信通知
}
}
测试代码
public class BankDemo {
public static void main(String[] args) {
System.out.println("=== 普通银行取款 ===");
BankTransaction normalBank = new NormalBank();
normalBank.withdraw("SAV001", 1000);
System.out.println("\n=== VIP银行取款 ===");
BankTransaction vipBank = new VIPBank();
vipBank.withdraw("VIP001", 5000);
}
}
模板方法模式的优势
- 代码复用:公共算法骨架在父类中实现一次,子类只实现差异部分
- 控制流程:算法流程由父类控制,子类无法改变流程顺序
- 扩展方便:通过钩子方法,子类可以灵活地插入自定义逻辑
- 符合开闭原则:新增功能时,只需创建新的子类,不需要修改父类
适用场景
- 多个子类有共同的操作步骤和算法
- 重要的、复杂的算法集中在父类中
- 想让子类实现算法的可变部分,保持算法的整体结构不变
- 需要通过钩子方法控制子类的扩展点
模板方法模式非常适合处理那些有固定流程,但具体步骤实现不同的业务场景,如业务流程、数据处理、框架设计等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播