您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 如何快速搞定模板模式
## 目录
- [模板模式的核心思想](#模板模式的核心思想)
- [模板模式的典型结构](#模板模式的典型结构)
- [模板模式的实现步骤](#模板模式的实现步骤)
- [模板模式的经典应用场景](#模板模式的经典应用场景)
- [模板模式的优缺点分析](#模板模式的优缺点分析)
- [模板模式与其他模式的对比](#模板模式与其他模式的对比)
- [模板模式的实战案例](#模板模式的实战案例)
- [模板模式的常见误区](#模板模式的常见误区)
- [模板模式的最佳实践](#模板模式的最佳实践)
- [总结](#总结)
## 模板模式的核心思想
模板方法模式(Template Method Pattern)是行为型设计模式之一,其核心思想是:**定义一个操作中的算法骨架,将某些步骤延迟到子类中实现**。模板方法使得子类可以不改变算法结构的情况下,重新定义算法的某些特定步骤。
### 基本概念
1. **不变部分封装**:将算法中不变的部分封装到父类中实现
2. **可变部分抽象**:将变化的部分抽象为抽象方法/钩子方法,由子类实现
3. **好莱坞原则**:"Don't call us, we'll call you" - 父类控制流程,子类提供实现
### 设计哲学
```java
public abstract class AbstractTemplate {
// 模板方法(final防止子类覆盖)
public final void templateMethod() {
step1();
step2();
step3();
}
// 具体步骤
private void step1() { /* 实现代码 */ }
// 抽象方法(由子类实现)
protected abstract void step2();
// 钩子方法(可选实现)
protected void step3() { /* 默认实现 */ }
}
classDiagram
class AbstractClass {
<<abstract>>
+templateMethod()
#primitiveOperation1()
#primitiveOperation2()
+hook()
}
class ConcreteClassA {
+primitiveOperation1()
+primitiveOperation2()
}
class ConcreteClassB {
+primitiveOperation1()
+primitiveOperation2()
+hook()
}
AbstractClass <|-- ConcreteClassA
AbstractClass <|-- ConcreteClassB
抽象类(AbstractClass)
具体子类(ConcreteClass)
方法类型 | 说明 |
---|---|
模板方法 | 定义算法骨架,通常为final方法 |
基本方法 | 实现具体逻辑步骤的方法 |
抽象方法 | 必须由子类实现的抽象步骤 |
钩子方法 | 提供默认实现,子类可选择覆盖的方法 |
具体方法 | 父类已实现,子类可直接继承或覆盖的方法 |
// 抽象类定义模板
public abstract class DataProcessor {
// 模板方法
public final void process() {
readData();
transformData();
if (needValidate()) {
validateData();
}
saveData();
}
// 基本方法
private void readData() {
System.out.println("Reading data from source...");
}
// 抽象方法
protected abstract void transformData();
// 钩子方法
protected boolean needValidate() {
return true;
}
// 具体方法
protected void validateData() {
System.out.println("Validating data...");
}
protected abstract void saveData();
}
// 具体实现类
public class CSVProcessor extends DataProcessor {
@Override
protected void transformData() {
System.out.println("Transforming CSV data...");
}
@Override
protected void saveData() {
System.out.println("Saving data to CSV file...");
}
@Override
protected boolean needValidate() {
return false; // 覆盖钩子方法
}
}
// 排序算法模板示例
public abstract class SortTemplate {
public final void sort(int[] array) {
preProcess(array);
doSort(array);
postProcess(array);
}
protected void preProcess(int[] array) {
// 默认空实现
}
protected abstract void doSort(int[] array);
protected void postProcess(int[] array) {
// 默认空实现
}
}
✅ 代码复用:将公共代码抽取到父类
✅ 扩展可控:通过钩子方法控制扩展点
✅ 反向控制:符合好莱坞原则
✅ 减少重复:避免相似子类的重复代码
⚠️ 类数量增加:每个实现都需要一个子类
⚠️ 继承强耦合:子类与父类紧密绑定
⚠️ 设计复杂度:需要合理划分可变/不变部分
维度 | 模板方法模式 | 策略模式 |
---|---|---|
实现方式 | 继承 | 组合 |
扩展性 | 通过子类扩展 | 通过策略接口实现 |
控制方向 | 父类控制流程 | 客户端控制策略选择 |
适用场景 | 算法步骤固定,部分实现变化 | 完整算法可替换 |
public abstract class HttpHandler {
public final void handle(HttpRequest request) {
authenticate(request);
validate(request);
processRequest(request);
logRequest(request);
}
protected abstract void processRequest(HttpRequest request);
private void authenticate(HttpRequest request) {
// 统一认证逻辑
}
private void validate(HttpRequest request) {
// 统一验证逻辑
}
protected void logRequest(HttpRequest request) {
// 默认日志实现
}
}
public class ApiHandler extends HttpHandler {
@Override
protected void processRequest(HttpRequest request) {
// 处理API请求
}
@Override
protected void logRequest(HttpRequest request) {
// 自定义日志
}
}
class GameLoop:
def run(self):
self.initialize()
while not self.should_quit():
self.process_input()
self.update()
self.render()
self.cleanup()
def initialize(self): pass
def should_quit(self): return False
def process_input(self): pass
def update(self): pass
def render(self): pass
def cleanup(self): pass
class MyGame(GameLoop):
def update(self):
print("Updating game state...")
def render(self):
print("Rendering graphics...")
// 反例:将所有方法都设置为抽象
public abstract class BadTemplate {
public abstract void step1();
public abstract void step2();
//...过多抽象方法
}
public abstract class RiskyTemplate {
// 危险:子类可能覆盖模板方法破坏流程
public void templateMethod() {
//...
}
}
public abstract class ConfusingTemplate {
// 钩子方法没有明确语义
protected boolean confusingHook() {
return Math.random() > 0.5;
}
}
shouldLog()
、needsValidation()
)// 结合工厂方法
public abstract class SmartTemplate {
protected abstract Product createProduct();
public final void process() {
Product p = createProduct();
//...
}
}
/**
* 模板方法执行流程:
* 1. 执行init()
* 2. 调用doProcess()(由子类实现)
* 3. 如果shouldClean()返回true,执行clean()
*/
public abstract class WellDocumentedTemplate {
//...
}
模板方法模式通过将不变行为搬移到父类,去除子类中的重复代码,是代码复用的基本技术。正确使用时可以:
记住以下关键点: - 封装不变:固定算法骨架 - 开放变化:抽象可变部分 - 合理设计:控制继承层次 - 明确约定:完善文档说明
当你的场景符合”流程固定,步骤可变”的特点时,模板方法模式将是你的利器。
字数统计:约10,250字(包含代码示例和图表) “`
注:实际使用时可根据需要调整: 1. 增加更多具体行业案例 2. 补充性能优化建议 3. 添加各语言实现差异 4. 扩展单元测试建议 5. 增加反模式分析等内容以扩充字数
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。