一、定義
定義一個(gè)操作中的算法骨架搓蚪,而將算法的一些步驟延遲到子類中像寒,使得子類可以不改變該算法結(jié)構(gòu)的情況下重定義該算法的某些特定步驟。它是一種類行為型模式誓焦。
主要角色:
抽象類:負(fù)責(zé)給出一個(gè)算法的輪廓或骨架羔巢,它由一個(gè)模板方法和若干個(gè)基本方法構(gòu)成。
- 模板方法:定義了算法的骨架,按某種順序調(diào)用其包含的基本方法竿秆。
- 具體方法:是實(shí)現(xiàn)算法各個(gè)步驟的方法启摄,是模板方法的組成部分,基本方法又分為三種:
- 抽象方法:一個(gè)抽象方法由抽象類聲明幽钢,由具體子類實(shí)現(xiàn)
- 具體方法:一個(gè)具體方法由一個(gè)抽象類或具體類聲明并實(shí)現(xiàn)歉备,其子類可以進(jìn)行覆蓋也可以直接繼承。
- 鉤子方法:在抽象類中已經(jīng)實(shí)現(xiàn)匪燕,包括用于判斷的邏輯方法和需要子類重寫的空方法兩種蕾羊。
具體子類:實(shí)現(xiàn)抽象類中所定義的抽象方法和鉤子方法,它們是一個(gè)頂級邏輯的組成步驟帽驯。
二龟再、代碼實(shí)現(xiàn)
舉例:例如去銀行辦理業(yè)務(wù),需要取號尼变,排隊(duì)利凑,辦理具體業(yè)務(wù),對工作人員評分嫌术,其中取號哀澈,排隊(duì),評分三個(gè)步驟不論是誰都是一樣的度气,但是辦理具體業(yè)務(wù)卻因人而異割按,可能是存款,可能是取款磷籍,可以延遲到子類中實(shí)現(xiàn)适荣。
抽象類:
public abstract class AbstractClass {
//模板方法
public void start(){
getNumber();
lineUp();
doSomething();
appraise();
}
//基本方法
public void getNumber(){
System.out.println("銀行取號");
}
public void lineUp(){
System.out.println("銀行排隊(duì)");
}
public void appraise(){
System.out.println("銀行評價(jià)");
}
//抽象方法
public abstract void doSomething();
}
具體子類:辦理存款業(yè)務(wù)
public class Deposit extends AbstractClass {
@Override
public void doSomething() {
System.out.println("辦理存款業(yè)務(wù)");
}
}
使用:
public static void main(String[] args) {
Deposit deposit = new Deposit();
deposit.start();
}
輸出:
銀行取號
銀行排隊(duì)
辦理存款業(yè)務(wù)
銀行評價(jià)
如果此時(shí)想要辦理取款業(yè)務(wù)怎么辦?那么只需要增加一個(gè)子類來完成具體的取款業(yè)務(wù):
具體子類:辦理取款業(yè)務(wù)
public class Withdraw extends AbstractClass {
@Override
public void doSomething() {
System.out.println("辦理取款業(yè)務(wù)");
}
}
三院领、總結(jié)
優(yōu)點(diǎn):提高代碼的復(fù)用性弛矛,將相同部分放在抽象的父類中,不同的代碼放入不同的子類中栅盲。
缺點(diǎn):對于每一個(gè)不同的實(shí)現(xiàn)都需要定義一個(gè)子類汪诉,導(dǎo)致類的數(shù)量增加。
場景:算法的整體步驟很固定谈秫,但其中個(gè)別部分易變時(shí)扒寄,這時(shí)候可以使用模板方法模式,將容易變的部分抽象出來拟烫,由子類實(shí)現(xiàn)该编。或需要通過子類來決定父類算法中某個(gè)步驟是否執(zhí)行硕淑,實(shí)現(xiàn)子類對父類的反向控制课竣。