模板方法模式id钩子方法
- 在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为"钩子"
- 还是用上面做豆浆的例子来讲解,比如,我们还希望制作纯豆浆,不添加任何的配料,请使用钩子方法对其那面的模板方法进行改造
代码改进
package com.atguigu.template.improve;
public abstract class SoyaMilk {
// 模板方法,make,模板方法可以做成final,不让子类去覆盖
final void make() {
// 第一步
select();
if (customerWantCondiments()) {
addCondiments();
}
soak();
beat();
}
// 选材料
void select() {
System.out.println("第一步: 选择好的新鲜黄豆");
}
// 添加不同的配料,抽象方法,子类具体实现
abstract void addCondiments();
// 浸泡
void soak() {
System.out.println("第三部,黄豆和配料开始浸泡,需要3小时");
}
//
void beat() {
System.out.println("第四部,黄豆和配料放到豆浆机去打碎!");
}
// 钩子方法,决定是否添加配料
boolean customerWantCondiments() {
// 默认返回
return true;
}
}
package com.atguigu.template.improve;
public class PeanutSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("第二步 加入上号的花生!");
}
}
package com.atguigu.template.improve;
public class RedBeanSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("第二步 加入上号的红豆");
}
}
这里加上
package com.atguigu.template.improve;
public class PureSoyaMilk extends SoyaMilk{
@Override
void addCondiments() {
// 空实现
}
@Override
boolean customerWantCondiments() {
// 重写这个地方
return false;
}
}
客户端
package com.atguigu.template.improve;
public class Client {
public static void main(String[] args) {
System.out.println("---------");
// 制作红豆豆浆
System.out.println("----制作红豆豆浆----");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("----制作花生豆浆----");
SoyaMilk peanutSoyMilk = new PeanutSoyaMilk();
peanutSoyMilk.make();
System.out.println("----制作纯豆浆----");
SoyaMilk pureSoyMilk = new PureSoyaMilk();
pureSoyMilk.make();
/**
* ---------
* ----制作红豆豆浆----
* 第一步: 选择好的新鲜黄豆
* 第二步 加入上号的红豆
* 第三部,黄豆和配料开始浸泡,需要3小时
* 第四部,黄豆和配料放到豆浆机去打碎!
* ----制作花生豆浆----
* 第一步: 选择好的新鲜黄豆
* 第二步 加入上号的花生!
* 第三部,黄豆和配料开始浸泡,需要3小时
* 第四部,黄豆和配料放到豆浆机去打碎!
* ----制作纯豆浆----
* 第一步: 选择好的新鲜黄豆
* 第三部,黄豆和配料开始浸泡,需要3小时
* 第四部,黄豆和配料放到豆浆机去打碎!
*
* Process finished with exit code 0
*/
}
}
钩子方法,他可以轻松的实现,哪一个方法在你的模板中要不要调用