模板方法模式¶
模板方法它适用于一整个业务的逻辑大体是固定不变的,好多地方都在用,但是某一天突然有一个需求, 和这个逻辑几乎一样,但是又有一些细节不同,那为了避免代码重复,保证以后也可以新增代码时不大面积改动代码, 就可以考虑模板方法模式。它可以使代码复用,可以控制扩展,易于维护,但是会限制子类的灵活性,还使得代码变复杂。
🏀代码样例¶
平时使用豆浆机时,我们的第一步都是选择新鲜的豆子,然后将豆子和配料开始浸泡3H,最后将豆子和配料放入豆浆机榨汁就行了。 但是放啥配料,放不放配料,都会改变具体步骤。
public abstract class SoyaMilk {
/*
* 模板方法:可以做成final,不让子类去覆盖
*/
final void make() {
select();
if (customerWantCondiment()) {
addCondiment();
}
soak();
beat();
}
// 1️⃣选材料
void select() {
System.out.println("第一步:选择新鲜的豆子");
}
// 2️⃣第二步:添加不同的配料:抽象方法,由子类具体实现
abstract void addCondiment();
// 3️⃣浸泡
void soak() {
System.out.println("第三步:豆子和配料开始浸泡3H");
}
// 4️⃣榨汁
void beat() {
System.out.println("第四步:豆子和配料放入豆浆机榨汁");
}
// 钩子方法:决定是否需要添加配料
boolean customerWantCondiment() {
// 默认情况下是要加配料的, 那些需要配料的豆浆品种就不需要覆写
return true;
}
}
这时候大家的步骤都是一样的,如何体现个性呢?我们去实现一下这个类,一样的步骤就不重写了, addCondiment()是决定每个子类差异的方法,也可以有多个。
其中模板类里面的钩子🪝方法可以看情况去除。
🐔使用方式¶
使用的时候,直接做豆浆就可以了,放到spring框架里面就是交给容器管理用到就注入
public class Client {
public static void main(String[] args) {
System.out.println("=======制作红豆豆浆=======");
SoyaMilk redBeanSoyaMilk = new ReadBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("=======制作花生豆浆=======");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
System.out.println("=======制作原味豆浆=======");
OriginalSoyaMilk originalSoyaMilk = new OriginalSoyaMilk();
originalSoyaMilk.make();
System.out.println("=======制作咖啡豆浆=======");
CoffeeSoyalMilk coffeeSoyalMilk = new CoffeeSoyalMilk();
coffeeSoyalMilk.make();
}
}
=======制作红豆豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的红豆
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作花生豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的花生
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作原味豆浆=======
第一步:选择新鲜的豆子
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作咖啡豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的花生
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入咖啡机做咖啡,举个例子🌰而已