只有光頭才能變強。java
文本已收錄至個人GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3ygit
在上一篇有讀者說,一分鐘就看完門面模式了,因此今天的標題就取《一分鐘學會模板方法模式》github
回顧前面所寫過的設計模式:面試
不管是面試仍是我的的提高,設計模式是必學的。今天來說解模板方法模式~算法
你們都知道,我每次寫原創技術文章,開頭總會有「只有光頭才能變強」。我固然不可能每次寫文章的時候都去複製這句話(由於這樣太麻煩了)。設計模式
我有本身的寫做模板,給你們看一下:框架
前言和最後都是固定下來的,至於第一點和第二點就得看是寫什麼文章,寫不一樣的文章對應的內容也是不同的。ide
每次我寫文章的時候,只要在這個模板上添加我本身想寫的東西就行了,就不用每次都複製一遍相同的內容,這樣就大大減小個人工做量啦。ui
代碼來源於生活,一樣地我能夠將我寫文章的過程用代碼來描述,你們來看一下。.net
3y每篇文章都會有「前言」和「最後」的內容,3y把這兩個模塊寫出來了。
// 3y的文章模板 public class Java3yWriteArticle { // 前言 public void introduction() { System.out.println("只有光頭才能變強"); } // 最後 public void theLast() { System.out.println("關注個人公衆號:Java3y"); } }
3y寫文章的時候,3y可能就會這樣使用:
// 3y寫文章 public static void main(String[] args) { Java3yWriteArticle writeArticle = new Java3yWriteArticle(); // 前言 writeArticle.introduction(); // 實際內容 System.out.println("你們好,我是3y,今天來給你們分享我寫的模板方法模式"); // 最後 writeArticle.theLast(); }
這樣是能夠完成3y寫文章的功能,可是這樣作好嗎?這時候3y女友也想寫文章,她的文章一樣也想有「前言」和「最後」兩個模塊,因此3y女友的文章模板是這樣的:
// 3y女友的文章模板 public class Java3yGFWriteArticle { // 前言 public void introduction() { System.out.println("balabalabalalabalablablalab"); } // 最後 public void theLast() { System.out.println("balabalabalalabalablablalab"); } }
那3y女友寫文章的時候,可能也會這樣使用:
// 3y女友寫文章 public static void main(String[] args) { Java3yGFWriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle(); // 前言 java3yGFWriteArticle.introduction(); // 實際內容 System.out.println("3y是傻子,不用管他"); // 最後 java3yGFWriteArticle.theLast(); }
能夠發現3y和3y女友要寫文章的時是要重複調用introduction();
和theLast();
。而且,3y的文章模板和3y女友的文章模板中的「前言」和「最後」只是實現內容的不一樣,卻定義了兩次,明顯就是重複的代碼。面對重複的代碼咱們會作什麼?很簡單,抽取出來!
因而咱們就能夠抽取出一個通用的WriteArticle(爲了方便調用,咱們還將寫文章的步驟封裝成一個方法):
// 通用模板 public abstract class WriteArticle { // 每一個人的「前言」都不同,因此抽象(abstract) protected abstract void introduction(); // 每一個人的「最後」都不同,因此抽象(abstract) protected abstract void theLast(); // 實際要寫的內容,每一個人的「實際內容」都不同,因此抽象(abstract) protected abstract void actualContent(); // 寫一篇完整的文章(爲了方便調用,咱們將這幾個步驟分裝成一個方法) public final void writeAnCompleteArticle() { // 前言 introduction(); // 實際內容 actualContent(); // 最後 theLast(); } }
因此,3y的模板就能夠繼承通用模板,在通用模板上實現本身想要的就行了:
// 3y的文章模板 public class Java3yWriteArticle extends WriteArticle { // 前言 @Override public void introduction() { System.out.println("只有光頭才能變強"); } // 最後 @Override public void theLast() { System.out.println("關注個人公衆號:Java3y"); } @Override protected void actualContent() { System.out.println("你們好,我是3y,今天來給你們分享我寫的模板方法模式"); } }
一樣地,3y女友的文章模板也是相似的:
// 3y女友的文章模板 public class Java3yGFWriteArticle extends WriteArticle { // 前言 @Override public void introduction() { System.out.println("balabalabalalabalablablalab"); } // 最後 @Override public void theLast() { System.out.println("balabalabalalabalablablalab"); } @Override protected void actualContent() { System.out.println("3y是傻子,不用管他"); } }
想要真正寫文章的時候就十分方便了:
// 3y寫文章 public static void main(String[] args) { WriteArticle java3ywriteArticle = new Java3yWriteArticle(); java3ywriteArticle.writeAnCompleteArticle(); } // 3y女友寫文章 public static void main(String[] args) { WriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle(); java3yGFWriteArticle.writeAnCompleteArticle(); }
要點:
嗯,上面的就是模板方法模式,就這麼簡單!
《設計模式之禪》:
定義一個操做中的算法框架,而將一些步驟延遲到子類中。使子類能夠不改變一個算法的結構便可重定義該算法的某些步驟。
根據咱們上面的例子,來說講這段話的含義:
好比3y在文章模板中的introduction()
改了,「只有充錢才能變強」
@Override public void introduction() { System.out.println("只有充錢才能變強"); }
咱們沒有碰過writeAnCompleteArticle()的代碼,但再次調用這個方法的時候,具體的實現就會發生改變(由於writeAnCompleteArticle受子類的具體實現影響)
下面咱們看一下模板方法模式的通用類圖:
在模板方法模式中,也有幾個術語,根據咱們的例子中的註釋,我給你們介紹一下:
// 抽象模板類 public abstract class WriteArticle { // 基本方法 protected abstract void introduction(); // 基本方法 protected abstract void theLast(); // 基本方法 protected abstract void actualContent(); // 模板方法 public final void writeAnCompleteArticle() { introduction(); actualContent(); theLast(); } } // 具體模板類 public class Java3yWriteArticle extends WriteArticle { // 實現基本方法 @Override public void introduction() { System.out.println("只有充錢才能變強"); } // 實現基本方法 @Override public void theLast() { System.out.println("關注個人公衆號:Java3y"); } // 實現基本方法 @Override protected void actualContent() { System.out.println("你們好,我是3y,今天來給你們分享我寫的模板方法模式"); } }
優勢:
缺點:
最經典的就是JUC包下的AQS(AbstractQueuedSynchronizer)了。AQS是什麼?
AQS其實就是一個能夠給咱們實現鎖的框架。內部實現的關鍵是:先進先出的隊列、state狀態
咱們能夠看一下AQS定義的acquire()
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
acquire()
至關於模板方法,tryAcquire(arg)
至關於基本方法。
模板方法模式也很簡單呀,一個抽象類有基本方法(等着被子類實現的方法),有模板方法(對外暴露、調用基本方法、定義了算法的框架),那就完事了。
推薦閱讀和參考資料:
樂於分享和輸出乾貨的Java技術公衆號:Java3y。關注便可領取海量的視頻資源!
精彩回顧:
以爲個人文章寫得不錯,不妨點一下贊!