工廠模式主要是爲了建立對象實例或者類簇(抽象工廠), 關心的是最終產出(建立)的對象, 而不關心建立的過程.javascript
在出現多個類的時候, 每次建立須要找到對應的類每每比較麻煩, 這時候一般使用一個函數進行封裝來建立所須要的對象,
這樣就無需關注建立這些對象到底依賴哪些基類了, 只要知道有這個函數就能夠了, 一般這個函數被稱爲工廠函數,
這種模式叫簡單工廠模式php
假設一體育商品店賣器材, 裏面有不少體育商品, 及其相關介紹. 當你來到體育用品店買一個籃球及相關介紹時,
你只須要問售貨員, 她會幫你找到你所須要的東西.java
// 籃球基類 var Basketball = function() { this.intro = '籃球盛行於美國'; } Basketball.prototype = function() { getMember: function() { console.log('每一個隊伍須要5名隊員'); }, getBallSize: function() { console.log('籃球很大'); } } // 足球基類 var Football = function() { this.intro = '足球在世界範圍內盛行'; } Football.prototype = function() { getMember: function() { console.log('每一個隊伍須要11名隊員'); }, getBallSize: function() { console.log('足球很大'); } } // 網球基類 var Tennis = function() { this.intro = '每一年有不少網球系列賽'; } Tennis.prototype = function() { getMember: function() { console.log('每一個隊伍須要1名隊員'); }, getBallSize: function() { console.log('網球很小'); } } // 運動工廠(這邊至關於諮詢體育器材店的售貨員, 告訴她你想要買什麼體育用品) var SportFactory = function(name) { switch(name) { case 'basketball': return new Basketball(); case 'football': return new Football(); case 'tennis': return new Tennis(); } } var ball = new SportFactory('tennis'); console.log(ball.intro) // 每一年有不少網球系列賽 console.log(ball.getMember()); // 每一個隊伍須要1名隊員
簡單工廠模式的理念就是建立對象, 而除此以外, 簡單工廠模式還能夠建立類似對象. 在建立多個類的時候, 假設每一個類都有不少類似的地方, 好比在多種彈出框上都有關閉按鈕, 都有提示文案等. 能夠經過將這些類似的東西提取, 不類似針對性處理便可.緩存
假設當前項目需求是須要作各類彈出框: 警示框, 確認框及提示框.
var LoginAlert = function(text) { this.content = text; }; LoginAlert.prototype.show = function() { // 顯示警示框 }; var LoginConfirm = function(text) { this.content = text; }; LoginConfirm.prototype.show = function() { // 顯示確認框 }; var LoginPrompt = function(text) { this.content = text; }; LoginPrompt.prototype.show = function() { // 顯示提示框 }; function createPop(type, text) { var o = new Object(); o.content = text; o.show = function() { // 顯示方法 }; if(type === 'alert') { // 警示框差別部分 } if(type === 'confirm') { // 確認框差別部分 } if(type === 'prompt') { // 提示框差別部分 } return o; } // 建立警示框 var userNameAlert = createPop('alert', '用戶名只能是26個字母和數字');
經過對產品類的抽象使其建立業務主要負責用於建立多類產品的實例.
假設有一批關於計算機培訓的廣告資源須要投放, 一批是PHP要求黃色字體紅色背景, 一批JAVA綠色字體, 一批JAVASCRIPT粉色背景....
var Java = function(content) { this.content = content; (functiont(content) { var div = document.createElement('div'); div.innerHTML = content; div.style.color = 'green'; document.getElementById('container').appendChild(div); })(content); }; var Php = function(content) { this.content = content; (functiont(content) { var div = document.createElement('div'); div.innerHTML = content; div.style.color = 'yellow'; div.style.background = 'red'; document.getElementById('container').appendChild(div); })(content); }; var Javascript = function(content) { this.content = content; (functiont(content) { var div = document.createElement('div'); div.innerHTML = content; div.style.background = 'pink'; document.getElementById('container').appendChild(div); })(content); }; // 建立學科類工廠 function JobFactory(type, content) { switch(type) { case 'java': return new Java(content); case 'php': return new Php(content); case 'Javascript': return new Javascript(contet); } } // 又要添需求啦.....多加一批UI學科, 紅色邊框..... // 代碼改進: var Factory = function(type, content) { if(this instanceof Factory) { var s = new this[type] (content); return s; } else { return new Factory(type, content); } }; // 在工廠原型中設置建立全部類型數據對象的基類 Factory.prototype = { Java: function() { // ... }, Php: function() { // ... }, Javascript: function() { // ... }, UI: function() { // ... } }; var data = [ {type:'JavaScript', content:'javascript'}, {type:'Java', content:'java'}, {type:'PHP', content:'php'}, {type:'UI', content:'ui'} ]; for(var i = data.length; i >= 0; i--) { Factory(data[i].type, data[i].content); }
抽象工廠模式通常不用來建立具體對象, 抽象類中定義的方法只是顯性地定義一些功能, 但沒有具體的實現, 而一個對象須要具備一套完整的功能, 因此用抽象類建立的對象也是抽象的而非真實對象. 所以通常用它做爲父類來建立子類.app
抽象工廠實際上是一個實現子類繼承父類的方法, 在這個方法中須要經過傳遞子類以及要繼承父類(抽象類)的名稱,而且在抽象工廠方法中又增長了一次對抽象存在性的一次判斷, 若是存在, 則將子類繼承父類的方法. 而後子類經過寄生式繼承.繼承父類的原型中須要注意一點是, 在對過渡類的原型繼承時, 不是繼承父類的原型, 而是經過new關鍵字複製父類的一個實例, 這麼作事由於過渡類不該僅僅繼承父類的原型方法, 還要繼承父類的對象屬性, 因此要經過new關鍵字將父類的構造函數執行一遍來複制構造函數中的屬性和方法函數
抽象工廠添加抽象類比較特殊, 由於抽象工廠是個方法不須要實例化對象, 故只須要一份, 所以直接爲抽象工廠添加類的屬性便可.字體
// 抽象工廠方法 var VehicleFatory = function(subType, superType) { // 判斷抽象工廠中是否有該抽象類 if(typeof VehicleFactory[superType] === 'function') { // 緩存類 function F() {}; // 繼承父類屬性和方法 F.prototype = new VehicleFactory[superType] (); // 將子類constructor 指向子類 subType.constructor = subType; // 子類原型繼承'父類' subType.prototype = new F(); } else { // 不存在該抽象類拋出錯誤 throw new Error('未建立該抽象類'); } }; // 小汽車抽象類 VehicleFactory.Car = function() { this.type = 'car'; }; VehicleFactory.Car.prototype = { getPrice: function() { return new Error('抽象方法不能調用'); }, getSpeed: function() { return new Error('抽象方法不能調用'); } }; // 公交車抽象類 VehicleFactory.Bus = function() { this.type = 'bus'; }; VehicleFactory.Bus.prototype = { getPrice: function() { return new Error('抽象方法不能調用'); }, getSpeed: function() { return new Error('抽象方法不能調用'); } }; // 貨車抽象類 VehicleFactory.Truck = function() { this.type = 'truck'; }; VehicleFactory.Truck.prototype = { getPrice: function() { return new Error('抽象方法不能調用'); }, getSpeed: function() { return new Error('抽象方法不能調用'); } }; // 建立產品子類繼承相應的產品簇抽象類 // 寶馬汽車子類 var BMW = function(price, speed) { this.price = price; this.speed = speed; } //抽象工廠實現對Car抽象類的繼承 VehicleFactory(BMW, 'Car'); BMW.prototype.getPrice = function() { return this.price }; BMW.prototype.getSpeed = function() { return this.speed }; // 公交車... // 貨車...