先看一段代碼:java
public static void main(String[] args) { // TODO Auto-generated method stub long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { System.out.println("x"); } long end = System.currentTimeMillis(); System.out.println(end-start); }
求程序運行時間的代碼,對於初學者來講這就算完成了,可是咱們是有經驗的開發人員(kidding),這段代碼不符合萬物皆對象的思想,將這段代碼抽象到類中的代碼以下:設計模式
public static void main(String[] args) { GetTime gt = new GetTime(); gt.getTime(); } } class GetTime{ public void getTime() { long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); System.out.println(end-start); } public void code() { for (int i = 0; i < 10000; i++) { System.out.println("x"); } } }
這樣,面向對象的思想就有了,可是這裏面還存在問題,code方法被寫死,若是要測試其餘的代碼顯得不那麼靈活,這時能夠考慮引進子類,在子類中去修改code方法。ide
public static void main(String[] args) { Demo d = new Demo(); d.getTime(); } } abstract class GetTime{ public final void getTime() { long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); System.out.println(end-start); } public abstract void code(); } //延遲到子類中去實現 class Demo extends GetTime{ @Override public void code() { for (int i = 0; i < 10000; i++) { System.out.println("x"); } } }
將父類抽象,只在父類中定義方法,延遲到子類中去實現,代碼修改變得靈活。之因此叫作模板方法設計模式是由於在把計算開始時間和結束時間固定,中間添加代碼,不管中間怎麼添加都是這個模板,就像作磚頭同樣先找來模具,中間添加不一樣的材料就能作成不一樣的磚。學習
說一下缺點,能夠看到若是要增長方法須要在父類中修改代碼,咱們學習任何一種模式都是爲了使開發更靈活,因此要取其精華,拋棄他缺點的一面,利用友好的一面。測試
補充一下這個final,被final修飾是爲了避免讓子類去重寫getTime方法,重寫了就沒辦法測出運行時間。final修飾的類不能被繼承,final修飾的方法不能被重寫,final不能與abstract同時出現,被final修飾的變量不能改變。這很好理解,final至關於定義一個不變的東西,而繼承須要定義更強大的子類,至關於改變了,抽象方法或者類都須要重寫抽象方法設計