模板方法模式(Template Method Pattern),在父类中定义了一个模板方法,和一系列抽象方法,模板方法中调用了一系列抽象方法,而这些抽象方法的实现放到了子类当中实现。
而在子类中,不能改变这个模板方法,只能实现父类定义的抽象方法,这就相当于在子类中,能赋予自己的不同行为和细节,但是父类的模板方法,规定了每个子类都要执行这样一组方法。也就是约定了总体行为,具体行为则各自实现。
比如,我们每个人每天上班的过程如下:
7点起床,吃早饭—》乘坐交通工具上班—》完成上午的工作—》吃午饭—》完成下午的工作—》乘坐交通工具下班—》吃晚饭
我们每个人的上班生活,差不多是这样,总结一下就是:
吃早饭—>上班—>吃午饭—>下班—>吃晚饭
我们都要吃早饭,但是每个人吃的早饭各不相同,张三早上吃油条,李四早上吃面条,所以映射成代码就相当于:
模板方法定义了一天的生活
void dailyLife() {
breakfast();//吃早饭
goOnTransport();//上班
lunch();//吃午饭
goOffTransport();//下班
dinner();//吃晚饭
}
这写方法则是抽象方法,等待子类取实现自己的行为。
我们来具体看代码:
1、定义抽象类,定义了模板方法和每天各种要做的事情
package com.itzhimei.study.design.template;
/**
* www.itzhimei.com
* 定义了每天生活的模板
*/
public abstract class AbstractTemplateDailyLife {
/**
* 定义了每天生活的模板
* 每个人都要吃早饭、上班、吃午饭、下班、吃晚饭
*/
public final void dailyLife() {
System.out.println("----------------------------");
breakfast();
goOnTransport();
lunch();
goOffTransport();
dinner();
System.out.println("----------------------------");
}
/**
* 早饭
*/
abstract void breakfast();
/**
* 上班方式--乘坐哪种交通工具
*/
abstract void goOnTransport();
/**
* 午饭
*/
abstract void lunch();
/**
* 下班方式--乘坐哪种交通工具
*/
abstract void goOffTransport();
/**
* 晚饭
*/
abstract void dinner();
}
2、定义了张三和李四每天的生活,张三class和李四class继承了抽象父类
package com.itzhimei.study.design.template;
/**
* 张三的日常生活
*/
public class PersonA extends AbstractTemplateDailyLife {
@Override
void breakfast() {
System.out.println("张三早饭吃面包");
}
@Override
void goOnTransport() {
System.out.println("张三骑自行车上班");
}
@Override
void lunch() {
System.out.println("张三午饭吃盖饭");
}
@Override
void goOffTransport() {
System.out.println("张三骑自行车下班");
}
@Override
void dinner() {
System.out.println("张三晚饭吃饺子");
}
}
package com.itzhimei.study.design.template;
/**
* 李四的日常生活
*/
public class PersonB extends AbstractTemplateDailyLife {
@Override
void breakfast() {
System.out.println("李四早饭吃油条");
}
@Override
void goOnTransport() {
System.out.println("李四上班坐地铁");
}
@Override
void lunch() {
System.out.println("李四午饭吃面条");
}
@Override
void goOffTransport() {
System.out.println("李四下班坐地铁");
}
@Override
void dinner() {
System.out.println("李四晚饭吃披萨");
}
}
3、测试
package com.itzhimei.study.design.template;
/**
* www.itzhimei.com
* 模板方法模式--测试
*/
public class Client {
public static void main(String[] args) {
AbstractTemplateDailyLife zhangsan = new PersonA();
AbstractTemplateDailyLife lisi = new PersonA();
//我们看看张三和李四的日常生活
zhangsan.dailyLife();
lisi.dailyLife();
}
}
输出结果:
----------------------------
张三早饭吃面包
张三骑自行车上班
张三午饭吃盖饭
张三骑自行车下班
张三晚饭吃饺子
----------------------------
----------------------------
张三早饭吃面包
张三骑自行车上班
张三午饭吃盖饭
张三骑自行车下班
张三晚饭吃饺子
----------------------------
涉及角色:
1、抽象角色:声明了模板方法和需要子类实现的抽象方法。
2、具体角色:继承了抽象类,实现了抽象方法,定义了自己的行为。
类关系图:
![](https://www.itzhimei.com/wp-content/uploads/2020/07/image-12.png)
总结:
模板方法模式定义一个算法骨架,将一些具体实现推迟到子类中实现,模板方法可以使子类在不改变算法结构和逻辑的情况下,赋予新的行为。