策略模式 + 模板方法模式
策略模式和模板方法模式的组合是一种常见的设计模式组合,它将行为逻辑的动态可替换性(策略模式)与算法框架的固定性(模板方法模式)结合起来。模板方法模式定义了一个算法的固定框架,而策略模式允许在框架中的某些步骤上动态替换不同的实现逻辑。
1. 场景说明
这种组合适用于以下场景:
- 算法框架固定,部分逻辑需要灵活替换: 模板方法定义算法的固定步骤,策略模式动态替换某些步骤的实现。
- 需要支持多种算法或处理方式: 策略模式可以动态选择不同的算法,模板方法负责控制流程。
- 避免重复代码: 模板方法封装通用逻辑,策略模式提供不同的实现,从而减少代码重复。
2. 示例场景:文件数据处理系统
我们设计一个文件数据处理系统,具有以下特点:
- 不同文件类型的数据(如 CSV、JSON)需要进行加载、处理和保存。
- 数据的处理逻辑可能因文件类型而异,但加载和保存的逻辑是通用的。
通过模板方法模式定义数据处理的固定流程,并通过策略模式动态替换数据处理的逻辑。
(1) 策略接口
定义一个策略接口,用于定义数据处理逻辑。
// 数据处理策略接口
public interface DataProcessingStrategy {
void processData(); // 定义数据处理逻辑
}
(2) 具体策略实现
每种文件类型都有不同的数据处理逻辑。
// 具体策略:处理CSV文件数据
public class CsvProcessingStrategy implements DataProcessingStrategy {
@Override
public void processData() {
System.out.println("处理CSV文件的数据...");
}
}
// 具体策略:处理JSON文件数据
public class JsonProcessingStrategy implements DataProcessingStrategy {
@Override
public void processData() {
System.out.println("处理JSON文件的数据...");
}
}
(3) 模板方法
使用抽象类定义数据处理的固定流程,包含加载数据、处理数据和保存数据三个步骤,其中处理数据的逻辑由策略模式决定。
// 数据处理模板类
public abstract class DataProcessor {
private DataProcessingStrategy strategy; // 策略模式
public DataProcessor(DataProcessingStrategy strategy) {
this.strategy = strategy;
}
// 模板方法:定义数据处理的固定流程
public final void process() {
loadData();
strategy.processData(); // 使用策略模式进行数据处理
saveData();
}
// 加载数据
protected void loadData() {
System.out.println("加载数据...");
}
// 保存数据
protected void saveData() {
System.out.println("保存数据...");
}
}
(4) 具体模板类
针对不同的数据来源(如文件或数据库),可以定义不同的模板实现。
// 从文件加载数据
public class FileDataProcessor extends DataProcessor {
public FileDataProcessor(DataProcessingStrategy strategy) {
super(strategy);
}
@Override
protected void loadData() {
System.out.println("从文件加载数据...");
}
@Override
protected void saveData() {
System.out.println("将数据保存到文件...");
}
}
(5) 客户端代码
客户端可以根据需要选择不同的策略和模板。
public class Client {
public static void main(String[] args) {
// 使用CSV处理策略
DataProcessingStrategy csvStrategy = new CsvProcessingStrategy();
DataProcessor fileProcessorCsv = new FileDataProcessor(csvStrategy);
fileProcessorCsv.process();
System.out.println("\n");
// 使用JSON处理策略
DataProcessingStrategy jsonStrategy = new JsonProcessingStrategy();
DataProcessor fileProcessorJson = new FileDataProcessor(jsonStrategy);
fileProcessorJson.process();
}
}
运行结果:
从文件加载数据...
处理CSV文件的数据...
将数据保存到文件...
从文件加载数据...
处理JSON文件的数据...
将数据保存到文件...
3. 优点
组合带来的优势
-
分离通用流程和具体实现:
- 模板方法封装通用的流程逻辑,减少了重复代码。
- 策略模式动态替换部分实现,增强了灵活性。
-
符合开闭原则:
- 添加新策略只需实现
DataProcessingStrategy接口,而不需要修改模板逻辑。 - 添加新模板类只需继承
DataProcessor,而不需要修改现有代码。
- 添加新策略只需实现
-
灵活扩展:
- 可以轻松扩展新的数据处理逻辑(新策略)。
- 可以支持新的数据来源(新模板)。
4. 缺点
-
增加系统复杂性:
- 模式组合会引入更多的类和接口,增加了系统的复杂度。
-
依赖注入:
- 模板方法需要依赖策略类,这可能增加类之间的耦合性。
5. 应用场景
-
数据处理系统:
- 模板方法定义加载、处理、保存的固定流程。
- 策略模式动态选择数据处理逻辑。
-
支付系统:
- 模板方法定义支付的固定流程(如验证、扣款、记录)。
- 策略模式提供不同的支付方式(如支付宝、微信、信用卡)。
-
游戏AI:
- 模板方法定义角色行为的固定步骤(如选择目标、行动)。
- 策略模式动态选择不同的AI算法。
-
日志系统:
- 模板方法定义日志的固定流程(如格式化、输出)。
- 策略模式动态选择输出方式(如文件、控制台、数据库)。
6. 总结
策略模式 + 模板方法模式是一种功能互补的组合设计模式。模板方法模式提供了固定的算法框架,而策略模式允许动态替换其中的可变部分。通过这种组合,可以实现灵活、可扩展的系统架构,同时保持代码的清晰性和可维护性。适用于需要固定流程但某些步骤需要灵活扩展的场景。
2415

被折叠的 条评论
为什么被折叠?



