模板方法模式
Template method pattern defines the sequential steps to execute a multi-step algorithm and optionally can provide a default implementation as well (based on requirements).
特征
- 一系列固定步骤的算法
- 一些步骤是不变的,一些步骤是可变的
- 不变的步骤放在抽象基类实现,可变步骤在具体实现类中实现,步骤的方法声明都在基类
UML 类图
image.png场景
建造一个房子,一般都是有固定步骤的,一些步骤在抽象基类中实现,一些特殊的步骤在具体的特殊房子中实现。
不变步骤
- 房子打地基
- 房子建造屋顶
可变步骤
- 建造房子的墙
- 建造窗户和门
- 房子粉刷
- 内部装饰
举例
建造一个玻璃墙的房子和一个混凝土墙的房子
抽象基类
/**
* abstract class House containing template method buildHouse and implementation
* of steps which is same for all types of houses. Those implementations have
* been marked as final.
*/
public abstract class House {
/**
* This is the template method we are discussing. This method should be
* final so that other class can't re-implement and change the order of the
* steps.
*/
public final void buildhouse() {
constructBase();
constructRoof();
constructWalls();
constructWindows();
constructDoors();
paintHouse();
decorateHouse();
}
public abstract void decorateHouse();
public abstract void paintHouse();
public abstract void constructDoors();
public abstract void constructWindows();
public abstract void constructWalls();
/**
* final implementation of constructing roof - final as all type of house
* Should build roof in same manner.
*/
private final void constructRoof() {
System.out.println("Roof has been constructed.");
}
/**
* final implementation of constructing base - final as all type of house
* Should build base/foundation in same manner.
*/
private final void constructBase() {
System.out.println("Base has been constructed.");
}
}
混凝土墙房子
public class ConcreteWallHouse extends House {
@Override
public void decorateHouse() {
System.out.println(“Decorating Concrete Wall House”);
}
@Override
public void paintHouse() {
System.out.println(“Painting Concrete Wall House”);
}
@Override
public void constructDoors() {
System.out.println(“Constructing Doors for Concrete Wall House”);
}
@Override
public void constructWindows() {
System.out.println(“Constructing Windows for Concrete Wall House”);
}
@Override
public void constructWalls() {
System.out.println(“Constructing Concrete Wall for my House”);
}
}
玻璃墙的房子
public class GlassWallHouse extends House {
@Override
public void decorateHouse() {
System.out.println("Decorating Glass Wall House");
}
@Override
public void paintHouse() {
System.out.println("Painting Glass Wall House");
}
@Override
public void constructDoors() {
System.out.println("Constructing Doors for Glass Wall House");
}
@Override
public void constructWindows() {
System.out.println("Constructing Windows for Glass Wall House");
}
@Override
public void constructWalls() {
System.out.println("Constructing Glass Wall for my House");
}
}
使用样例
public class Demo {
public static void main(String[] args) {
System.out.println(“Going to build Concrete Wall House”);
House house = new ConcreteWallHouse();
house.buildhouse();
System.out.println(“Concrete Wall House constructed successfully”);
System.out.println(“********************”);
System.out.println(“Going to build Glass Wall House”);
house = new GlassWallHouse();
house.buildhouse();
System.out.println(“Glass Wall House constructed successfully”);
}
}
设计关键点
- 被 final 修饰的模板方法,实现类不能覆写和改变它的执行顺序
- 在抽象基类中,实现了所有基类固定不变的默认的方法,具体实现类中,不需要实现固定不变的抽象基类的方法
- 所有抽象基类的抽象方法,在具体实现类中,必须实现
普遍应用
- Non-abstract methods of
InputStream
,OutputStream
,Reader
,Writer
from Java IO. - Non-abstract methods of some abstract collection classes like
AbstractList
,AbstractSet
,AbstractMap
etc. -
BaseExecutor
Class of Mybatis ,基于缓存和事务组件,提供了查询数据库的模板方法。
网友评论