Java設(shè)計(jì)模式模板方法模式(Template)用法解析
這篇文章主要介紹了Java設(shè)計(jì)模式模板方法模式(Template)用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
前言:
我們?cè)陂_(kāi)發(fā)中有很多固定的流程,這些流程有很多步湊是固定的,比如JDBC中獲取連接,關(guān)閉連接這些流程是固定不變的,變動(dòng)的只有設(shè)置參數(shù),解析結(jié)果集這些是根據(jù)不同的實(shí)體對(duì)象“來(lái)做調(diào)整”,針對(duì)這種擁有固定算法流程,其中有固定的步湊,存在不固定的步湊的情況下就誕生了模板方法模式。
模板方法模式(Template)定義:
模板方法模式又叫模板模式,指的是父類(lèi)定義了一個(gè)多步湊的算法骨架,其中很多步湊是在父類(lèi)中實(shí)現(xiàn)了的,有的步湊是根據(jù)不同的子類(lèi)擁有不同的實(shí)現(xiàn),就把這些“不確定”的實(shí)現(xiàn)步湊定義為抽象方法交給子類(lèi)去實(shí)現(xiàn)。模板模式的核心就是在使子類(lèi)不改變算法結(jié)構(gòu)的情況下,重新定義算法的某些步湊。屬于行為型設(shè)計(jì)模式。
應(yīng)用很廣發(fā),比如Mybatis中的BaseExecutor;Spring中的JdbcTemplate;Spring集成Hibernate中的HibernateTemplate,Spring集成各種Mq的Template,還有MongodbTemplate等......
模式中的角色:
抽象類(lèi)(AbstractClass):實(shí)現(xiàn)了模板方法,定義了算法的骨架。
具體類(lèi) (Concrete):實(shí)現(xiàn)了抽象類(lèi)中抽象放,使得父類(lèi)定義的算法更完整。
代碼實(shí)現(xiàn):
1:用抽象類(lèi)定義流程,比如我們每天上班有個(gè)流程: 開(kāi)機(jī)-->寫(xiě)代碼(不同的程序員可能寫(xiě)不同的代碼-->關(guān)機(jī); 整個(gè)流程中開(kāi)機(jī)和關(guān)機(jī)是相同的,只是寫(xiě)代碼這個(gè)步湊不同,java程序員寫(xiě)java代碼,Php程序員寫(xiě)Php代碼; 我們先用一個(gè)抽象的父類(lèi)定義這個(gè)流程:
public abstract class Work {
//定義算法步湊流程
public void workDay(){
//1:上班開(kāi)機(jī)
openComputer();
//2:搬磚:寫(xiě)代碼
coding();
//3:下班關(guān)機(jī) closeComputer();
}
//開(kāi)機(jī)
private final void openComputer() {
System.out.println("到達(dá)公司,開(kāi)機(jī)");
}
//寫(xiě)代碼
protected abstract void coding();
//關(guān)機(jī)
private final void closeComputer() {
System.out.println("下班,關(guān)機(jī)");
}
}
2:具體實(shí)現(xiàn)
Java程序員
public class JavaProgrammer extends Work {
@Override
protected void coding() {
System.out.println("Java程序員打開(kāi)Idea,寫(xiě)Java代碼。。。");
}
}
PHP程序員
public class PhpProgrammer extends Work {
@Override
protected void coding() {
System.out.println("PHP程序員打開(kāi)Zend Studio,寫(xiě)Php代碼。。。");
}
}
3:使用
public class TemplateMethodDemo {
public static void main(String[] args) {
Work javaProgrammer = new JavaProgrammer();
javaProgrammer.workDay();
System.out.println("================");
Work phpProgrammer = new PhpProgrammer();
phpProgrammer.workDay();
}
}
運(yùn)行結(jié)果

模板模式在源碼中的體現(xiàn):
1:我們每天都在使用的HttpServlet里面的service方法,service方法里面定義了調(diào)用流程,根據(jù)客戶(hù)端調(diào)用的不同方式,if else邏輯判斷調(diào)用不同的方法,比如doGet,doPost,doDelete等實(shí)現(xiàn)restful調(diào)用,具體的doGet,doPost方法實(shí)現(xiàn)我們可以在我們自己定義的Servlet中進(jìn)行重寫(xiě)。

2:Mybatis框架中也有一些經(jīng)典實(shí)用,比如BaseExecutor類(lèi),它是一個(gè)基礎(chǔ)的SQL執(zhí)行類(lèi),實(shí)現(xiàn)了大部分SQL的執(zhí)行邏輯,然后把幾個(gè)方法教給子類(lèi)定制化完成,源碼如下:


其中doUpdate(),doFlushStatements(),doQuery(),doQueryCursor()等方法都是由子類(lèi)來(lái)實(shí)現(xiàn)的,BaseExecutor有那些子類(lèi)呢?我們來(lái)看一下他的類(lèi)圖:

我們可以去看看具體每個(gè)子類(lèi)的不同的實(shí)現(xiàn)。
模板模式的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1:利用模板模式可以將相同處理邏輯的代碼放到抽象父類(lèi)中,提高了代碼的復(fù)用性。
2:將不同的邏輯放到不同的子類(lèi)中,通過(guò)子類(lèi)的擴(kuò)展增加新的行為,提高了代碼的擴(kuò)展性。
3:把不變的行為寫(xiě)在父類(lèi)中,去除了子類(lèi)的重復(fù)代碼,提供了一個(gè)很好的代碼復(fù)用平臺(tái),符合開(kāi)閉原則。
4:公司的高級(jí)工程師或者架構(gòu)師在項(xiàng)目前期可以利用模板模式定義好流程,讓其他編碼功工程師去實(shí)現(xiàn)具體。
缺點(diǎn):
1:每個(gè)抽象類(lèi)都需要至少一個(gè)子類(lèi)來(lái)實(shí)現(xiàn),導(dǎo)致了類(lèi)數(shù)量的增加。
2:類(lèi)數(shù)量增加間接增加了系統(tǒng)的復(fù)雜性。
3:因?yàn)槔^承關(guān)系的自身缺點(diǎn),如果父類(lèi)添加一個(gè)新的抽象方法,素有子類(lèi)都要實(shí)現(xiàn)一遍。
代碼鏈接:https://gitee.com/ganganbobo/gps-parent
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ApiOperation和ApiParam注解依賴(lài)的安裝和使用以及注意事項(xiàng)說(shuō)明
這篇文章主要介紹了ApiOperation和ApiParam注解依賴(lài)的安裝和使用以及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
java long轉(zhuǎn)String +Codeforces110A案例
這篇文章主要介紹了java long轉(zhuǎn)String +Codeforces110A案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
使用springboot對(duì)linux進(jìn)行操控的方法示例
這篇文章主要介紹了使用springboot對(duì)linux進(jìn)行操控的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
springboot+Vue實(shí)現(xiàn)分頁(yè)的示例代碼
本文主要介紹了springboot+Vue實(shí)現(xiàn)分頁(yè)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
Spring使用@Autowired注解實(shí)現(xiàn)自動(dòng)裝配方式
這篇文章主要介紹了Spring使用@Autowired注解實(shí)現(xiàn)自動(dòng)裝配方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
java8 多個(gè)list對(duì)象用lambda求差集操作
這篇文章主要介紹了java8 多個(gè)list對(duì)象用lambda求差集操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
Java使用for循環(huán)解決經(jīng)典的雞兔同籠問(wèn)題示例
這篇文章主要介紹了Java使用for循環(huán)解決經(jīng)典的雞兔同籠問(wèn)題,結(jié)合實(shí)例形式分析了Java巧妙使用流程控制語(yǔ)句for循環(huán)解決雞兔同籠問(wèn)題相關(guān)操作技巧,需要的朋友可以參考下2018-05-05
Java連接MYSQL數(shù)據(jù)庫(kù)的詳細(xì)步驟
這篇文章主要為大家介紹了Java連接MYSQL數(shù)據(jù)庫(kù)的詳細(xì)步驟,感興趣的小伙伴們可以參考一下2016-05-05

