无场景,不设计,有这样的一个需求:有一个小贩需要制作豆浆,制作豆浆的流程如下:
请使用 模板方法模式 完成 废话不多说,直接步入正题。
操作中的算法的骨架
,而将一些步骤延迟到子类
中,使得子类可以不改变一个算法结构,就可以重新定义该算法的某些特定步骤说明
好了接下来使用应用案例来进行理解一下吧。
说明如下:
类图
代码演示
public abstract class SoyaMilk {
//模板方法, make , 模板方法可以做成final , 不让子类去覆盖.
final void make() {
select();
addCondiments();
soak();
beat();
}
//选材料
void select() {
System.out.println("第一步:选择好的新鲜黄豆 ");
}
//添加不同的配料, 抽象方法, 子类具体实现
abstract void addCondiments();
//浸泡
void soak() {
System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 ");
}
void beat() {
System.out.println("第四步:黄豆和配料放到豆浆机去打碎 ");
}
}
public class RedBeanSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println(" 加入上好的红豆 ");
}
}
public class PeanutSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println(" 加入上好的花生 ");
}
}
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//制作红豆豆浆
System.out.println("----制作红豆豆浆----");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("----制作花生豆浆----");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
}
}
//抽象类,表示豆浆
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;
}
}
public class PureSoyaMilk extends SoyaMilk{
@Override
void addCondiments() {
// TODO Auto-generated method stub
//空实现
}
@Override
boolean customerWantCondiments() {
// TODO Auto-generated method stub
return false;
}
}
(红豆豆浆)和(花生豆浆)不变
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("----制作纯豆浆----");
SoyaMilk pureSoyaMilk = new PureSoyaMilk();
pureSoyaMilk.make();
}
}
以上就是模板方法模式的基本概念以及应用案例的展示,不知道是否对模板方法模式有更好的一个理解。接下来给大家讲解一下模板方法模式在Spring源码中的应用。
Spring IOC容器初始化时运用到的模板方法模式
ConfigurableApplicationContext
这个类,它里面有一个非常重要的方法Refresh
方法,这是一个抽象的方法,AbstractApplicationContext
AbstractApplicationContext
这个类里面就有refresh()
方法由此可见refresh()
就是一个模板方法
AbstractApplicationContext
这个类中的refresh()
方法中还有一个obtainFreshBeanFactory()
方法。obtainFreshBeanFactory()
方法发现里面有refreshBeanFactory()
和getBeanFactory()
这两个方法,refreshBeanFactory()``getBeanFactory()
这两个方法发现它们是当前类的抽象方法(会被它的子类去实现)GenericApplicationContext
中有实现 refreshBeanFactory()``getBeanFactory()
这两个方法我们继续查看Refresh()
方法是否有钩子方法
postProcessBeanFactory()
方法,发现这是一个``空方法`。它的意义就是让子类覆盖它,确定其就是一个钩子方法onRefresh()
也是一个钩子方法说了这么多不知是不是有点蒙呢。用图形总结一下吧: