有人說設計模式是能被反覆使用、多數人知道的、通過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼,讓代碼更容易被他人理解、保證代碼的可靠性。html
我的認爲,設計模式其實就是前端工程化編程的一種思想,將代碼 可以理解成更貼近生活的一種經驗。年紀大了,就知道作什麼,怎麼作,怎麼能作的更好,編程也同樣,時間長了,就更明白什麼需求應該採用什麼方式編寫,這種一向的編寫方式因而被總結爲設計模式,咱們如今用的這些模式,其實就是前輩的經驗總結,能避免咱們繞彎路,更好的編程。前端
....
咱們經常使用的也就是 單體模式、工廠模式、單例模式、觀察者模式、策略模式,其餘的可能沒用到,或者無形中用到了但沒注意是什麼模式,無論是什麼模式,可以被重用的,可維護的代碼,都是好的程序vue
單例模式在js中咱們隨處都見,一個類只能保證有一個實例,例如對象字面量的方式建立一個單例,他能夠定義不少的屬性和方法,這個類也只有一個實例對象。優勢,可以單獨劃分一個命名空間,避免和別人的內部變量發生衝突,因此單例能夠分爲簡單的單例和閉包單例編程
簡單單例segmentfault
//先判斷實例是否存在,存在則返回,不存在則建立,這樣能夠保證一個類只有一個實例對象 var test_simple = test_simple || { name: 'alice', age: 15, gender: '2', sayName: function(){ console.log('my name is ' + this.name) }, sayAge: function(){ console.log('i am '+ this.age + ' years old') } }
閉包單例設計模式
閉包的做用是保護一些私有屬性,不讓外界訪問,只有return將屬性暴露才能被外界訪問 var test_Closure = test_Closure || { introduce = (function(){ var _name = 'bob', //定義私有屬性 var _age = 18, var _gender = '1', var _sayName = function(){ console.log('my name is ' + _name) }, var _sayAge = function(){ console.log('i am '+ _age + ' years old') } //將屬性暴露 讓別人看看 return { name: _name, age : _age, gender : _gender, sayName : function(){ return _sayName(); }, sayAge : function(){ return _sayAge(); } } })() } //調用 test_Closure.sayName(); =>'my name is bob' test_Closure.sayAge(); =>'i am 18 years old'
例如vue的雙向數據綁定的原理:前端工程化
當咱們在表單輸入框中輸入(發佈)message的時候,依賴(訂閱)他的地方都會被更改
一句話描述:一個頁面在多處訂閱使用了同一個數據,用Object.defineProperty監聽其改變,並由發佈者通知 訂閱者 去更新它所持有的數據數組
具體實現請參照 https://segmentfault.com/a/11...閉包
實現一個分蛋糕案例
一、onserver.jsapp
var Observer = {}; //定義一個對象 包括三個方法 訂閱 發佈 退訂 (function (_observer) { var subListObj = {}, // 回調函數存放的數組 subId = -1; //訂閱者id // 發佈 傳入兩個參數 (訂閱主題,具體內容) _observer.publish = function (subTip, args) { if (!subListObj[subTip]) { return false; //判斷是否有訂閱者 } setTimeout(function () { var subscribers = subListObj[subTip], //定義一個數組用來存儲全部訂閱者 len = subscribers ? subscribers.length : 0; while (len--) { //只要發佈者一發布就會遍歷全部訂閱者,分發信息 subscribers[len].func(subTip, args); } }, 0); return true; }; //訂閱 _observer.subscribe = function (subTip, func) { if (!subListObj[subTip]) { subListObj[subTip] = []; } var token = (++subId).toString(); //訂閱者惟一標識 subListObj[subTip].push({ //接收信息 token: token, func: func //func不只是一個動做 數據更新的回調 }); // console.log(token) // => {example1:[0,func]}{example1:[1,func]} return token; }; //退訂 _observer.unsubscribe = function (token) { //退訂 傳入訂閱者的id進行過濾 若是退訂就splice刪除 for (var m in subListObj) { if (subListObj[m]) { for (var i = 0, j = subListObj[m].length; i < j; i++) { if (subListObj[m][i].token === token) { subListObj[m].splice(i, 1); console.log('我' + token + '不吃了') return token; } } } } return false; }; } (Observer));
二、過來吃蛋糕啦 index.html
<script src="./js/observer.js"></script> <script> //來,訂閱一個 Observer.subscribe('subCake', function (subTip, data) { console.log(subTip + ": " + data); }); //來,再訂閱一個 Observer.subscribe('subCake', function (subTip, data) { console.log(subTip + "我來啦.." + data); }); //0不吃了 Observer.unsubscribe('0') //發佈通知 Observer.publish('subCake', '快來分蛋糕...'); </script> 若是0沒有退訂: subCake我也收到了..快來分蛋糕... subCake: 快來分蛋糕... 0退訂了: 我0不吃了 subCake我也收到了..快來分蛋糕...
工廠模式:提供建立對象的接口,封裝一些公用的方法,若是實現具體的業務邏輯,能夠放在子類重寫父類的方法
優勢:弱化對象間的耦合,防止代碼重複
缺點:簡單業務能夠用,複雜的業務會致使代碼維護性差,不易閱讀
//聲明一個蛋糕店 負責作蛋糕 和 賣蛋糕 var CakeShop = function(){} CakeShop.prototype = { sellCake: function(){ }, makeCake: function(type){ console.log('aaa') } } //定義一個繼承的方法 var Extend = function(desc, src){ for(var property in src){ desc[property] = src[property] } return desc; } Object.extend = function(obj){ return Extend.apply(this,[this.obj]) } //聲明一個水果蛋糕,從蛋糕店 var FruitCake = function(){} Object.extend(FruitCake, CakeShop); console.log(FruitCake.prototype) FruitCake.prototype.makeCake = function(type){ var cake; switch (type){ case 'apple': cake = new AppleCake();break; case 'pear': cake = new Pear();break; default: cake = new Orange();break; } return cake; } var buyCake = new FruitCake(); var myCake = buyCake.sellCake('apple') console.log(myCake)
策略模式是一種很好的編程思想,能夠用來解決多個if條件語句,可以代碼複用,邏輯清晰,也容易擴展。
來來來,上代碼
//之前你是這樣的 var buyCar = function(brand){ if(brand == '奧迪') { return '大於80萬' } if(brand == 'QQ') { return '小於10萬' } if(brand == 'ofo') { return '小於1000元' } } console.log(buyCar('ofo')) // => 小於1000元 //那麼如今你應該這樣 var buyCars = { '奧迪': function(){ return '大於80萬' }, 'QQ': function(){ return '小於10萬' }, 'ofo': function(){ return '小於1000元' } } var result = function(brand){ return buyCars[brand](); } console.log(result('ofo')) // => 小於1000元 // 系不繫很簡單
設計模式還有不少,有時間還會繼續學習...