設計模式幾十種,閱讀了《JavaScript設計模式與開發實踐》這本書後,我的感受js就是圍繞對象來設計的,發現平常寫代碼能用上的並很少,下面是經常使用的幾種設計模式。javascript
單一模式的核心是確保只有一個實例,並提供全局訪問,在 JS 開發中,常常把用一個對象包裹,這樣減小了全局變量的污染,好比 var a = {}。java
普通寫法:git
// 每次點擊點擊按鈕,都會建立一個 div var createLayer1 = (function () { var div = document.createElement('div'); div.innerHTML = '我是內容'; div.style.display = 'none'; document.body.appendChild(div); return div; })() document.getElementById('#btn').onclick = function () { var layer1 = createLayer1(); layer1.style.display = 'block'; }
單例模式:github
//實例對象老是在咱們調用方法時才被建立,而不是在頁面加載好的時候就建立。 // 這樣就不會每次點擊按鈕,都會建立一個 div 了 var createLayer2 = function () { var div; return function () { if (!div) { document.createElement('div'); div.innerHTML = '我是內容'; div.style.display = 'none'; document.body.appendChild(div); } return div; } } document.getElementById('#btn').onclick = function () { var layer2 = createLayer2(); layer2.style.display = 'block'; }
策略模式代碼很是優雅,最喜歡模式之一,也很便於修改,請看代碼。設計模式
普通模式:app
var awardS = function (salary) { return salary * 4 }; var awardA = function (salary) { return salary * 3 }; var awardB = function (salary) { return salary * 2 }; var calculateBonus = function (level, salary) { if (level === 'S') { return awardS(salary); } if (level === 'A') { return awardA(salary); } if (level === 'B') { return awardB(salary); } }; calculateBonus('A', 10000);
策略模式:socket
var strategies = { 'S': function (salary) { return salary * 4; }, 'A': function (salary) { return salary * 3; }, 'B': function (salary) { return salary * 2; } } var calculateBonus = function (level, salary) { return strategies[level](salary); } calculateBonus('A', 10000);
模板方法模式使用了原型鏈的方法,封裝性好,複用性差。this
var Coffee = function () { }; Coffee.prototype.boilWater = function () { // todo console.log('把水煮沸'); }; Coffee.prototype.brewCoffee = function () { // todo console.log('衝咖啡'); }; Coffee.prototype.pourInCup = function () { // todo console.log('把咖啡倒進杯子'); }; Coffee.prototype.addSugarAndMilk = function () { // todo console.log('加糖和牛奶'); }; Coffee.prototype.init = function () { this.boilWater(); this.brewCoffee(); this.pourInCup(); this.addSugarAndMilk(); } var coffee = new Coffee(); coffee.init();
沒錯,我剛開始寫第一個項目時候就這麼嵌套的,重複代碼太多,邏輯太亂,維護下太差。prototype
var order = function (orderType, pay, stock) { // 500 元定金模式 if (orderType === 1) { if (pay === true) { console.log('500元定金預購,獲得100元優惠券'); } else { if (stock > 0) { console.log('普通購買,無優惠券'); } else { console.log('手機庫存不足'); } } // 200 元定金模式 } else if (orderType === 2) { if (pay === true) { console.log('200元定金預購,獲得50元優惠券'); } else { if (stock > 0) { console.log('普通購買,無優惠券'); } else { console.log('手機庫存不足'); } } // 沒有定金模式 } else if (orderType === 3) { if (stock > 0) { console.log('普通購買,無優惠券'); } else { console.log('手機庫存不足'); } } } order(1, true, 500);
職責鏈,一系列可能處理請求的對象被鏈接成一條鏈,請求在這些對象之間依次傳遞,直到遇到一個能夠處理它的對象,減小了不少重複代碼。
var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log('500元定金預購,獲得100元優惠券'); } else { order200(orderType, pay, stock); } } var order200 = function (orderType, pay, stock) { if (orderType === 2 && pay === true) { console.log('200元定金預購,獲得50元優惠券'); } else { orderNormal(orderType, pay, stock); } } var orderNormal = function (orderType, pay, stock) { if (stock > 0) { console.log('普通購買,無優惠券'); } else { console.log('手機庫存不足'); } } order500(1, true, 500); order500(1, false, 500); order500(2, true, 500);
發佈訂閱模式,顧名思義,就是一個發佈消息,一個監聽消息,當有消息接收時處理消息。
// js前端 window.onload = function () { var socket = io.connect('http://localhost:20122?token=abc'); socket.on('connect', function() { socket.emit('message', ':chat socket') }); socket.on('message', function(data) { alert(data) }) }; // 服務端 io.on('connection', function (socket) { socket.on('chat message', function (msg) { console.log('receive a message: ' + msg) io.emit('chat message', msg); }); })
能夠參考個人另外一個倉庫地址,一個簡單的實時聊天 demo