摘要:常用設(shè)計模式大型單頁應(yīng)用里,復(fù)雜度上升到一定程度時,沒有適當(dāng)?shù)脑O(shè)計模式進(jìn)行降耦,后續(xù)的開發(fā)也難以下手。而設(shè)計模式正是為了降耦而存在。特點(diǎn)滿足單一職責(zé)原則使用代理模式,不在構(gòu)造函數(shù)中判斷是否已經(jīng)創(chuàng)建過該單例滿足惰性原則應(yīng)用彈出登陸窗口。
JS常用設(shè)計模式
大型單頁應(yīng)用里,復(fù)雜度上升到一定程度時,沒有適當(dāng)?shù)脑O(shè)計模式進(jìn)行降耦,后續(xù)的開發(fā)也難以下手。
而設(shè)計模式正是為了降耦而存在。
單例模式的核心是確保只有一個實(shí)例,并且提供全局訪問。
特點(diǎn)滿足“單一職責(zé)原則” : 使用代理模式,不在構(gòu)造函數(shù)中判斷是否已經(jīng)創(chuàng)建過該單例;
滿足惰性原則
應(yīng)用彈出登陸窗口。
實(shí)例var getSingle = function (fn) { var res; return function() { return res || (res = fn.apply(this, arguments)); } } var createPopup() { var div = document.createElement("div"); div.innerHTML = "Login window"; div.style.display = "none"; document.body.appendChild(div); return div; } var createLoginPopup = getSingle(createPopup); //create popup div here by using a given function, 滿足兩個原則 document.getElementById("loginBt").onclick = function() { var popup = createLoginPopup(); pop.style.display = "block"; }構(gòu)造函數(shù)模式
/** * 構(gòu)造一個動物的函數(shù) */ function Animal(name, color){ this.name = name; this.color = color; this.getName = function(){ return this.name; } } // 實(shí)例一個對象 var cat = new Animal("貓", "白色"); console.log( cat.getName() );原型模式
function Person(){ } Person.prototype.name = "bill"; Person.prototype.address = "GuangZhou"; Person.sayName = function (){ alert(this.name); } var person1 = new Person(); var person2 = new Person(); //測試代碼 alert(person1.name); // bill alert(person2.name); // bill person1.sayName(); //bill person2.sayName(); //bill person1.name = "666"; alert(person1.name); // 666 alert(person2.name); // bill person1.sayName(); //666 person2.sayName(); //bill混合模式
/** * 混合模式 = 原型模式 + 構(gòu)造函數(shù)模式 */ function Animal(name, color){ this.name = name; this.color = color; console.log( this.name + this.color) } Animal.prototype.getInfo = function(){ console.log("名稱:"+ this.name); } function largeCat(name, color){ Animal.call(null, name, color); this.color = color; } largeCat.prototype = create(Animal.prototype); function create (parentObj){ function F(){} F.prototype = parentObj; return new F(); }; largeCat.prototype.getColor = function(){ return this.color; } var cat = new largeCat("Persian", "白色"); console.log( cat )工廠模式
工廠:函數(shù)內(nèi)部產(chǎn)生b對象并返回。
1. function a(name){ var b = new object(); b.name = name; b.say = function(){ alert(this.name); } return b } 2. function Animal(opts){ var obj = new Object(); obj.name = opts.name; obj.color = opts.color; obj.getInfo = function(){ return "名稱:"+obj.name +", 顏色:"+ obj.color; } return obj; } var cat = Animal({name: "波斯貓", color: "白色"}); cat.getInfo();簡單工廠模式
簡單工廠模式的理念就是創(chuàng)建對象,對不同類的實(shí)例化;只需要創(chuàng)建一個對象,然后通過對這個對象大量的方法和屬性,并在最終將對象返回出來
//basketball base class var Baseketball = function(){ this.intro = "baseketball is hotting at unitedstates"; } Baseketball.prototype = { getMember : function(){ console.log("each team needs five players"); }, getBallSize : function(){ console.log("basketball is big"); } } //football base class var Football = function(){ this.intro = "football is popular at all of the world"; } Football = function(){ getMember = function(){ }, getBallSize = function(){ } } //sport factory var SportsFactory = function(name){ switch(name){ case "NBA": return new Baseketball(); case "wordCup": return new Football(); } } //when you want football var football = SportsFactory("wordCup"); console.log(football); console.log(football.intro); football.getMember();迭代器模式
裝飾者模式
策略模式定義一個個可以相互替換的算法,并且把他們封裝起來。
特點(diǎn)符合開放-封閉原則 : 要修改使用的算法時不用深入函數(shù)內(nèi)部進(jìn)行修改,只需修改策略類;
將算法的實(shí)現(xiàn)與使用分離開,提高算法復(fù)用性;
通過組合、委托和多態(tài)避免多重條件選擇語句;
應(yīng)用動畫實(shí)現(xiàn)不同的緩動效果。
一般分為兩個部分:策略類于環(huán)境類。策略類用于封裝各種算法,并且負(fù)責(zé)具體的計算過程; 環(huán)境類負(fù)責(zé)接收用戶的請求,并且把請求委托給某一個策略類。因為各個策略類實(shí)現(xiàn)的算法和計算的結(jié)果不同,而環(huán)境類調(diào)用策略類的方法卻是相同的,這就體現(xiàn)了多態(tài)性。要想實(shí)現(xiàn)不同的算法,只需要替換環(huán)境類中的策略類即可。
在js中,我們不必構(gòu)造策略類,可直接使用函數(shù)作為策略對象。
示例
var strategies = { "s1": function() { //algo 1 }, "s2": function() { //algo 2 }, "s3": function() { //algo 3 } } var someContext = new SomeConext(); someContext.start("s1"); //using s1 to calculate //someContext.add("s1"); or add s1 as a rule for validation外觀模式
也可譯為門面模式。它為子系統(tǒng)中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。引入外觀角色之后,使用者只需要直接與外觀角色交互,使用者與子系統(tǒng)之間的復(fù)雜關(guān)系由外觀角色來實(shí)現(xiàn),從而降低了系統(tǒng)的耦合度。
比如在家要看電影,需要打開音響,再打開投影儀,再打開播放器等等,引入外觀角色之后,只需要調(diào)用“打開電影設(shè)備”方法就可以。外觀角色封裝了打開投影儀等操作,給使用者提供更容易使用的方法。
簡化復(fù)雜接口
解耦和,屏蔽使用者對子系統(tǒng)的直接訪問
實(shí)例在形式上,外觀模式在javascript中就像這樣:
function a(x){ // do something } function b(y){ // do something } function ab( x, y ){ a(x); b(y); }
下面的一個例子,把阻止冒泡和阻止默認(rèn)事件放到了外觀角色中:
var N = window.N || {}; N.tools = { stopPropagation : function( e ){ if( e.stopPropagation ){ e.stopPropagation(); }else{ e.cancelBubble = true; } }, preventDefault : function( e ){ if( e.preventDefault ){ e.preventDefault(); }else{ e.returnValue = false; } }, stopEvent : function( e ){ N.tools.stopPropagation( e ); N.tools.preventDefault( e ); }
外觀模式在javascript的應(yīng)用主要可以分為兩類,某塊代碼反復(fù)出現(xiàn),比如函數(shù)a的調(diào)用基本都出現(xiàn)在函數(shù)b的調(diào)用之前,那么可以考慮考慮將這塊代碼使用外觀角色包裝一下來優(yōu)化結(jié)構(gòu)。還有一種就是對于一些瀏覽器不兼容的API,放置在外觀內(nèi)部進(jìn)行判斷,處理這些問題最好的方式便是將跨瀏覽器差異全部集中放置到一個外觀模式實(shí)例中來提供一個對外接口。
代理模式代理模式的定義:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。
虛擬代理虛擬代理是把一些開銷很大的對象,延遲到真正需要它的時候才去創(chuàng)建執(zhí)行
圖片懶加載//圖片加載 let imageEle = (function(){ let node = document.createElement("img"); document.body.appendChild(node); return { setSrc:function(src){ node.src = src; } } })(); //代理對象 let proxy = (function(){ let img = new Image(); img.onload = function(){ imageEle.setSrc(this.src); }; return { setSrc:function(src){ img.src = src; imageEle.setSrc("loading.gif"); } } })(); proxy.setSrc("example.png");合并http請求
如果有一個功能需要頻繁進(jìn)行請求操作,這樣開銷比較大,可以通過一個代理函數(shù)收集一段時間內(nèi)請求數(shù)據(jù),一次性發(fā)出
//上傳請求 let upload = function(ids){ $.ajax({ data: { id:ids } }) } //代理合并請求 let proxy = (function(){ let cache = [], timer = null; return function(id){ cache[cache.length] = id; if(timer) return false; timer = setTimeout(function(){ upload(cache.join(",")); clearTimeout(timer); timer = null; cache = []; },2000); } })(); // 綁定點(diǎn)擊事件 let checkbox = document.getElementsByTagName( "input" ); for(var i= 0, c; c = checkbox[i++];){ c.onclick = function(){ if(this.checked === true){ proxy(this.id); } } }緩存代理
緩存代理可以作為一些開銷大的運(yùn)算結(jié)果提供暫時的存儲,下次運(yùn)算時,如果傳遞進(jìn)來的參數(shù)跟之前一致,則可以直接返回前面存儲的運(yùn)算結(jié)果
//計算乘積 let mult = function(){ let result = 1; for(let i = 0,len = arguments.length;i < len;i++){ result*= arguments[i]; } return result; } //緩存代理 let proxy = (function(){ let cache = {}; reutrn function(){ let args = Array.prototype.join.call(arguments,","); if(args in cache){ return cache[args]; } return cache[args] = mult.apply(this,arguments); } })();優(yōu)缺點(diǎn)
1.優(yōu)點(diǎn):代理模式能將代理對象與被調(diào)用對象分離,降低了系統(tǒng)的耦合度。代理模式在客戶端和目標(biāo)對象之間起到一個中介作用,這樣可以起到保護(hù)目標(biāo)對象的作用。代理對象也可以對目標(biāo)對象調(diào)用之前進(jìn)行其他操作。
2.缺點(diǎn):增加了系統(tǒng)的復(fù)雜度
觀察者模式
模塊模式/** * 模塊模式 = 封裝大部分代碼,只暴露必需接口 */ var Car = (function(){ var name = "法拉利"; function sayName(){ console.log( name ); } function getColor(name){ console.log( name ); } return { name: sayName, color: getColor } })(); Car.name(); Car.color("紅色");
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107494.html
摘要:常用模式片段之摘要第一次看到這個字眼是在中,即。之后也見到一些別人的代碼里有,它和頁面的有什么關(guān)系,以及和有何淵源。以前都見過這些詞,但都似懂非懂,今天查了些資料收集了些代碼,做個完整的理解。 CSS篇 常用模式片段之CSS布局篇 http://jsorz.cn/blog/2016/08/code-patterns-of-css-layout.html 摘要:position 拉伸性質(zhì)...
摘要:常用模式片段之摘要第一次看到這個字眼是在中,即。之后也見到一些別人的代碼里有,它和頁面的有什么關(guān)系,以及和有何淵源。以前都見過這些詞,但都似懂非懂,今天查了些資料收集了些代碼,做個完整的理解。 CSS篇 常用模式片段之CSS布局篇 http://jsorz.cn/blog/2016/08/code-patterns-of-css-layout.html 摘要:position 拉伸性質(zhì)...
摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對象事件框架選擇框架。核心模塊和對象全局對象,,,事件驅(qū)動,事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進(jìn)階、CSS進(jìn)階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對...
摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對象事件框架選擇框架。核心模塊和對象全局對象,,,事件驅(qū)動,事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進(jìn)階、CSS進(jìn)階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對...
摘要:中常用的有兩種,透視投影相機(jī)與正交投影相機(jī)。這里的投影是指將三維空間中的物體坐標(biāo)投影到二維平面上。正交投影是只考慮所有點(diǎn)的坐標(biāo),每一個二維空間中的點(diǎn)都是與軸平行的直線在觀察平面上的投影。所看到的物體大小不會受到距離遠(yuǎn)近的影響。 three.js中常用的camera有兩種,透視投影相機(jī)(PerspectiveCamera)與正交投影相機(jī)(OrthographicCamera)。這里的投影...
閱讀 1970·2021-11-23 10:03
閱讀 4129·2021-11-22 09:34
閱讀 2466·2021-10-08 10:05
閱讀 2246·2019-08-30 15:53
閱讀 1686·2019-08-30 13:56
閱讀 1149·2019-08-29 16:52
閱讀 1102·2019-08-26 13:31
閱讀 3346·2019-08-26 11:45