设计模式之模板模式
1. 模板方法模式
1.1 定义
模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,但将一些步骤延迟到子类中实现。这种模式允许你定义一个算法的基础结构,并且可以由子类来重写某些特定步骤而不会改变算法的结构。模板模式的核心思想是封装变化的部分,提供扩展点,使得子类能够以不同的方式实现这些变化部分。
模板模式的关键组件
- 抽象类:定义了模板方法以及一系列基本操作方法。
- 模板方法:定义了算法的骨架,通常是一个 final 方法,防止子类覆盖。
- 基本操作:这些方法可以是抽象的,也可以有默认实现,供子类选择性地覆盖。
- 钩子方法:提供一种方式让子类对算法的某个步骤进行控制或修改。它们通常是空操作或者具有默认行为的方法。
- 具体类:继承自抽象类,实现或重写基本操作和/或钩子方法,从而定制算法的具体细节。
1.2 使用场景
- 当你的多个类有相似的行为,只有少数步骤不同。
- 当你想为通用算法提供一个框架,同时允许子类自定义算法的某些步骤。
- 当你需要在不改变算法结构的情况下,支持多种不同的执行方式。
1.3 优点
- 封装了不变部分的代码,提高了代码复用性。
- 提高了代码的可维护性,因为公共部分的更改只需要在父类中进行。
- 通过将相同的代码移动到超类,减少了代码重复。
1.4 缺点
- 每个不同的实现都需要一个新的子类,这可能会导致系统中类的数量增加。
- 如果父类添加新的抽象方法,所有子类可能需要相应地更新,这可能导致大量的代码改动。
1.5 代码示例
①定义抽象类
public abstract class DataViewer {
/**
* 抽象方法:获取数据
*/
public abstract void GetData();
/**
* 具体方法:转换数据
*/
public void ConvertData() {
System.out.println("将数据转换为XML格式。");
}
/**
* 抽象方法:显示数据
*/
public abstract String DisplayData();
/**
* 钩子方法:判断是否为XML格式的数据
*
* @return
*/
public boolean IsNotXMLData() {
return true;
}
/**
* 模板方法
*/
public String Process() {
GetData();
//如果不是XML格式的数据则进行数据转换
if (IsNotXMLData()) {
ConvertData();
}
return DisplayData();
}
}
②具体子类实现
public class CsvDataViewer extends DataViewer{
@Override
public void GetData() {
System.out.println("get csv data");
}
@Override
public String DisplayData() {
System.out.println("display csv data");
return "csv";
}
@Override
public void ConvertData() {
System.out.println("将数据转换为csv格式。");
}
@Override
public String Process() {
GetData();
//如果不是XML格式的数据则进行数据转换
if (IsNotXMLData()) {
ConvertData();
}
return DisplayData();
}
}
public class XMLDataViewer extends DataViewer{
@Override
public void GetData() {
System.out.println("get xml data");
}
@Override
public String DisplayData() {
System.out.println("display xml data");
return "xml";
}
@Override
public boolean IsNotXMLData() {
return false;
}
}
③client调用
public class Client {
public static void main(String[] args) {
DataViewer dv;
//dv = new XMLDataViewer();
dv = new CsvDataViewer();
System.out.println(dv.Process());
}
}