什么是模板方法设计模式

  模板设计模式(Template Method Pattern) 是一种行为型设计模式,它通过抽象父类定义了一个算法的框架,并将一些步骤的实现延迟到子类中。通过这种方式,子类可以在不改变算法结构的情况下重新定义算法中的某些特定步骤。
 

案例

  假设我们有一个数据处理系统,需要从不同的数据源(例如CSV、txt、excel)中读取数据,处理数据,最后输出结果。
 

不使用模板方法模式:

  一般的方式是对不同数据源的文件处理编写不同的方法,

class DataProcessor {

    // 处理CSV数据
    public void processCsvFile() {
        readCsvData();
        processCsvData();
        outputCsvData();
    }

    // 处理Txt数据
    public void processTxtFile() {
        readTxtData();
        processTxtData();
        outputTxtData();
    }

    // 处理Excel数据
    public void processExcelFile() {
        readExcelData();
        processExcelData();
        outputExcelData();
    }


    private void readCsvData() {
    	//读取csv数据逻辑
    }
    private void processCsvData() {
        //处理csv数据逻辑
    }
    private void outputCsvData() {
        //输出csv结果
    }
    
    
    private void readTxtData() {
        //读取txt文件的逻辑
    }
    private void processTxtData() {
        //处理txt数据逻辑
    }
    private void outputTxtData() {
    	//输出Txt结果
    }
    

    private void processExcelData() {
        //处理excel数据逻辑
    }
    private void readExcelData() {
        //读取excel文件的逻辑
    }
    private void outputExcelData() {
        //输出Excel结果
    }
}

主函数:

public class Main {
    public static void main(String[] args) {
        DataProcessor processor = new DataProcessor();

        // 分别处理不同数据源
        processor.processCsvFile();
        processor.processTxtFile();
        processor.processExcelFile();
    }
}

  可以看到,虽然是对不同数据源(csv,txt,excel)的文件进行处理,但是逻辑都是 readData()-> processData()->outputData()的步骤.
 

这样的代码的缺点:

  1. 违反开闭原则(对扩展开放,对修改关闭):如果需要添加新的数据源类型(如读取word文件),我们必须为每个数据源添加新的方法,修改现有代码,容易出错.
  2. 重复代码: 对于每个格式的文件,我们都重复实现了读取数据、处理数据和输出数据的步骤,这导致代码冗长且不易维护.

 

使用模板方法模式改造

  模板方法模式通过父类定义一个算法的骨架(模板方法),并将某些步骤的实现细节延迟到子类中,避免了重复的代码。

1.定义抽象模板父类:

  将算法骨架抽离出来:

abstract class DataProcessorTemplate {

    // 模板方法,定义算法的骨架
    public final void processFile() {
        readData();
        processData();
        outputData();
    }

    // 每个子类必须实现这些方法
    protected abstract void readData();
    protected abstract void processData();
    protected abstract void outputData();
}

  将相同的核心流程(读取数据、处理数据、输出数据)在抽象父类DataProcessorTemplate中定义.而不同的数据源的具体实现细节则由子类实现。

 

2.实现细节交给子类实现:

class CsvDataProcessor extends DataProcessorTemplate {

    @Override
    protected void readData() {
        //读取csv文件
    }

    @Override
    protected void processData() {
        //处理csv文件
    }

    @Override
    protected void outputData() {
        //输出
    }
}

class TxtDataProcessor extends DataProcessorTemplate {

    @Override
    protected void readData() {
        //读取Txt文件
    }

    @Override
    protected void processData() {
        //处理Txt文件
    }

    @Override
    protected void outputData() {
        //输出
    }
}

class ExcelDataProcessor extends DataProcessorTemplate {

    @Override
    protected void readData() {
        //读取Excel文件
    }

    @Override
    protected void processData() {
        //处理Excel文件
    }

    @Override
    protected void outputData() {
        //输出
    }
}

 

3.使用

多态:父类引用指向子类对象,实现对不同对象的统一操作

public class Main {
    public static void main(String[] args) {
        DataProcessorTemplate csvProcessor = new CsvDataProcessor();
        csvProcessor.processFile();
        
        DataProcessorTemplate txtProcessor = new TxtDataProcessor();
        txtProcessor.processFile();
        
        DataProcessorTemplate excelProcessor = new ExcelDataProcessor();
        excelProcessor.processFile()
    }
}

  因为具体的实现细节已经在子类中实现,在使用时子类的实例直接调用父类的模板方法processData()即可完成对应逻辑.

模板方法模式的优点:

  1. 符合开闭原则(对扩展开放,对修改关闭):新增数据源只需要添加新的子类,不需要修改现有代码.
  2. 减少重复代码:核心流程(读取数据、处理数据、输出数据)在父类DataProcessorTemplate中定义,而不同的数据源的具体实现则由子类实现。
  3. 算法结构固定:模板方法定义了算法的整体结构,确保了算法步骤的执行顺序不变。

模板方法设计模式的缺点:

  1. 复杂度增加:模板方法模式可能会导致类的数目增加,因为每个具体子类对应一个具体实现。
  2. 灵活性较低: 因为部分算法结构在父类中已经确定,可能会在一定程度上限制了某些子类的灵活性.

 

模板方法设计模式的关键要点

  1. 父类定义算法框架:父类提供了一个固定的算法结构(即模板方法),并定义了算法中不变的部分。
  2. 子类重写某些步骤:子类可以在父类提供的框架内,重写其中的某些步骤,而无需改变整个算法的结构。
  3. 方法调用顺序固定:模板方法中的调用顺序由父类控制,子类只负责提供某些步骤的具体实现。

老铁觉得有用就点个赞吧😊💓🤪

更多推荐