工廠模式:
什么叫工廠模式,工廠就是大家大腦里想的那樣,一個流水線作業的一個東西,只需要滿足剛需就可以了,一個人,只干一件事,最后串起來,就是一個事件。
首先需要說一下工廠模式。工廠模式根據抽象程度的不同分為三種:
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
簡單工廠:
簡單工廠說白了,就是需要想到你要干什么,要分幾步做,把每個事件全都擺出來,完咯,開始着手建廠,在廠里把你想干的事情,全都分列清除,把條件弄好,好知道來需求的時候,知道哪些人干活。最后就是客戶提的需求了,根據需求去辦事。
代碼案例:
/** * 寶馬 */ var Baoma = function () { this.play = function () { console.log('我在造寶馬'); } } /** * 奧迪 */ var Aodi = function () { this.play = function () { console.log('我在造奧迪'); } } //造寶馬事件 var baoma = new Baoma(); // 運行造寶馬事件 baoma.play(); // 造奧迪事件 var aodi = new Aodi(); // 運行造奧迪事件 aodi.play(); /** * 造小汽車工廠 */ var Ball = function(name) { switch (name) { case '寶馬': return new Baoma(); break; case '奧迪': return new Aodi(); break; } } // 客戶需求要寶馬 var baoma = Ball('寶馬'); // 來開造 baoma.play(); // 客戶需要奧迪 var aodi = Ball('奧迪'); //來開造 aodi.play();
工廠方法:
工廠方法說白了就是在工廠里面去寫方法,在外部寫一個公用的方法去調取工廠的獨有方法,來實現客戶的需求
代碼如下:
// 安全模式創建工廠類 var Ball = function (type,name) { // 判斷實例是否屬於ball if(this instanceof Ball) { var s = new this[type](name); console.log(s) return s; }else { return; } } // 工廠原型中設置創建所有類型數據對象的基類 Ball.prototype = { baoma: function(name) { this.play = function() { console.log('我在生產'+name); } }, aodi: function(name) { this.play = function() { console.log('我在建造'+name); } }, } // 客戶需求 var baoma = new Ball('baoma','寶馬'); // 開始建造 baoma.play(); // 客戶需求 var aodi = new Ball('aodi','奧迪'); // 開始建造 aodi.play(); /* baoma {play: ƒ} 我在建造寶馬 aodi {play: ƒ} 我在生產奧迪 */
對比簡單模式和方法模式,方法模式的代碼,要比簡單工廠模式的代碼要少的多,最后只需要在工廠里面去添加方法,去調用就行了,不要再往開發零件區去填寫內容了。
抽象工廠:
抽象工廠,說白了比較抽象的,說是抽象,其實看着也差不多應改,在開始的時候建一個工廠,里面去判斷這個方法,有這個方法的時候就開始繼承,指向,繼承,最后運行事件,感覺代碼老多了,不易理解,要建一個私有類,完咯在工廠中找到這個類,取到類的值,用值去跑建造方法。最后當然就是需求的提交,和程序的運行了
// # 抽象工廠模式 var Sport = function(subType, superType) { if( typeof Sport[superType] === 'function'){ // 緩存類 function F() {}; // 繼承父類屬性和方法 F.prototype = new Sport[superType](); // 將子類constructor 指向子類 subType.constructor = subType; // 子類原型繼承 “父類” subType.prototype = new F(); }else { // 不存在抽象類則拋出錯誤 throw new Error('未創建該抽象類'); } } // 寶馬抽象類 Sport.baoma = function () { this.type = 'baoma'; } Sport.baoma.prototype = { play: function () { return new Error('抽象方法不能調用'); } } // 奧迪抽象類 Sport.aodi = function () { this.type = 'aodi'; } Sport.aodi.prototype = { play: function () { return new Error('抽象方法不能調用'); } } // 大眾抽象類 Sport.dazhong = function () { this.type = 'dazhong'; } Sport.dazhong.prototype = { play: function () { return new Error('抽象方法不能調用'); } } // 寶馬類 var BasketBall = function (name) { this.name = name; }; // 抽象工廠實現對寶馬的繼承 Sport(BasketBall,'baoma'); BasketBall.prototype.play = function () { console.log('我在造'+this.name); } // 奧迪類 var WeightLifting = function (name) { this.name = name; }; // 抽象工廠實現對奧迪的繼承 Sport(WeightLifting,'aodi'); WeightLifting.prototype.play = function () { console.log('我在造'+this.name); } // 大眾類 var Running = function (name) { this.name = name; }; // 抽象工廠實現對大眾的繼承 Sport(Running,'dazhong'); Running.prototype.play = function () { console.log('我在造'+this.name); } // 抽象工廠模式實現 var basketBall = new BasketBall('寶馬'); console.log(basketBall.type);//baoma basketBall.play(); var weightLifting = new WeightLifting('奧迪'); console.log(weightLifting.type);//aodi weightLifting.play(); var running = new Running('大眾'); console.log(running.type);//ball running.play(); /** 輸出結果 * baoma * 我在造寶馬 * aodi * 我在造奧迪 * dazhong * 我在造大眾 */
在vue項目中使用,大家熟悉的莫過於路由了,其實路由頁面的代碼就應該算是一個簡單工廠,但沒有那些復雜的方法,
import Vue from 'vue' import Router from 'vue-router' import MainTab from '@/views/MainTab' import PersonRegister from '@/views/PersonRegister' Vue.use(Router) export default new Router({ routes: [ { // 根目錄 path: '/', component: MainTab, redirect:'/PersonRegister', children: [ { // 人員登記 path: '/PersonRegister', name: 'PersonRegister', component: PersonRegister }, { // 簽到表詳情 path: '/InterviewSigin', name: 'InterviewSigin', component: () => import('@/views/InterviewSigin') }, { // 邀約人頁面 path: '/inviteApproval', name: 'inviteApproval', component: () => import('@/views/inviteApproval') }, { // 刪除統計 path: '/DeleteCount', name: 'DeleteCount', component: () => import('@/views/DeleteCount') }, { // 離場統計 path: '/DepartureCount', name: 'DepartureCount', component: () => import('@/views/DepartureCount') }, { // 簽到表 path: '/SiginManage', name: 'SiginManage', component: () => import('@/views/SiginManage') } ] } ] })
在上面的代碼中就可以看出來,他的子路由就是一塊一塊的,就好比是工廠模式的上面的每一方法一樣,我也不知道這樣嵌套這說對不對,我感覺差不多吧,你想添加頁面的話,只需要在里面寫一個子路由就行了。
抽象工廠模式的優點:
-
當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象。
-
增加新的具體工廠和產品族很方便,無須修改已有系統,符合“開閉原則”。
抽象工廠模式的缺點:
-
開閉原則的傾斜性(增加新的工廠和產品族容易,增加新的產品等級結構麻煩)。
-
增加新的產品等級結構:對於增加新的產品等級結構,需要修改所有的工廠角色,包括抽象工廠類,在所有的工廠類中都需要增加生產新產品的方法,不能很好地支持“開閉原則”。
抽象工廠模式的適用情況:
在以下情況下可以使用抽象工廠模式:
-
一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有類型的工廠模式都是重要的。
-
系統中有多於一個的產品族,而每次只使用其中某一產品族。
屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。 -
系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現。
抽象工廠模式總結
-
抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則需要面對多個產品等級結構。
-
抽象工廠模式適用情況包括:一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節;系統中有多於一個的產品族,而每次只使用其中某一產品族;屬於同一個產品族的產品將在一起使用;系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現。