一:什麼是模板方法模式:
模板方法模式由二部分組成,第一部分是抽象父類,第二部分是具體實現的子類,一般的情況下是抽象父類封裝了子類的演算法框架,包括實現一些公共方法及封裝子類中所有方法的執行順序,子類可以繼承這個父類,並且可以在子類中重寫父類的方法,從而實現自己的業務邏輯。
比如說我們要實現一個JS功能,比如表單驗證等js,那麼如果我們沒有使用上一章講的使用javascript中的策略模式來解決表單驗證封裝程式碼,而是自己寫的臨時表單驗證功能,肯定是沒有進行任何封裝的,那麼這個時候我們是針對兩個值是否相等給使用者彈出一個提示,如果再另外一個頁面也有一個表單驗證,他們判斷的方式及業務邏輯基本相同的,只是比較的引數不同而已,我們是不是又要考慮寫一個表單驗證程式碼呢?那麼現在我們可以考慮使用模板方法模式來解決這個問題;公用的方法提取出來,不同的方法由具體的子類是實現。這樣設計程式碼也可擴充套件性更強,程式碼更優等優點~
我們不急著寫程式碼,我們可以先來看一個列子,比如最近經常在qq群裡面有很多前端招聘的資訊,自己也接到很多公司或者獵頭問我是否需要找工作等電話,當然我現在是沒有打算找工作的,因為現在有更多的業餘時間可以處理自己的事情,所以也覺得蠻不錯的~ 我們先來看看招聘中面試這個流程;面試流程對於很多大型公司,比如BAT,面試過程其實很類似;因此我們可以總結面試過程中如下:
- 筆試:(不同的公司有不同的筆試題目)。
- 技術面試(一般情況下分為二輪):第一輪面試你的有可能是你未來直接主管或者未來同事問你前端的一些專業方面的技能及以前做過的專案,在專案中遇到哪些問題及當時是如何解決問題的,還有根據你的簡歷上的基本資訊來交流的,比如說你簡歷說精通JS,那麼人家肯定得問哦~ 第二輪面試一般都是公司的牛人或者架構師來問的,比如問你計算機基本原理,或者問一些資料結構與演算法等資訊;第二輪面試可能會更深入的去了解你這個人的技術。
- HR和總監或者總經理面試;那麼這一輪的話,HR可能會問下你一些個人基本資訊等情況,及問下你今後有什麼打算的個人規劃什麼的,總監或者總經理可能會問下你對他們的網站及產品有了解過沒有?及現在他們的產品有什麼問題,有沒有更好的建議或者如何改善的地方等資訊;
- 最後就是HR和你談薪資及一般幾個工作日可以得到通知,拿到offer(當然不符合的肯定是沒有通知的哦);及自己有沒有需要了解公司的情況等等資訊;
一般的面試過程都是如上四點下來的,對於不同的公司都差不多的流程的,當然有些公司可能沒有上面的詳細流程的,我這邊這邊講一般的情況下,好了,這邊就不扯了,這邊也不是講如何面試的哦,這邊只是通過這個列子讓我們更加的理解javascript中模板方法模式;所以我們現在回到正題上來;
我們先來分析下上面的流程;我們可以總結如下:
首先我們看一下百度的面試;因此我們可以先定義一個建構函式。
var BaiDuInterview = function(){};
那麼下面就有百度面試的流程哦~
- 筆試
那麼我們可以封裝一個筆試的方法,程式碼如下:
// baidu 筆試 BaiDuInterview.prototype.writtenTest = function(){ console.log("我終於看到百度的筆試題了~"); };
2. 技術面試:
// 技術面試 BaiDuInterview.prototype.technicalInterview = function(){ console.log("我是百度的技術負責人"); };
3. HR和總監或者總經理面試,我們可以稱之為leader面試;程式碼如下:
// 領導面試 BaiDuInterview.prototype.leader = function(){ console.log("百度leader來面試了"); };
4. 和HR談期望的薪資待遇及HR會告訴你什麼時候會有通知,因此我們這邊可以稱之為這個方法為 是否拿到offer(當然不符合要求肯定是沒有通知的哦);
// 等通知 BaiDuInterview.prototype.waitNotice = function(){ console.log("百度的人力資源太不給力了,到現在都不給我通知"); };
如上看到程式碼的基本結構,但是我們還需要一個初始化方法;程式碼如下:
// 程式碼初始化 BaiDuInterview.prototype.init = function(){ this.writtenTest(); this.technicalInterview(); this.leader(); this.waitNotice(); }; var baiDuInterview = new BaiDuInterview(); baiDuInterview.init();
綜合所述:所有的程式碼如下:
var BaiDuInterview = function(){}; // baidu 筆試 BaiDuInterview.prototype.writtenTest = function(){ console.log("我終於看到百度的題目筆試題了~"); }; // 技術面試 BaiDuInterview.prototype.technicalInterview = function(){ console.log("我是百度的技術負責人"); }; // 領導面試 BaiDuInterview.prototype.leader = function(){ console.log("百度leader來面試了"); }; // 等通知 BaiDuInterview.prototype.waitNotice = function(){ console.log("百度的人力資源太不給力了,到現在都不給我通知"); }; // 程式碼初始化 BaiDuInterview.prototype.init = function(){ this.writtenTest(); this.technicalInterview(); this.leader(); this.waitNotice(); }; var baiDuInterview = new BaiDuInterview(); baiDuInterview.init();
上面我們可以看到百度面試的基本流程如上面的程式碼,那麼阿里和騰訊的也和上面的程式碼類似(這裡就不一一貼一樣的程式碼哦),因此我們可以把公用程式碼提取出來;我們首先定義一個類,叫面試Interview
那麼程式碼改成如下:
var Interview = function(){};
- 筆試:
我不管你是百度的筆試還是阿里或者騰訊的筆試題,我這邊統稱為筆試(WrittenTest),那麼你們公司有不同的筆試題,都交給子類去具體實現,父類方法不管具體如何實現,筆試題具體是什麼樣的 我都不管。程式碼變為如下:
// 筆試 Interview.prototype.writtenTest = function(){ console.log("我終於看到筆試題了~"); };
2. 技術面試,技術面試原理也一樣,這裡就不多說,直接貼程式碼:
// 技術面試 Interview.prototype.technicalInterview = function(){ console.log("我是技術負責人負責技術面試"); };
3. 領導面試
// 領導面試 Interview.prototype.leader = function(){ console.log("leader來面試了"); };
4. 等通知
// 等通知 Interview.prototype.waitNotice = function(){ console.log("人力資源太不給力了,到現在都不給我通知"); };
程式碼初始化方法如下:
// 程式碼初始化 Interview.prototype.init = function(){ this.writtenTest(); this.technicalInterview(); this.leader(); this.waitNotice(); };
二:建立子類
現在我們來建立一個百度的子類來繼承上面的父類;程式碼如下:
var BaiDuInterview = function(){}; BaiDuInterview.prototype = new Interview();
現在我們可以在子類BaiDuInterview 重寫父類Interview中的方法;程式碼如下:
// 子類重寫方法 實現自己的業務邏輯 BaiDuInterview.prototype.writtenTest = function(){ console.log("我終於看到百度的筆試題了"); } BaiDuInterview.prototype.technicalInterview = function(){ console.log("我是百度的技術負責人,想面試找我"); } BaiDuInterview.prototype.leader = function(){ console.log("我是百度的leader,不想加班的或者業績提不上去的給我滾蛋"); } BaiDuInterview.prototype.waitNotice = function(){ console.log("百度的人力資源太不給力了,我等的花兒都謝了!!"); } var baiDuInterview = new BaiDuInterview(); baiDuInterview.init();
如上看到,我們直接呼叫子類baiDuInterview.init()方法,由於我們子類baiDuInterview沒有init方法,但是它繼承了父類,所以會到父類中查詢對應的init方法;所以會迎著原型鏈到父類中查詢;對於其他子類,比如阿里類程式碼也是一樣的,這裡就不多介紹了,對於父類這個方法 Interview.prototype.init() 是模板方法,因為他封裝了子類中演算法框架,它作為一個演算法的模板,指導子類以什麼樣的順序去執行程式碼。
Javascript中的模板模式使用場景
雖然在java中也有子類實現父類的介面,但是我認為javascript中可以和java中不同的,java中可能父類就是一個空的類,子類去實現這個父類的介面,在javascript中我認為完全把公用的程式碼寫在父函式內,如果將來業務邏輯需要更改的話,或者說新增新的業務邏輯,我們完全可以使用子類去重寫這個父類,這樣的話程式碼可擴充套件性強,更容易維護。由於本人不是專業java的,所以描述java中的知識點有誤的話,請理解~~