简介
1.模板方法你是(Template Method Pattern) 又叫模板模式 (Template Pattern)在一个抽象类公开定义了执行它的方法的模板.他的子类可以按照需求重写方法实现,但是调用将以抽象类中定义的方式进行
2.简单说,模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构,就可以重新定义该算法的某些特定的步骤
3.这种设计模式属于行为型模式
豆浆制作的问题,说明如下
1.制作豆浆的流程 选材料 -> 添加配料 -> 浸泡 -> 放到豆浆机打碎
2.通过添加不同的配料,可以制作不同的口味的豆浆
3.选材.浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的
4.请使用模板方法方式完成(说明:以为内模板方式比较简单,很容易就想到这个方法)
模板方法模式的原理类图
说明
1.AbstractClass:抽象类 类中实现了模板方法 定义了算法的框架,具体子类需要去实现 求他的抽象方法 op...2 3 4
2.ConcreteClass 实现抽象方法 op...2 3 4 已完成算法中的特定子类的步骤
案例实现
1.程序说明如上
2.类图说明
3.代码实现
//抽象类,表示豆浆
public abstract class SoyaMilk {
// 模板方法 可以定义为 final
final void make() {
select();
addCodiments();
soak();
beat();
}
// 选材料
void select() {
System.out.println("第一步:选择材料");
}
// 添加不同的配料 子类具体实现
abstract void addCodiments();
// 浸泡
void soak() {
System.out.println("第三步:黄豆和配料开始浸泡,需要3小时");
}
void beat() {
System.out.println("第四部:黄豆和豆浆一起做");
}
}
public class RedBeanSoyaMilk extends SoyaMilk{
@Override
void addCodiments() {
System.out.println("加入上好的红豆");
}
}
public class PeanutSoyaMilk extends SoyaMilk {
@Override
void addCodiments() {
System.out.println("增加上好的花生");
}
}
public class Client {
public static void main(String[] args) {
//制作红豆豆浆
System.out.println("====制作红豆豆浆====");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("====制作花生豆浆====");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
}
}
测试
====制作红豆豆浆====
第一步:选择材料
加入上好的红豆
第三步:黄豆和配料开始浸泡,需要3小时
第四部:黄豆和豆浆一起做
====制作花生豆浆====
第一步:选择材料
增加上好的花生
第三步:黄豆和配料开始浸泡,需要3小时
第四部:黄豆和豆浆一起做
模板方法模式中的钩子方法
1.在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事情,子类视情况要不要覆盖他,该方法称为钩子
2.还是用上面做豆浆的例子来讲解,比如,我们希望制作纯豆浆,不添加任何的配料,请使用钩子方法对前面的模板方法进行改造
3.代码演示
修改 SoyaMilk.java 添加钩子方法
//抽象类,表示豆浆
public abstract class SoyaMilk {
// 模板方法 可以定义为 final
final void make() {
select();
if (customerWantCondiments()) {
addCodiments();
}
soak();
beat();
}
// 选材料
void select() {
System.out.println("第一步:选择材料");
}
// 添加不同的配料 子类具体实现
abstract void addCodiments();
// 浸泡
void soak() {
System.out.println("第三步:黄豆和配料开始浸泡,需要3小时");
}
void beat() {
System.out.println("第四部:黄豆和豆浆一起做");
}
// 钩子方法 决定是否需要添加配料
boolean customerWantCondiments() {
return true;
}
}
添加一个类 纯豆浆
public class PureSoyaMilk extends SoyaMilk{
@Override
void addCodiments() {
//啥都不要
//空实现
}
@Override
boolean customerWantCondiments() {
return false;
}
}
测试
public class Client {
public static void main(String[] args) {
//制作红豆豆浆
System.out.println("====制作红豆豆浆====");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("====制作花生豆浆====");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
System.out.println("====制作纯豆浆====");
//制作纯豆浆
PureSoyaMilk milk = new PureSoyaMilk();
milk.make();
}
}
====制作红豆豆浆====
第一步:选择材料
加入上好的红豆
第三步:黄豆和配料开始浸泡,需要3小时
第四部:黄豆和豆浆一起做
====制作花生豆浆====
第一步:选择材料
增加上好的花生
第三步:黄豆和配料开始浸泡,需要3小时
第四部:黄豆和豆浆一起做
====制作纯豆浆====
第一步:选择材料
第三步:黄豆和配料开始浸泡,需要3小时
第四部:黄豆和豆浆一起做
模板方法模式在 Spring框架应用的分析
1.Spring IOC 容器初始化的时候运用到了模板方法模式
模板方法模式的注意事项和细节
1.基本思想是:算法只存在与一个地方,也就是父类中,容易修改 需要修改算法的时候,只需要修改父类的模板方法或者是已经实现的某些步骤,子类就会继承这些修改
2.实现了最大优化代码复用父类的模板方法和已经实现的某些步骤会被子类继承而直接使用
3.既统一算法,也提供很大的灵活性父类的模板方法确保了算法的结构保持不变.同时有子类提供部分算法的实现
4.该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统变得庞大
5.一本模板方法都加上 fianl关键字,防止子类重写模板方法
6.模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤,这一些列步骤基本相同但是个别步骤实现的时候可能不相同,通常考虑模板方法模式处理