模板方法模式
模板方法模式,定义一个功能的实现流程,封装共有的流程,公开需要不同实现的步骤(方法),使得不同子类在固定整个功能骨架的情况下,来实现统一功能的不同表现
两个角色
- 抽象父类(定义功能的实现流程/步骤)
- 具体实现子类
例子:把不同的东西放入冰箱,总共分三步,打开冰箱门、放东西、关上冰箱门
定义了放东西的三个步骤,私有第一步和第三步,公开第二步给子类来使用,子类不用自己再操作一遍打开冰箱门和关闭冰箱门
- 定义抽象父类
public abstract class AbstractPutSomething2Fridge {
protected final void putSomething2Fridge() {
openTheDoor();
putThing();
closeTheDoor();
}
private void openTheDoor() {
System.out.println("打开冰箱门......");
}
private void closeTheDoor() {
System.out.println("关上冰箱门......");
}
protected void putThing() {
System.out.println("啥也没放......");
}
}
- 定义具体子类-把大象放进冰箱
public class PutElephant2Fridge extends AbstractPutSomething2Fridge {
@Override
protected void putThing() {
System.out.println("把大象放冰箱......");
}
}
- 定义具体子类-把鸭子放进冰箱
public class PutDuck2Fridge extends AbstractPutSomething2Fridge {
@Override
protected void putThing() {
System.out.println("把鸭子放冰箱......");
}
}
- 具体使用
public class Main {
public static void main(String[] args) {
AbstractPutSomething2Fridge elephant = new PutElephant2Fridge();
elephant.putSomething2Fridge();
System.out.println("--------------------------");
AbstractPutSomething2Fridge duck = new PutDuck2Fridge();
duck.putSomething2Fridge();
}
}
- 结果如下
打开冰箱门......
把大象放冰箱......
关上冰箱门......
--------------------------
打开冰箱门......
把鸭子放冰箱......
关上冰箱门......
总结
优点:封装重复代码,减少子类中的重复代码,使子类做的功能更简单、单一
缺点:父类可变的方法增加,会导致子类的增多
补充
钩子方法的使用,定义一些boolean类型返回值的方法,来决定某一步骤是否执行
例子
Tom, Jerry决定去逛街买衣服,Tom缺少衣服,所以他要买,但是Jerry不缺衣服,只是陪着Tom逛街
- 定义抽象父类
public abstract class Shopping {
public void goShopping() {
go();
if (isNecessary()) {
shopping();
} else {
System.out.println("不购物,就是跟着逛");
}
back();
}
private void back() {
System.out.println("回家");
}
protected abstract void shopping();
private void go() {
System.out.println("出发");
}
protected boolean isNecessary() {
return true;
}
}
- 定义两个实现子类Tom和Jerry
public class Tom extends Shopping {
@Override
protected void shopping() {
System.out.println("Tom 去购物");
}
}
public class Jerry extends Shopping{
@Override
protected void shopping() {
System.out.println("Jerry 去购物");
}
@Override
protected boolean isNecessary() {
return false;
}
}
- 具体使用
public class Main {
public static void main(String[] args) {
Shopping tom = new Tom();
tom.goShopping();
System.out.println();
Shopping jerry = new Jerry();
jerry.goShopping();
}
}
- 运行结果
出发
Tom 去购物
回家
出发
不购物,就是跟着逛
回家
这就起到了钩子函数的作用