摘要:寫在前面設計模式是程序員通識知識,熟練掌握并使用各種設計模式,可以體現一個程序員的工程開發水平。我花了幾天時間,重溫并整理了多種設計模式,以為示例語言。節流模式對重復的業務邏輯進行節流控制,執行最后一次操作并取消其他操作,以提高性能。
寫在前面
設計模式是程序員通識知識,熟練掌握并使用各種設計模式,可以體現一個程序員的工程開發水平。我花了幾天時間,重溫并整理了30多種設計模式,以JavaScript為示例語言。下面我會列出一些常用的設計模式說明及示例,更全面的內容見:https://github.com/yzsunlei/javascript-design-mode
什么是設計模式?一個模式就是一個可重用的方案,可應用于在軟件設計中的常見問題。另一種解釋就是一個我們如何解決問題的模板 - 那些可以在許多不同的情況里使用的模板。
設計模式的分類:創建型設計模式:
1、簡單工廠模式
2、工廠方法模式
3、抽象工廠模式
4、建造者模式
5、原型模式
6、單例模式
結構型設計模式:
7、外觀模式
8、適配器模式
9、代理模式
10、裝飾者模式
11、橋接模式
12、組合模式
13、享元模式
行為型設計模式:
14、模板方法模式
15、觀察者模式
16、狀態模式
17、策略模式
18、職責鏈模式
19、命令模式
20、訪問者模式
21、中介者模式
22、備忘錄模式
23、迭代器模式
24、解釋器模式
技巧型設計模式:
25、鏈模式
26、委托模式
27、數據訪問對象模式
28、節流模式
29、簡單模板模式
30、惰性模式
31、參與者模式
32、等待者模式
架構型設計模式:
33、同步模塊模式
34、異步模塊模式
35、Widget模式
36、MVC模式
37、MVP模式
38、MVVM模式
備注:該分類借鑒于《JavaScript設計模式-張容銘》
工廠方法模式:通過對產品類的抽象使其創建業務主要負責用于創建多類產品的實例。
// 安全模式創建的工廠類 var Factory = function(type, content) { if (this instanceof Factory) { // 保證是通過new進行創建的 var s = new this[type](content); return s; } else { return new Factory(type, content); } }; // 工廠原型中設置創建所有類型數據對象的基類 Factory.prototype = { Java: function(content) { }, Php: function(content) { }, JavaScript: function(content) { } };原型模式:
用原型實例指向創建對象的類,使用于創建新的對象的類共享原型對象的屬性以及方法。
// 圖片輪播類 var LoopImages = function(imgArr, container) { this.imagesArray = imgArr; this.container = container; }; LoopImages.prototype = { // 創建輪播圖片 createImage: function() { console.log("LoopImages createImage function"); }, // 切換下一張圖片 changeImage: function() { console.log("LoopImages changeImage function"); } }; // 上下滑動切換類 var SliderLoopImg = function(imgArr, container) { // 構造函數繼承圖片輪播類 LoopImages.call(this, imgArr, container); }; SliderLoopImg.prototype = new LoopImages(); // 重寫繼承的“切換下一張圖片”方法 SliderLoopImg.prototype.changeImage = function() { console.log("SliderLoopImg changeImage function"); };單例模式:
又稱單體模式,是只允許實例化一次的對象類。
// 惰性 var LarySingle = (function() { // 單例實例引用 var _instance = null; // 單例 function Single() { // 這里定義私有屬性和方法 return { publicMethod: function() {}, publicProperty: "1.0" }; } // 獲取單例對象接口 return function() { // 如果未創建單例將創建單例 if(!_instance){ _instance = Single(); } // 返回單例 return _instance; }; })();外觀模式:
為一組復雜的子系統接口提供一個更高級的統一接口,通過這個接口使得對子系統接口的訪問更容易。
function addEvent(dom, type, fn) { // 對于支持DOM2級事件處理程序addEventListener方法的瀏覽器 if (dom.addEventListener) { dom.addEventListener(type, fn, false); } else if (dom.attachEvent) { // 對于不支持addEventListener方法但支持attchEvent方法的瀏覽器 dom.attachEvent("on" + type, fn); } else { // 對于不支持addEventListener方法,也不支持attchEvent方法,但支持“on”+事件名的瀏覽器 dom["on" + type] = fn; } }裝飾者模式:
在不改變原對象的基礎上,通過對其進行包裝拓展(添加屬性或方法)使原對象可以滿足用戶更復雜需求。
var decorator = function (input, fn) { // 獲取事件源 var input = document.getElementById(input); // 若事件源已經綁定事件 if (typeof input.click === "function") { // 緩存事件源原有回調函數 var oldClickFn = input.click; // 為事件源定義新的事件 input.click = function () { // 事件源原有回調函數 oldClickFn(); // 執行事件源新增回調函數 fn(); } } else { // 事件源未綁定事件,直接為事件源添加新增回調函數 input.onclick = fn; } }觀察者模式:
又稱發布-訂閱者模式或消息機制,定義一種依賴關系,解決了主體對象與觀察者之間功能的耦合。
var Observer = (function () { var __messages = {}; return { // 注冊消息 register: function (type, fn) { if (typeof __messages[type] === "undefined") { __messages[type] = [fn]; } else { __messages[type].push(fn); } }, // 發布消息 fire: function (type, args) { if (!__messages[type]) return; var events = { type: type, args: args || {} }; var i = 0; var len = __messages[type].length; for (; i < len; i++) { __messages[type][i].call(this, events); } }, // 移除消息 remove: function (type, fn) { if (__messages[type] instanceof Array) { var i = __messages[type].length - 1; for (; i >= 0; i--) { __messages[type][i] == fn && __messages[type].splice(i, 1); } } } } })();狀態模式:
當一個對象的內部狀態發生改變時,會導致其行為的改變,這看起來像是改變了對象。
// 狀態對象 var ResultState = function () { var States = { state0: function () { console.log("第一種情況"); }, state1: function () { console.log("第二種情況"); }, state2: function () { console.log("第三種情況"); }, state3: function () { console.log("第四種情況"); } }; function show(result) { States["state" + result] && States["state" + result](); } return { show: show } }();命令模式:
將請求與實現解耦并封裝成獨立對象,從而使不同的請求對客戶端的實現參數化。
// 繪圖命令 var CanvasCommand = (function () { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var Action = { fillStyle: function (c) { ctx.fillStyle = c; }, fillRect: function (x, y, w, h) { ctx.fillRect(x, y, w, h); }, strokeStyle: function (c) { ctx.strokeStyle = c; }, strokeRect: function (x, y, w, h) { ctx.strokeRect(x, y, w, h); }, fillText: function (text, x, y) { ctx.fillText(text, x, y); }, beginPath: function () { ctx.beginPath(); }, moveTo: function (x, y) { ctx.moveTo(x, y); }, lineTo: function (x, y) { ctx.lineTo(x, y); }, arc: function (x, y, r, begin, end, dir) { ctx.arc(x, y ,r, begin, end, dir); }, fill: function () { ctx.fill(); }, stroke: function () { ctx.stroke(); } }; return { excute: function (msg) { if (!msg) return; if (msg.length) { for (var i = 0, len = msg.length; i < len; i++) { arguments.callee(msg[i]); } } else { msg.param = Object.prototype.toString.call(msg.param) === "[object Array]" ? msg.param : [msg.param]; Action[msg.command].apply(Action, msg.param); } } } })();迭代器模式:
在不暴露對象內部結構的同時,可以順序的訪問聚合對象內部的元素。
// 迭代器 var Iterator = function (items, container) { var container = container && document.getElementById(container) || document; var items = container.getElementsByTagName(items); var len = items.length; var idx = 0; var splice = [].splice(); return { first: function () {}, second: function () {}, pre: function () {}, next: function () {}, get: function () {}, dealEach: function () {}, dealItem: function () {}, exclusive: function () {} } };鏈模式:
通過在對象方法中將當前對象返回,實現對同一個對象多個方法的鏈式調用。
var A = function (selector) { return new A.fn.init(selector); }; A.fn = A.prototype = { constructor: A, init: function (selector) { console.log(this.constructor); } }; A.fn.init.prototype = A.fn;節流模式:
對重復的業務邏輯進行節流控制,執行最后一次操作并取消其他操作,以提高性能。
var throttle = function () { var isClear = arguments[0]; var fn; if (typeof isClear === "boolean") { fn = arguments[1]; fn.__throttleID && clearTimeout(fn.__throttleID); } else { fn = isClear; param = arguments[1]; var p = extend({ context: null, args: [], time: 30 }, param); arguments.callee(true, fn); fn.__throttleID = setTimeout(function () { fn.apply(p.context, p.args); }, p.time); } }參與者模式:
在特定的作用域中執行給定的函數,并將參數原封不動的傳遞。
// 函數綁定 function bind(fn, context) { return function () { return fn.apply(context, arguments); } } // 函數柯里化 function curry(fn) { var Slice = [].slice; var args = Slice.call(arguments, l); return function () { var addArgs = Slice.call(arguments); var allArgs = args.concat(addArgs); return fn.apply(null, allArgs); } }參考資料
https://book.douban.com/subject/26589719/
https://book.douban.com/subject/26382780/
https://www.w3cschool.cn/zobyhd/m1w6jozt.html
https://www.cnblogs.com/xiyangbaixue/p/3902699.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104873.html
稍微整理了一下自己平時看到的前端學習資源,分享給大家。 html MDN:Mozilla開發者網絡 SEO:前端開發中的SEO css 張鑫旭:張鑫旭的博客 css精靈圖:css精靈圖實踐 柵格系統:詳解CSS中的柵格系統 媒體查詢:css媒體查詢用法 rem布局:手機端頁面自適應布局 移動前端開發之viewport的深入理解:深入理解viewport 淘寶前端布局:手機淘寶移動端布局 fl...
摘要:開發中,我們或多或少地接觸了設計模式,但是很多時候不知道自己使用了哪種設計模式或者說該使用何種設計模式。本文意在梳理常見設計模式的特點,從而對它們有比較清晰的認知。 showImg(https://segmentfault.com/img/remote/1460000014919705?w=640&h=280); 開發中,我們或多或少地接觸了設計模式,但是很多時候不知道自己使用了哪種設...
摘要:離線版大部分整理自,少部分整理自,由本人整理。感謝站長的無私奉獻。由于本人精力有限,此處的列表不一定能夠及時更新,最新版本請到本人博客查看。 離線版大部分整理自 w3cschool ,少部分整理自 w3school ,由本人整理。 感謝 w3cschool 站長的無私奉獻。 由于本人精力有限,此處的列表不一定能夠及時更新,最新版本請到本人博客查看。 AngularJS教程 最后更...
摘要:離線版大部分整理自,少部分整理自,由本人整理。感謝站長的無私奉獻。由于本人精力有限,此處的列表不一定能夠及時更新,最新版本請到本人博客查看。 離線版大部分整理自 w3cschool ,少部分整理自 w3school ,由本人整理。 感謝 w3cschool 站長的無私奉獻。 由于本人精力有限,此處的列表不一定能夠及時更新,最新版本請到本人博客查看。 AngularJS教程 最后更...
閱讀 2008·2019-08-29 16:27
閱讀 1377·2019-08-29 16:14
閱讀 3380·2019-08-29 14:18
閱讀 3461·2019-08-29 13:56
閱讀 1260·2019-08-29 11:13
閱讀 2128·2019-08-28 18:19
閱讀 3447·2019-08-27 10:57
閱讀 2283·2019-08-26 11:39