Loading... # 模板方法模式 # 什么是模板方法模式? 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),是行为型设计模式之一。它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。这样,子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。此模式鼓励将不变的行为放在基类中,实现复用,而将可变的行为放在子类中,实现扩展。 # 定义 ## 定义和意图 模板方法模式在基类中定义一个算法的骨架,并允许子类在不改变算法结构的情况下重定义某些步骤,目的是实现代码复用,同时保持算法的一致性和灵活性。 ## 使用场景 适用场景包括: * 实现一个算法的通用部分,并将可变的行为留给子类实现。 * 提取子类中的公共行为,集中到一个公共父类中,避免代码重复。 * 控制子类扩展,防止子类改变算法中的固定部分。 # 结构 ## 角色和职责 1. **抽象类(Abstract Class)** :定义算法骨架,包括模板方法和若干基本方法。 2. **具体类(Concrete Class)** :实现抽象类中的基本方法,实现算法中可变的部分。 ## UML 图解 以下是模板方法模式的 UML 类图: ```plantuml @startuml abstract class DataProcessor { +process() {abstract} void readData() {abstract} void processData() boolean shouldSaveData() void saveData() } class CSVDataProcessor { +readData() +processData() } class XMLDataProcessor { +readData() +processData() +shouldSaveData() : boolean } class CustomDataProcessor { +readData() +processData() +saveData() } DataProcessor <|-- CSVDataProcessor DataProcessor <|-- XMLDataProcessor DataProcessor <|-- CustomDataProcessor @enduml ``` 模板方法活动图 ```plantuml @startuml |DataProcessor| start :process(); :readData(); :processData(); if (shouldSaveData()) then (yes) :saveData(); else (no) endif stop @enduml ``` # 实现 ## Java 代码示例 以下是一个通过模板方法模式实现的数据处理框架示例: ```java // 抽象类,定义算法骨架 abstract class DataProcessor { // 模板方法,定义了处理数据的流程 public final void process() { readData(); processData(); if (shouldSaveData()) { // 钩子方法 saveData(); } } // 基本方法(可以是具体的,也可以是抽象的) abstract void readData(); abstract void processData(); // 钩子方法,子类可以选择重写 void saveData() { System.out.println("数据保存!!!"); } // 钩子方法,默认实现返回true,子类可以选择重写 boolean shouldSaveData() { return true; } } // 具体类,实现抽象类中的基本方法 class CSVDataProcessor extends DataProcessor { @Override void readData() { System.out.println("读取CSV文件数据"); } @Override void processData() { System.out.println("处理CSV文件数据"); } } class XMLDataProcessor extends DataProcessor { @Override void readData() { System.out.println("读取XML文件数据"); } @Override void processData() { System.out.println("处理XML文件数据"); } @Override boolean shouldSaveData() { // XML数据处理后不需要保存 return false; } } // 具体类,重写抽象类中的saveData方法 class CustomDataProcessor extends DataProcessor { @Override void readData() { System.out.println("自定义数据读取"); } @Override void processData() { System.out.println("自定义数据处理"); } @Override void saveData() { System.out.println("自定义数据保存!"); } } // 客户端代码 public class TemplateMethodPatternDemo { public static void main(String[] args) { DataProcessor csvProcessor = new CSVDataProcessor(); csvProcessor.process(); DataProcessor xmlProcessor = new XMLDataProcessor(); xmlProcessor.process(); DataProcessor customProcessor = new CustomDataProcessor(); customProcessor.process(); } } ``` ## 详细解释 在上面的示例中,`DataProcessor` 类是一个抽象类,它定义了一个名为 `process` 的模板方法,并声明了两个抽象方法:`readData` 和 `processData`。具体类 `CSVDataProcessor` 和 `XMLDataProcessor` 以及 `CustomDataProcessor` 分别实现了这些抽象方法。 * **模板方法**:`process` 方法定义了处理数据的流程,包括读取数据、处理数据和保存数据。 * **基本方法**:`readData` 和 `processData` 是抽象方法,由子类实现具体的读取和处理逻辑。 * **钩子方法**:`saveData` 和 `shouldSaveData` 是钩子方法,子类可以选择重写以改变默认行为。 通过调用模板方法 `process`,我们可以看到不同的数据处理方式如何按照相同的流程执行,但具体步骤由子类决定。使用钩子方法可以进一步增强灵活性,使子类可以根据需要选择性地执行某些步骤。 # 优缺点 ## 优点 * **代码复用**:将相同的代码提取到基类中,减少了代码重复。 * **灵活性**:允许子类重定义部分步骤而不改变整体算法。 * **控制反转**:通过模板方法调用子类实现的步骤,实现了一种控制反转。 ## 缺点 * **继承关系**:模板方法模式依赖继承,可能导致类的数量增加,且父类和子类之间的耦合度较高。 * **灵活性降低**:模板方法定义在父类中,如果需要修改算法的固定部分,需要修改父类,影响所有子类。 # 实际应用 ## 真实案例 在实际开发中,模板方法模式广泛应用于框架设计中。例如,Java 中的 `java.io.InputStream` 和 `java.io.OutputStream` 类就采用了模板方法模式,定义了读取和写入数据的固定流程,而具体的读取和写入方式由子类实现。 ## 应用场景讨论 模板方法模式适合用于需要固定流程的算法场景,例如: * **数据处理管道**:固定数据处理流程的各个步骤,如数据的读取、处理和保存。 * **UI 渲染框架**:定义通用的 UI 渲染流程,不同控件的具体渲染方式由子类实现。 # 总结 模板方法模式通过定义算法的骨架,允许子类重定义某些步骤,实现了代码复用和扩展性。学习和应用这一模式,可以帮助开发者设计出结构清晰、可维护性高的代码。希望这篇文章能帮助您深入理解模板方法模式,从基础概念到实际应用,逐步掌握这一重要的设计模式。 最后修改:2024 年 07 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果文章有帮助到你,请随意赞赏