Java設(shè)計(jì)模式 模板模式及應(yīng)用場(chǎng)景解析
模板模式,顧名思義,就是通過(guò)模板拓印的方式。
定義模板,就是定義框架、結(jié)構(gòu)、原型。定義一個(gè)我們共同遵守的約定。
定義了模板,我們的剩余工作就是對(duì)其進(jìn)行充實(shí)、豐潤(rùn),完善它的不足之處。
定義模板采用抽象類(lèi)來(lái)定義,公共的結(jié)構(gòu)化邏輯需要在抽象類(lèi)中完成,只將非公共的部分邏輯抽象成抽象方法,留待子類(lèi)充實(shí)實(shí)現(xiàn)。
所以上文所述不足之處就是這些抽象方法。
總的來(lái)說(shuō),模板模式就是通過(guò)抽象類(lèi)來(lái)定義一個(gè)邏輯模板,邏輯框架、邏輯原型,然后將無(wú)法決定的部分抽象成抽象類(lèi)交由子類(lèi)來(lái)實(shí)現(xiàn),一般這些抽象類(lèi)的調(diào)用邏輯還是在抽象類(lèi)中完成的。這么看來(lái),模板就是定義一個(gè)框架,比如蓋房子,我們定義一個(gè)模板:房子要封閉,有門(mén),有窗等等,但是要什么樣的門(mén),什么樣的窗,這些并不在模板中描述,這個(gè)交給子類(lèi)來(lái)完善,比如門(mén)使用防盜門(mén),窗使用北向的窗等等。
我們不凡就以建房為例來(lái)見(jiàn)識(shí)一下模板模式如何:
模板抽象類(lèi):HouseTemplate
public abstract class HouseTemplate { protected HouseTemplate(String name){ this.name = name; } protected String name; protected abstract void buildDoor(); protected abstract void buildWindow(); protected abstract void buildWall(); protected abstract void buildBase(); //公共邏輯 public final void buildHouse(){ buildBase(); buildWall(); buildDoor(); buildWindow(); } }
子類(lèi)1:HouseOne
public class HouseOne extends HouseTemplate { HouseOne(String name){ super(name); } @Override protected void buildDoor() { System.out.println(name +"的門(mén)要采用防盜門(mén)"); } @Override protected void buildWindow() { System.out.println(name + "的窗戶要面向北方"); } @Override protected void buildWall() { System.out.println(name + "的墻使用大理石建造"); } @Override protected void buildBase() { System.out.println(name + "的地基使用鋼鐵地基"); } }
子類(lèi)2:HouseTwo
public class HouseTwo extends HouseTemplate { HouseTwo(String name){ super(name); } @Override protected void buildDoor() { System.out.println(name + "的門(mén)采用木門(mén)"); } @Override protected void buildWindow() { System.out.println(name + "的窗戶要向南"); } @Override protected void buildWall() { System.out.println(name + "的墻使用玻璃制造"); } @Override protected void buildBase() { System.out.println(name + "的地基使用花崗巖"); } }
測(cè)試類(lèi):Clienter
public class Clienter { public static void main(String[] args){ HouseTemplate houseOne = new HouseOne("房子1"); HouseTemplate houseTwo = new HouseTwo("房子2"); houseOne.buildHouse(); houseTwo.buildHouse(); } }
測(cè)試結(jié)果
房子1的地基使用鋼鐵地基 房子1的墻使用大理石建造 房子1的門(mén)要采用防盜門(mén) 房子1的窗戶要面向北方 房子2的地基使用花崗巖 房子2的墻使用玻璃制造 房子2的門(mén)采用木門(mén) 房子2的窗戶要向南
通過(guò)以上例子,我們認(rèn)識(shí)了模板模式中的基本方法和模板方法,其中HouseTemplate中的buildHouse方法就是基本方法,其余四個(gè)均為模板方法。其中基本方法一般會(huì)用final修飾,保證其不會(huì)被子類(lèi)修改,而模板方法則使用protected修飾,表明其需要在子類(lèi)中實(shí)現(xiàn)。
其實(shí),模板模式中還有一個(gè)鉤子方法的概念,有人稱(chēng),具有鉤子方法的模板模式才算完整,也許吧。
鉤子方法時(shí)干啥的呢?鉤子就是給子類(lèi)一個(gè)授權(quán),允許子類(lèi)通過(guò)重寫(xiě)鉤子方法來(lái)顛覆基本邏輯的執(zhí)行,這有時(shí)候是非常有用的。就比如在蓋房子的時(shí)候,有一個(gè)需要子類(lèi)來(lái)決定是否建造廁所間的需求時(shí),可以這么實(shí)現(xiàn):
模板抽象類(lèi):HouseTemplate
public abstract class HouseTemplate { protected HouseTemplate(String name){ this.name = name; } protected String name; protected abstract void buildDoor(); protected abstract void buildWindow(); protected abstract void buildWall(); protected abstract void buildBase(); protected abstract void buildToilet(); //鉤子方法 protected boolean isBuildToilet(){ return true; } //公共邏輯 public final void buildHouse(){ buildBase(); buildWall(); buildDoor(); buildWindow(); if(isBuildToilet()){ buildToilet(); } } }
子類(lèi)1:HouseOne
public class HouseOne extends HouseTemplate { HouseOne(String name){ super(name); } HouseOne(String name, boolean isBuildToilet){ this(name); this.isBuildToilet = isBuildToilet; } public boolean isBuildToilet; @Override protected void buildDoor() { System.out.println(name +"的門(mén)要采用防盜門(mén)"); } @Override protected void buildWindow() { System.out.println(name + "的窗戶要面向北方"); } @Override protected void buildWall() { System.out.println(name + "的墻使用大理石建造"); } @Override protected void buildBase() { System.out.println(name + "的地基使用鋼鐵地基"); } @Override protected void buildToilet() { System.out.println(name + "的廁所建在東南角"); } @Override protected boolean isBuildToilet(){ return isBuildToilet; } }
子類(lèi)2:HouseTwo
public class HouseTwo extends HouseTemplate { HouseTwo(String name){ super(name); } @Override protected void buildDoor() { System.out.println(name + "的門(mén)采用木門(mén)"); } @Override protected void buildWindow() { System.out.println(name + "的窗戶要向南"); } @Override protected void buildWall() { System.out.println(name + "的墻使用玻璃制造"); } @Override protected void buildBase() { System.out.println(name + "的地基使用花崗巖"); } @Override protected void buildToilet() { System.out.println(name + "的廁所建在西北角"); } }
測(cè)試類(lèi):Clienter
public class Clienter { public static void main(String[] args){ HouseTemplate houseOne = new HouseOne("房子1", false); HouseTemplate houseTwo = new HouseTwo("房子2"); houseOne.buildHouse(); houseTwo.buildHouse(); } }
測(cè)試結(jié)果
房子1的地基使用鋼鐵地基 房子1的墻使用大理石建造 房子1的門(mén)要采用防盜門(mén) 房子1的窗戶要面向北方 房子2的地基使用花崗巖 房子2的墻使用玻璃制造 房子2的門(mén)采用木門(mén) 房子2的窗戶要向南 房子2的廁所建在西北角
通過(guò)直接結(jié)果我們可以清晰的看到,我們通過(guò)重寫(xiě)鉤子方法自定義了房子1不需要建造廁所(fasle)。
鉤子方法的作用也就一目了然啦。
模板模式的關(guān)鍵點(diǎn):
1、使用抽象類(lèi)定義模板類(lèi),并在其中定義所有的基本方法、模板方法,鉤子方法,不限數(shù)量,以實(shí)現(xiàn)功能邏輯為主。其中基本方法使用final修飾,其中要調(diào)用基本方法和鉤子方法,基本方法和鉤子方法可以使用protected修飾,表明可被子類(lèi)修改。
2、定義實(shí)現(xiàn)抽象類(lèi)的子類(lèi),重寫(xiě)其中的模板方法,甚至鉤子方法,完善具體的邏輯。
使用場(chǎng)景:
1、在多個(gè)子類(lèi)中擁有相同的方法,而且邏輯相同時(shí),可以將這些方法抽出來(lái)放到一個(gè)模板抽象類(lèi)中。
2、程序主框架相同,細(xì)節(jié)不同的情況下,也可以使用模板方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot thymeleaf模板引擎的使用詳解
這篇文章主要介紹了Spring Boot thymeleaf模板引擎的使用詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03SpringMVC自定義攔截器登錄檢測(cè)功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了SpringMVC自定義攔截器登錄檢測(cè)功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08mybatis中映射文件include標(biāo)簽的應(yīng)用
這篇文章主要介紹了mybatis中映射文件include標(biāo)簽的應(yīng)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11java開(kāi)發(fā)validate方法中校驗(yàn)工具類(lèi)詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)validate方法中校驗(yàn)工具類(lèi)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Java設(shè)計(jì)模式詳解之門(mén)面模式(外觀模式)
為子系統(tǒng)中的一組接口提供一個(gè)一致的界面, Facade 模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。本文給大家介紹Java設(shè)計(jì)模式詳解之門(mén)面模式(外觀模式),感興趣的朋友參考下吧2016-04-04Spring中BeanUtils.copyProperties的坑及解決
這篇文章主要介紹了Spring中BeanUtils.copyProperties的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09SpringBootTest單元測(cè)試報(bào)錯(cuò)的解決方案
這篇文章主要介紹了SpringBootTest單元測(cè)試報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09