策略模式是什么?如何定义并封装一系列算法
策略模式 (Strategy Pattern)
应用场景:当需要根据不同条件选择不同算法或行为时,将算法封装成独立的策略类,使它们可以互相替换。
在这里插入图片描述
模板模式 (Template Pattern)
应用场景:当需要根据不同条件选择不同算法或行为时,将算法封装成独立的策略类,使它们可以互相替换
模板模式与策略模式的深度对比与区分
确实,模板模式和策略模式在结构上有相似之处,但它们的设计意图和应用场景有本质区别。下面我将详细分析两者的异同,并通过典型场景的代码示例展示它们的区别。
核心区别对比表
特性 | 模板模式 (Template Method) | 策略模式 (Strategy) |
---|---|---|
设计目的 | 定义算法骨架,允许子类重写特定步骤 | 定义算法家族,使它们可以互相替换 |
控制流程 | 父类控制流程,子类实现部分步骤 | 策略接口定义行为,上下文选择具体策略 |
代码复用 | 通过继承实现代码复用 | 通过组合实现行为复用 |
扩展方式 | 垂直扩展(子类化) | 水平扩展(添加新策略) |
运行时灵活性 | 编译时确定行为 | 运行时动态切换行为 |
适用场景 | 有固定流程但部分步骤可变 | 需要灵活切换不同算法 |
类关系 | 继承关系 abstract | 组合关系 interface |
变化部分 | 算法中的某些步骤 | 整个算法或策略 |
混合使用两种模式的场景
在实际开发中,可以结合两种模式的优点:
// 策略接口
interface CompressionStrategy {
byte[] compress(byte[] data);
}
// 具体策略
class ZipCompression implements CompressionStrategy {
@Override
public byte[] compress(byte[] data) {
System.out.println("使用ZIP算法压缩");
return data; // 简化实现
}
}
class RarCompression implements CompressionStrategy {
@Override
public byte[] compress(byte[] data) {
System.out.println("使用RAR算法压缩");
return data; // 简化实现
}
}
// 模板类
abstract class FileProcessor {
private CompressionStrategy compressionStrategy;
public FileProcessor(CompressionStrategy strategy) {
this.compressionStrategy = strategy;
}
// 模板方法
public final void processFile() {
validateFile();
byte[] data = readFile();
byte[] processedData = processData(data);
byte[] compressedData = compressionStrategy.compress(processedData);
saveFile(compressedData);
logResult();
}
protected abstract void validateFile();
protected abstract byte[] readFile();
protected abstract byte[] processData(byte[] data);
protected abstract void saveFile(byte[] data);
protected void logResult() {
System.out.println("文件处理完成");
}
}
// 具体实现
class ImageProcessor extends FileProcessor {
public ImageProcessor(CompressionStrategy strategy) {
super(strategy);
}
@Override
protected void validateFile() {
System.out.println("验证图片文件格式");
}
@Override
protected byte[] readFile() {
System.out.println("读取图片文件");
return new byte[0]; // 简化实现
}
@Override
protected byte[] processData(byte[] data) {
System.out.println("处理图片数据");
return data;
}
@Override
protected void saveFile(byte[] data) {
System.out.println("保存处理后的图片");
}
}
// 使用
public class MixedDemo {
public static void main(String[] args) {
// 使用模板模式定义处理流程,策略模式切换压缩算法
FileProcessor processor = new ImageProcessor(new ZipCompression());
processor.processFile();
System.out.println("------");
processor = new ImageProcessor(new RarCompression());
processor.processFile();
}
}