模板方法模式和JDBCTemplate(一)
本篇博客的目錄:
一:模板方法模式介紹
二:模板方法模式的簡單實現
三:總結
一:模板方法模式的介紹
1.1:模板方法模式的定義
定義:一個操作中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
這句話的意思就是我們先定義一套固定的規則標準,然後讓不確定的方法設置為抽象的,等到具體的實現時候,讓子類再去實現。先設置好一套規則,定義好一套業務流程,再去具體實現。這就是模板方法。這和我們現實生活的許多做法有很多異曲同工之處,比如我們新職員入公司、去銀行辦理業務等等,它們都預先定制好了一套流程,我們要做的就是按照這個流程往下走,就可以完成這件事情。
1.2:結構以及介紹:
其中可以看到有一個抽象類,裏面定義了幾個操作方法和一個模板方法,然後具體的子類再去繼承這個類,實現父類中尚未實現的方法。這其中還涉及一個概念,鉤子方法,也稱作回調函數(這個概念在jdbcTempalte中很常見).它的提出和模板方法設計的精髓很很大關聯,抽象類中的抽象方法就是鉤子,我們需要哪個掛哪個,再具體的去實現。
1.3:簡單代碼實現
為了讓這個更具有說服力,我們來模擬一個流程,公司招聘新員工的業務流程。假如我現在要去公司應聘啦,公司肯定預先定制好了一套流程,我們用代碼來仿照一下這個流程:
1.3.1:Company這個類定義為抽象類,我們預定了一系列的求職流程,求職者投遞簡歷,決定是否通過,這裏屬於具體的實現細節,交給子類去實現。如果通過才能繼續下面的流程,否則無法通過。然後就是會見求職者,筆試-面試,公司是否能讓該求職者通過屬於具體的子類實現細節,所以定義抽象方法isAccess(),只有在考慮錄用的情況下才會發放offer,代碼實現如下:
public abstract class Company { public static int score1=0; public static int score2=0; public void TemplateMethod(Jober jober){ if (Isreceive(jober)){ viewJober(jober); examination1(jober); examination2(jober); if (isAccess(jober)){ offer(jober); }else { System.out.println("很遺憾"+jober.getName()+"尚未通過本公司面試"); } }else { System.out.println(jober.getName()+"的簡歷不合格"); } } /** * 是否接受簡歷 * @return */ public abstract boolean Isreceive(Jober jober); /** * 會見求職者 * @param jober */ public void viewJober(Jober jober){ System.out.println("面試者會見求職者"+jober.getName()); } /** *筆試 * @param jober * @return */ public int examination1(Jober jober){ score1= jober.exam1(); return score1; } /** * 面試 * @param jober * @return */ public int examination2(Jober jober){ score2 = jober.exam2(); return score2; } /** * 考慮求職者是否能進入公司 * @param jober * @return */ public abstract boolean isAccess(Jober jober); /** * 發放offer * @param jober */ public void offer(Jober jober){ System.out.println("恭喜"+jober.getName()+"通過本公司的面試,現在發布offer"); } }
1.3.2:我們來定義一個具體的子類,去實現公司求職這個抽象父類,重寫他的抽象方法,實現自己的邏輯:
public class AiLBaba extends Company { @Override public boolean Isreceive(Jober jober) { if ("Yrion".equals(jober.getName())) { System.out.println(jober.getName() + "通過本公司簡歷篩選"); return true; }else return false; } @Override public boolean isAccess(Jober jober) { if (score1+score2 > 150) return true; return false; } }
可以看到,我們只需要繼承抽象的方法就行,這裏的具體實現邏輯自己來決定,而整個求職過程不會變更,這也是模板方法的主要原則:
1.3.3 我們來定義一個求職者對象,主要作用就是調用求職公司的模板方法,發起一個流程:
public class Jober { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } public int exam1() { System.out.println(name + "正在筆試..."); return 88; } public int exam2() { System.out.println(name + "正在面試..."); return 90; } public void getJob(Company company){ company.TemplateMethod(this); } }
1.3.4:根據現實的規則,求職者應該是主動發起的,我們通過getJob方法向公司發起求職動作,公司已經預設好一系列的流程了,進而轉為我們預先設計的模板流程中。好了,我們來建個測試類,運行這個小demo,看一下結果如何:
public class Test { public static void main(String[] args) { Company aLi =new AiLBaba(); Jober jober=new Jober(); jober.setName("Yrion"); jober.getJob(aLi); } }
運行結果如下:
Yrion通過本公司簡歷篩選
面試者會見求職者Yrion
Yrion正在筆試...
Yrion正在面試...
恭喜Yrion通過本公司的面試,現在發布offer
我們再來做個測試,假如尚未通過簡歷初選:
public class Test { public static void main(String[] args) { Company aLi =new AiLBaba(); Jober jober=new Jober(); jober.setName("周星星"); jober.getJob(aLi); } }
運行結果如下:
周星星的簡歷不合格
我們再來測試一下,假如簡歷通過,但是筆試面試尚未通過,只需要改這兩處代碼就行了:
public int exam1() { System.out.println(name + "正在筆試..."); return 60; } public int exam2() { System.out.println(name + "正在面試..."); return 60; }
我們再來測試一下:
Yrion通過本公司簡歷篩選
面試者會見求職者Yrion
Yrion正在筆試...
Yrion正在面試...
很遺憾Yrion尚未通過本公司面試
這個小實例就完成了,希望大家可以體會到模板方法的設計思想,進而將它運用到項目中去。這是個小實例,比較簡單,接下來我們將會把目光轉向更為復雜的Spring中的JDBCTemplate
三:總結
本篇博客講解了Template設計模式,它的主要目標是減少工作量,把固定不變的步驟提取出來形成一個模板,然後具體的可變的部分再交給子類去實現,方便於日後的擴展,主要的適用性如下:
- 一次性實現一個算法的不變的部分,並將可變的行為留給子類來實現。
- 各子類中公共的行為應被提取出來並集中到一個公共父類中以避免代碼重復。首先識別現有代碼中的不同之處,並且將不同之處分離為新的操作。最後,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
- 控制子類擴展。模板方法只在特定點調用,這樣就只允許在這些點進行擴展。
預告:下篇博客,將會深入了解JDBCTempalte的設計源碼
模板方法模式和JDBCTemplate(一)