什么是模板方法冰沙?即讓工作或流程順序按照寫好的模板進(jìn)行下去,同時(shí)還可以自定義流程,以及簡(jiǎn)化流程。
舉例:沖泡茶和咖啡均分四步進(jìn)行:
- 把水煮沸
- 沖泡咖啡(茶)
- 把咖啡(茶)倒入杯子
- 加糖(檸檬)
一般寫法
咖啡類
public class Coffee {
public void prepare() {
/**
* 制作咖啡:
* 1港庄。 把水煮沸
* 2倔既。 用水沖泡
* 3。 把咖啡倒進(jìn)杯子
* 4鹏氧。 加糖
*/
boilWater();
brewCoffee();
pourInCup();
addSuger();
}
public void boilWater() {
System.out.println("把水煮沸");
}
public void brewCoffee() {
System.out.println("用水沖泡咖啡");
}
public void pourInCup() {
System.out.println("把咖啡倒進(jìn)杯子");
}
public void addSuger() {
System.out.println("加糖");
}
}
茶類
public class Tea {
public void prepare() {
/**
* 制作茶:
* 1渤涌。 把水煮沸
* 2。 用水沖泡
* 3把还。 把茶倒進(jìn)杯子
* 4实蓬。 加檸檬
*/
boilWater();
pourInCup();
pourInCup();
addLemon();
}
public void boilWater() {
System.out.println("把水煮沸");
}
public void brewTea() {
System.out.println("用水沖泡茶");
}
public void pourInCup() {
System.out.println("把茶倒進(jìn)杯子");
}
public void addLemon() {
System.out.println("加檸檬");
}
}
測(cè)試類
public class Test01 {
/**
* 這種實(shí)現(xiàn)方式有很多重復(fù)的代碼
*/
public static void main(String[] args) {
Coffee coffee = new Coffee();
Tea tea = new Tea();
coffee.prepare();
System.out.println("---------------");
tea.prepare();
}
}
模板方法
定義抽象的模板方法,把公共方法抽離出來笨篷,其它交給子類去實(shí)現(xiàn)
public abstract class DrinksTemplate {
/**
* 設(shè)定為final,不讓子類去覆蓋或篡改流程
*/
final public void prepare() {
boilWater();
brew();
pourInCup();
add();
}
public void boilWater() {
System.out.println("把水煮沸");
}
/**
* 交給子類實(shí)現(xiàn)
*/
public abstract void brew();
public void pourInCup() {
System.out.println("把飲料倒進(jìn)杯子");
}
public abstract void add();
}
咖啡類
public class Coffee extends DrinksTemplate {
@Override
public void brew() {
System.out.println("用沸水沖泡咖啡");
}
@Override
public void add() {
System.out.println("加糖");
}
}
茶類
public class Tea extends DrinksTemplate {
@Override
public void brew() {
System.out.println("用沸水沖泡茶");
}
@Override
public void add() {
System.out.println("加檸檬");
}
}
測(cè)試類
public class Test01 {
public static void main(String[] args) {
Coffee coffee = new Coffee();
Tea tea = new Tea();
coffee.prepare();
System.out.println("-----------");
tea.prepare();
}
}
使用鉤子函數(shù)
鉤子函數(shù)是在抽象模板方法中定義的瓣履,它的作用就是控制流程中的某個(gè)步驟是否執(zhí)行率翅、簡(jiǎn)化流程,子類可以選擇覆蓋袖迎。比如冕臭,在準(zhǔn)備給用戶沖泡咖啡或茶之前詢問用戶是否需要加糖或者檸檬,不需要就不進(jìn)行加糖或檸檬這一步驟了燕锥。
抽象模板方法
public abstract class DrinksTemplate {
/**
* 設(shè)定為final辜贵,不讓子類去覆蓋或篡改流程
*/
final public void prepare() {
boilWater();
brew();
pourInCup();
if (ifAdd()) {
add();
}
}
public void boilWater() {
System.out.println("把水煮沸");
}
/**
* 交給子類實(shí)現(xiàn)
*/
public abstract void brew();
public void pourInCup() {
System.out.println("把飲料倒進(jìn)杯子");
}
public abstract void add();
/**
* 鉤子函數(shù)
*/
public Boolean ifAdd() {
return true;
}
}
只讓茶類去覆蓋鉤子函數(shù)
@Data
public class Tea extends DrinksTemplate {
private Boolean ifAdd;
@Override
public void brew() {
System.out.println("用沸水沖泡茶");
}
@Override
public void add() {
System.out.println("加檸檬");
}
@Override
public Boolean ifAdd() {
return ifAdd;
}
}
測(cè)試類
@SuppressWarnings("Duplicates")
public class Test01 {
public static void main(String[] args) {
Coffee coffee = new Coffee();
Tea tea = new Tea();
// 啟用鉤子函數(shù)
tea.setIfAdd(false);
coffee.prepare();
System.out.println("==========");
tea.prepare();
}
}
測(cè)試結(jié)果
把水煮沸
用沸水沖泡咖啡
把飲料倒進(jìn)杯子
加糖
==========
把水煮沸
用沸水沖泡茶
把飲料倒進(jìn)杯子