關於W3Cschool定義的設計模式–常用的9種設計模式的介紹
- 2019 年 10 月 3 日
- 筆記
一、設計模式
tip:每種設計模式,其實都是為了更高效的,更方便的解決在面對對象編程中所遇到的問題。
function Fn(){ this.name = "root"; } var f = new Fn() console.log(f.name)//root
單例模式
//單個實例,只有一個對象 //多次創建,返回同一個對象 function fn(){ if(!fn.obj) { //給函數添加一個屬性。 因為函數是全局的,所以該屬性一旦添加一直存在; fn.obj = { name : “土土皮皮" }; } return fn.obj; } var obj1 = new fn(); var obj2 = new fn(); console.log(obj1 == obj2); //例如我們創建一個資訊提示框,每一次執行toast方法,如果都創建一個新的元素,這樣做太浪費了。 //因此,我們採取單例模式,確保無論調用多少次toast方法,都只創建一個DOM元素。 //我們只控制它的顯示和隱藏,而不是每次創建每次銷毀。 function Toast(){ var div = document.createElement("div"); div.className = "box"; document.body.appendChild(div); setTimeout(function(){ div.remove(); },1000) } obtn.onclick = function(){ var a = new Toast(); var b = new Toast(); console.log(a == b) } function Toast(){ if(!Toast.div){ Toast.div = document.createElement("div"); Toast.div.className = "box"; document.body.appendChild(Toast.div); clearTimeout(Toast.div.timer); Toast.div.timer = setTimeout(function(){ Toast.div.style.display = "none"; },1000) }else{ Toast.div.style.display = "block"; clearTimeout(Toast.div.timer); Toast.div.timer = setTimeout(function(){ Toast.div.style.display = "none"; },1000) } return Toast; } obtn.onclick = function(){ var a = new Toast(); var b = new Toast(); console.log(a == b); }
單例模式-彈出框案例
// 單例模式 function Toast(){ // 第一次執行函數時給構造函數添加屬性為對象 if(!Toast.obj){ Toast.obj = {}; // 對對象進行加工 Toast.obj.dia = document.createElement("dialog"); Toast.obj.dia.innerHTML = "這是一個彈出框"; document.body.appendChild(Toast.obj.dia) } // 正常情況下,每次創建元素,都要立即顯示 Toast.obj.dia.style.display = "block"; // 過一定的時間後,隱藏元素 clearTimeout(Toast.obj.t) Toast.obj.t = setTimeout(() => { Toast.obj.dia.style.display = "none" }, 2000); // 覆蓋this的指向(覆蓋new出來的對象) return Toast.obj; } document.onclick = function(){ var t1 = new Toast() var t2 = new Toast() var t3 = new Toast() var t4 = new Toast() var t5 = new Toast() //這些被new出來的對象,都指向一個對象 console.log(t1 == t2)//true console.log(t3 == t2)//true console.log(t5 == t2)//true console.log(t4 == t2)//true console.log(t1 == t3)//true console.log(t3 == t5)//true }
四、組合模式
1、組合模式是用來組合對象的,一般應用於頁面,將對象按照一定的規律和關係組合,組成樹狀結構,類似於DOM元素中的樹狀結構,可以完成動態網頁的生成、創建元素和修改樣式。
2、將對象組合起來之後,可以實現:批量操作。
3、缺點:節省了操作,消耗了性能。
tip:組合模式最重要的是組合器。
// 最關鍵的是組合器: function ImagesStore( id ){ this.children = []; this.element = document.createElement("div"); this.element.id = id; document.body.appendChild(this.element) } ImagesStore.prototype = { constructor : ImagesStore, add:function( child ){ this.children.push( child ); this.element.appendChild( child.getElement() ); }, remove:function( child ){ for( var node, i=0; node = this.getChild(i); i++ ){ if( node === child ){ this.children.splice( i, 1 ); break; } } this.element.removeChild( child.getElement() ); }, getChild:function( i ){ return this.children[i]; }, show:function(){ this.element.style.border = 'solid 2px black'; for( var node, i=0; node = this.getChild(i); i++ ){ node.show(); } }, hide:function(){ for( var node, i=0; node = this.getChild(i); i++ ){ node.hide(); } this.element.style.border = 'none'; }, getElement:function(){ return this.element; } } function ImageItem( src ){ this.element = document.createElement("img"); this.element.src = src; this.element.className = "img-item"; } ImageItem.prototype = { constructor:ImageItem, add:function( child ){ console.log("這是子對象了,沒有添加功能"); }, remove:function( child ){ console.log("這是子對象了,沒有刪除功能"); }, getChild:function( i ){ console.log("這是子對象了,沒有獲取子對象功能"); }, show:function(){ this.element.style.border = 'solid 2px black'; }, hide:function(){ this.element.style.border = 'none'; }, getElement:function(){ return this.element; } } var box = new ImagesStore("box"); var xbox = new ImagesStore("xbox"); var img1 = new ImageItem("https://www.baidu.com/img/bd_logo1.png") var img2 = new ImageItem("https://www.baidu.com/img/bd_logo1.png") xbox.add(img1) xbox.add(img2) box.add(xbox) // box.remove(img1) // img1.show() box.show() // img1.add()
五、觀察者模式
1、觀察者模式又叫發布訂閱者模式:
(1)發布者:主題對象,一般只有一個。
(2)接收者:訂閱者,多個,隨時添加和刪除。
(3)廣播通訊,一個對象發布資訊,多個對象接收資訊,並做出對應處理。
2、觀察者模式的好處:
(1)支援簡單的廣播通訊,自動通知所有已經訂閱過的對象。
(2)頁面載入後目標對象很容易與觀察者存在一種動態關聯,增加了靈活性。
(3)目標對象與觀察者之間的抽象耦合關係能夠單獨擴展以及重用。
觀察者模式-案例-看孩子還是打麻將
function child(n){ this.name = n; this.type = function(){ return Math.random()>0.5? 0 : 1; } } function mather(n,c){ this.name = n; this.child = c; this.listen = function(t){ if(t==0){ console.log(this.child.name + "哭了,"+this.name+"看孩子") }else{ console.log(this.child.name + "睡了,"+this.name+"打麻將") } } } function father(n,c){ this.name = n; this.child = c; this.listen = function(t){ if(t==0){ console.log(this.child.name + "哭了,"+this.name+"看孩子") }else{ console.log(this.child.name + "睡了,"+this.name+"打麻將") } } } var c = new child("大寶"); var t = c.type(); var m = new mather('大寶媽',c); m.listen(t); var f = new father('大寶爸',c); f.listen(t);
六、代理模式
function girl(name){ this.name = name; } function boy(girl){ this.girl = girl; this.sendGift = function(gift){ alert("你好,漂亮的"+this.girl.name+",這是我送你的:"+gift); } } function porxyLitterBrother(girl){ this.girl = girl; this.send = function(gift){ this.g = gift; gift = "一個擁抱"; var b = new boy(girl); b.sendGift(gift); } this.init = function(){ console.log(this.g) } } var g = new girl("翠花"); var p = new porxyLitterBrother(g); p.send("鑽戒") p.init()
七、適配器模式
適配器模式就是將原本不具有某些功能的對象,在使用這些功能時,不出問題,並讓某些不具有特徵的屬性,變得特徵
demo:
電子工廠:手機,平板
手機:打電話,玩遊戲
平板:玩遊戲
測試模組只有一個:想能測平板又能測手機,還正確測試,不出問題
// 應用場景 // 讓某個不具有明顯特徵的功能,變得有特徵 function phone(){ this.name = "phone"; this.call = function(){ console.log(this.name + "可以打電話"); }; this.game = function(){ console.log(this.name + "可以打遊戲"); }; } function pad(){ this.name = "pad"; this.game = function(){ console.log(this.name + "可以打遊戲") } } function text(obj){ if(obj.call){ obj.call(); }else{ console.log(obj.name+"沒有打電話的功能"); }; if(obj.game){ obj.game(); }else{ consloe.log(obj.name+"沒有打遊戲的功能"); } } var p1 = new phone(); text(p1); var p2 = new pad(); text(p2);
八、抽象工廠模式
在工廠模式中,將多個實例的相同屬性或方法,再次抽象成一個公共對象,從公共對象上,再次創建出具體的實例。
demo:
造車廠:製造汽車
汽車需要車架子:輪子,引擎。
我們可以將相同的部分放一起,然後通過添加其他不同的零件,生產不行型號的車。
var f = (function (){ //抽象工廠模式主要就是這個公共對象,模具對象 function car(wheel,engine){ //內部配置函數,可以提供配置功能。 this.wheel = wheel; this.engine = engine; } return function(wheel , engine){ // 構造器, 負責創建對象。 return new car(wheel,engine); // 這是對外提供的介面,負責和外部需求連接。 } })(); var car1 = f("15","V8"); var car2 = f("13","V10"); //每次執行都會有這個公共對象,執行這個公共對象,獲得一個新的對象 console.log(car1);//一個新的car對象 console.log(car2);//一個新的car對象 console.log(car1 == car2);//false
//這種模式,就是所謂的抽象工廠模式。
九、策略模式
策略:計劃,規劃,預製要做的事情,不同的情況訂製不同的計劃。
function fn(n){ if(n < 10 || n.length < 1){ return "0"+n }else{ return n; } } var num = fn(4); console.log(num)//04
總結:這就是我們平時常用的九種設計模式,每種設計模式其實都是見名識義,很多種設計模式我們也只會在寫一些大型的項目的時候我們才會使用,每一種設計模式我們都需要根據當前的實際需求,來判斷我們該使用哪種設計模式,使我們的程式碼解構更強。