模板模式
介绍:
先定义某件事的步骤,不同的人根据自己的情况来实现不同的操作,比如说早上起床步骤是起床,穿衣服,刷牙,洗脸,穿鞋,同样的步骤不同的人可能穿衣服就需要比其他人多一些时间,刷牙也可能比其他人少一些时间,这就是模板方法模式。
主要解决:一些方法通用,却在每一个子类都重新写了这一方法。
何时使用:有一些通用的方法。
如何解决:将这些通用算法抽象出来。
关键代码:在抽象类实现,其他步骤在子类实现。
优点:
1、封装不变部分,扩展可变部分。
2、提取公共代码,便于维护。
3、行为由父类控制,子类实现。
缺点:
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
使用场景:
1、有多个子类共有的方法,且逻辑相同。
2、重要的、复杂的方法,可以考虑作为模板方法。
注意事项:为防止恶意操作,一般模板方法都加上 final 关键词。
起床模板:
package com.example.maybatissource.template_pattern;
/**
* 起床
*/
public abstract class GetUp {
//穿衣服
public abstract void getDressed();
//刷牙
public abstract void toothBrushing();
//洗脸
public abstract void washMyFace();
//穿鞋
public abstract void shoes();
//模板
public final void template(){
getDressed();
toothBrushing();
washMyFace();
shoes();
}
}
package com.example.maybatissource.template_pattern;
/**
* 张三起床
*/
public class Zhangsan extends GetUp {
@Override
public void getDressed() {
System.out.println("张三穿衣服穿了1分钟");
}
@Override
public void toothBrushing() {
System.out.println("张三刷牙刷了2分钟");
}
@Override
public void washMyFace() {
System.out.println("张三洗脸洗了3分钟");
}
@Override
public void shoes() {
System.out.println("张三穿鞋30秒");
}
}
package com.example.maybatissource.template_pattern;
/**
* 李四起床
*/
public class Lisi extends GetUp{
@Override
public void getDressed() {
System.out.println("李四穿衣服穿了1分钟");
}
@Override
public void toothBrushing() {
System.out.println("李四刷牙刷了2分钟");
}
@Override
public void washMyFace() {
System.out.println("李四洗脸洗了3分钟");
}
@Override
public void shoes() {
System.out.println("李四穿鞋30秒");
}
}
package com.example.maybatissource.template_pattern;
public class main {
public static void main(String[] args) {
GetUp zhangsan = new Zhangsan();
zhangsan.template();
System.out.println("---------------------------------------");
GetUp lisi = new Lisi();
lisi.template();
}
}
这里有点小问题穿衣服这里,穿不穿外套这是看个人的。这里我们就使用钩子函数。
钩子函数:
钩子就是给子类一个授权,让子类来决定模板方法的逻辑执行。我们去实现一下:
/**
* 起床
*/
public abstract class GetUp {
//穿衣服
public abstract void getDressed();
//穿外套
public abstract void wearJacket();
//刷牙
public abstract void toothBrushing();
//洗脸
public abstract void washMyFace();
//穿鞋
public abstract void shoes();
//是否穿外套
public boolean wearJacketBoolean () {
return false;
}
//模板
public final void template(){
getDressed();
//子类决定是否穿外套
if (this.wearJacketBoolean()) {
wearJacket();
}
toothBrushing();
washMyFace();
shoes();
}
}
/**
* 张三起床
*/
public class Zhangsan extends GetUp {
private boolean wearJacket = false;
public void setWearJacketBoolean (Boolean wearJacket) {
this.wearJacket = wearJacket;
}
public boolean wearJacketBoolean () {
return this.wearJacket;
}
@Override
public void getDressed() {
System.out.println("张三穿衣服穿了1分钟");
}
@Override
public void wearJacket() {
System.out.println("穿外套");
}
@Override
public void toothBrushing() {
System.out.println("张三刷牙刷了2分钟");
}
@Override
public void washMyFace() {
System.out.println("张三洗脸洗了3分钟");
}
@Override
public void shoes() {
System.out.println("张三穿鞋30秒");
}
}
/**
* 李四起床
*/
public class Lisi extends GetUp{
@Override
public void getDressed() {
System.out.println("李四穿衣服穿了1分钟");
}
@Override
public void wearJacket() {
System.out.println("穿外套");
}
@Override
public void toothBrushing() {
System.out.println("李四刷牙刷了2分钟");
}
@Override
public void washMyFace() {
System.out.println("李四洗脸洗了3分钟");
}
@Override
public void shoes() {
System.out.println("李四穿鞋30秒");
}
}
package com.example.maybatissource.template_pattern;
public class main {
public static void main(String[] args) {
// GetUp zhangsan = new Zhangsan();
// zhangsan.template();
Zhangsan zhangsan = new Zhangsan();
zhangsan.setWearJacketBoolean(true);
zhangsan.template();
System.out.println("---------------------------------------");
GetUp lisi = new Lisi();
lisi.template();
}
}