日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

模式(一)javascript设计模式

發(fā)布時(shí)間:2023/12/10 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模式(一)javascript设计模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

模式有三種:Architectural Pattern、Design Pattern、Coding Pattern,即:框架模式、設(shè)計(jì)模式、編程模式。本文主要講解javascript中的設(shè)計(jì)模式,好的設(shè)計(jì)模式能夠提高代碼的重用性,可讀性,使代碼更容易的維護(hù)和擴(kuò)展。本文適合有一點(diǎn)javascript基礎(chǔ),對(duì)javascript的概念有所了解。

一、單例模式:

?單例模式是javascript中最常用的模式,它是將自己的代碼放在一個(gè)命名空間下,這樣的好處是可以減少使用全局變量,在多人協(xié)同開發(fā)時(shí)也能避免命名沖突等問題。這樣的好處是維護(hù)起來非常方便,如下例:

1 var m = { 2 name: 'dog', 3 action: function() { 4 console.log(this.name); 5 } 6 }; 7 m.action();//調(diào)用

?

或者

1 var dog = function() { 2 this.name = 'dog'; 3 this.action = function() { 4 return console.log(this.name); 5 }; 6 action(); 7 }; 8 dog(); //調(diào)用

?

工廠模式:

工廠模式就是將對(duì)象的方法創(chuàng)建交給外部對(duì)象,這樣的好處就是解決了對(duì)象之間的相互影響、即耦合,避免了使用new來實(shí)例化對(duì)象,有助于創(chuàng)建模塊化的代碼,維護(hù)起來也方便。?工廠模式分為簡(jiǎn)單工廠模式和抽象工廠模式,下面介紹簡(jiǎn)單工廠模式:

1 var m = {}; 2 m.action = function() { 3 console.log('dog'); 4 }; 5 var demo = function() { 6 m.action(); 7 }; 8 demo()//調(diào)用

?

抽象工廠模式先設(shè)計(jì)一個(gè)抽象類,這個(gè)類不能被實(shí)例化,只能用來派生子類,最后通過對(duì)子類的擴(kuò)展實(shí)現(xiàn)工廠方法。如下:

1 var f = function() {}; 2 f.prototype = { 3 c: function() { 4 throw new Error('can\'t use this method');//如果調(diào)用此方法會(huì)報(bào)錯(cuò),因?yàn)樗怯脕砼缮宇惒荒軐?shí)例化 5 } 6 }; 7 var e = function() { 8 f.call(this); 9 } 10 e.prototype = new f(); 11 e.prototype.constructor = e; 12 e.prototype.c = function() { 13 console.log('this method is redefine'); 14 } 15 // 調(diào)用 16 var demo = new e(); 17 demo.c();

?

橋接模式:

橋接模式是將抽象與實(shí)現(xiàn)隔離,一遍二者獨(dú)立變化。在設(shè)計(jì)一個(gè)javascript API的時(shí)候,它可以用來弱化類和對(duì)象之間的耦合。它還可以用來把多個(gè)類聯(lián)接在一起。例如:

1 var class1 = function(a,b,c) { 2 this.a = a; 3 this.b = b; 4 this.c = c; 5 }; 6 var class2 = function(d) { 7 this.d = d; 8 }; 9 var demo = function(a,b,c,d) { 10 this.one = new Class1(a,b,c); 11 this.two = new Class2(d); 12 };

?

組合模式:

組合模式可以用一條命令在多個(gè)對(duì)象上激發(fā)復(fù)雜的或遞歸的行為。好處是可以用同樣的發(fā)放處理對(duì)象的集合與其中的特定子對(duì)象,也可以用來把一批子對(duì)象組織成樹形結(jié)構(gòu),并且使整個(gè)樹都可被遍歷。如下:

1 // DynamicGallery Class 2   var DynamicGallery =function (id) { // 實(shí)現(xiàn)Composite,GalleryItem組合對(duì)象類 3   this.children = []; 4   this.element = document.createElement('div'); 5   this.element.id = id; 6   this.element.className ='dynamic-gallery'; 7   } 8   DynamicGallery.prototype = { 9   // 實(shí)現(xiàn)Composite組合對(duì)象接口 10   add: function (child) { 11   this.children.push(child); 12   this.element.appendChild(child.getElement()); 13   }, 14   remove: function (child) { 15   for (var node, i =0; node =this.getChild(i); i++) { 16   if (node == child) { 17   this.children.splice(i, 1); 18    break; 19   } 20   } 21   this.element.removeChild(child.getElement()); 22   }, 23   getChild: function (i) { 24   returnthis.children[i]; 25   }, 26   // 實(shí)現(xiàn)DynamicGallery組合對(duì)象接口 27   hide: function () { 28   for (var node, i =0; node =this.getChild(i); i++) { 29   node.hide(); 30   } 31   this.element.style.display ='none'; 32   }, 33   show: function () { 34   this.element.style.display ='block'; 35   for (var node, i =0; node = getChild(i); i++) { 36   node.show(); 37   } 38   }, 39   // 幫助方法 40   getElement: function () { 41   returnthis.element; 42   } 43   }

?

1 var GalleryImage =function (src) { // 實(shí)現(xiàn)Composite和GalleryItem組合對(duì)象中所定義的方法 2   this.element = document.createElement('img'); 3   this.element.className ='gallery-image'; 4   this.element.src = src; 5   } 6   GalleryImage.prototype = { 7   // 實(shí)現(xiàn)Composite接口 8   // 這些是葉結(jié)點(diǎn),所以我們不用實(shí)現(xiàn)這些方法,我們只需要定義即可 9   add: function () { }, 10   remove: function () { }, 11   getChild: function () { }, 12   // 實(shí)現(xiàn)GalleryItem接口 13   hide: function () { 14   this.element.style.display ='none'; 15   }, 16   show: function () { 17   this.element.style.display =''; 18   }, 19   // 幫助方法 20   getElement: function () { 21   returnthis.element; 22   } 23   } 1 var topGallery =new DynamicGallery('top-gallery'); 2   topGallery.add(new GalleryImage('/img/image-1.jpg')); 3   topGallery.add(new GalleryImage('/img/image-2.jpg')); 4   topGallery.add(new GalleryImage('/img/image-3.jpg')); 5   var vacationPhotos =new DyamicGallery('vacation-photos'); 6   for(var i =0, i <30; i++){ 7     vacationPhotos.add(new GalleryImage('/img/vac/image-'+ i +'.jpg')); 8   } 9   topGallery.add(vacationPhotos); 10   topGallery.show(); 11   vacationPhotos.hide();

?

門面模式:

門面模式常常是開發(fā)人員最親密的朋友,他幾乎是所有javascript庫(kù)的核心原則。門面模式有兩個(gè)作用:一是簡(jiǎn)化類的接口;二是消除類與使用它的客戶代碼之間的耦合。示例如下:

1 function a() { 2 3 } 4 function b() { 5 6 } 7 function ab() { 8 a(); 9 b(); 10 }

?

適配器模式:

適配器模式可以用來在現(xiàn)有接口和不兼容的類之間進(jìn)行適配。從表面上看,適配器模式很像門面模式,都對(duì)別的對(duì)象進(jìn)行包裝并改變其呈現(xiàn)的接口。二者的區(qū)別在與它們?nèi)绾胃淖兘涌?#xff0c;門面元素展現(xiàn)的是一個(gè)簡(jiǎn)化的接口,它并不提供額外的選擇,而且有時(shí)為了方便完成常見任務(wù)它還會(huì)做出一些假定。而適配器則要把一個(gè)接口轉(zhuǎn)換為另一個(gè)接口,它并不會(huì)過濾某些能力,也不會(huì)簡(jiǎn)化接口。

1 var str = { 2 a: 'a', 3 b: 'b', 4 c: 'c' 5 }; 6 function i(s1,s2,s3) { 7 console.log(s1 + ',' + s2 + ',' + s3); 8 } 9 function demo(o) { 10 i(o.a,o.b,o.c); 11 }

?

裝飾者模式:

裝飾者模式可用來透明地把對(duì)象包裝在具有同樣接口的另一個(gè)對(duì)象之中,裝飾者可以用于為對(duì)象添加功能,可以用來代替大量子類。裝飾者模式和組合模式有很多共同點(diǎn),它們都與所包裝的對(duì)象實(shí)現(xiàn)統(tǒng)一的接口并且會(huì)把任何方法條用傳遞給這些對(duì)象。可是組合模式用于把眾多子對(duì)象組織為一個(gè)整體,而裝飾者模式用于在不修改現(xiàn)有對(duì)象或從派生子類的前提下為其添加方法。如下:

1 var m = {}; 2 m.child = {}; 3 m.child.one = function() {}; 4 m.child.two = function() {};

?

?享元模式:

?享元模式最適合于解決因創(chuàng)建大量類似對(duì)象而累及性能的問題。通過把大量獨(dú)立對(duì)象轉(zhuǎn)化為少量共享對(duì)象,可以降低運(yùn)行web應(yīng)用程序所需的資源數(shù)量。

javascript設(shè)計(jì)模式中的示例:

1 //汽車登記示例 2   var Car =function(make,model,year,owner,tag,renewDate){ 3     this.make=make; 4     this.model=model; 5     this.year=year; 6     this.owner=owner; 7     this.tag=tag; 8     this.renewDate=renewDate; 9   } 10   Car.prototype = { 11     getMake:function(){ 12       returnthis.make; 13     }, 14     getModel:function(){ 15       returnthis.model; 16     }, 17     getYear:function(){ 18       returnthis.year; 19     }, 20     transferOwner:function(owner,tag,renewDate){ 21       this.owner=owner; 22       this.tag=tag; 23       this.renewDate=renewDate; 24     }, 25     renewRegistration:function(renewDate){ 26       this.renewDate=renewDate; 27     } 28   } 29   //數(shù)據(jù)量小到?jīng)]多大的影響,數(shù)據(jù)量大的時(shí)候?qū)τ?jì)算機(jī)內(nèi)存會(huì)產(chǎn)生壓力,下面介紹享元模式優(yōu)化后 30   //包含核心數(shù)據(jù)的Car類 31   var Car=function(make,model,year){ 32     this.make=make; 33     this.model=model; 34     this.year=year; 35   } 36   Car.prototype={ 37     getMake:function(){ 38       returnthis.make; 39     }, 40     getModel:function(){ 41       returnthis.model; 42     }, 43     getYear:function(){ 44       returnthis.year; 45     } 46   } 47   //中間對(duì)象,用來實(shí)例化Car類 48   var CarFactory=(function(){ 49     var createdCars = {}; 50     return { 51       createCar:function(make,model,year){ 52         var car=createdCars[make+"-"+model+"-"+year]; 53         return car ? car : createdCars[make +'-'+ model +'-'+ year] =(new Car(make,model,year)); 54       } 55     } 56   })(); 57   //數(shù)據(jù)工廠,用來處理Car的實(shí)例化和整合附加數(shù)據(jù) 58   var CarRecordManager = (function() { 59     var carRecordDatabase = {}; 60     return { 61       addCarRecord:function(make,model,year,owner,tag,renewDate){ 62         var car = CarFactory.createCar(make, model, year); 63         carRecordDatabase[tag]={ 64           owner:owner, 65           tag:tag, 66           renewDate:renewDate, 67           car:car 68       } 69     }, 70       transferOwnership:function(tag, newOwner, newTag, newRenewDate){ 71         var record=carRecordDatabase[tag]; 72         record.owner = newOwner; 73         record.tag = newTag; 74         record.renewDate = newRenewDate; 75       }, 76       renewRegistration:function(tag,newRenewDate){ 77         carRecordDatabase[tag].renewDate=newRenewDate; 78       }, 79       getCarInfo:function(tag){ 80         return carRecordDatabase[tag]; 81       } 82     } 83   })();

?

代理模式:

代理是一個(gè)對(duì)象,它可以用來控制對(duì)另一個(gè)對(duì)象的訪問。它與另外那個(gè)對(duì)象實(shí)現(xiàn)了同樣的接口,并且會(huì)把任何方法調(diào)用傳遞給那個(gè)對(duì)象。代理模式適合處理實(shí)例化比較費(fèi)時(shí)的本體,也適合處理那些需要較長(zhǎng)時(shí)間才能把數(shù)據(jù)載入用戶界面的類。

javascript設(shè)計(jì)模式中的示例:

1 var Publication =new Interface('Publication', ['getIsbn', 'setIsbn', 'getTitle', 'setTitle', 'getAuthor', 'setAuthor', 'display']); 2   var Book =function(isbn, title, author) { 3    //... 4   } 5   // implements Publication 6   implements(Book,Publication); 7 8   /* Library interface. */ 9   var Library =new Interface('Library', ['findBooks', 'checkoutBook', 'returnBook']); 10 11   /* PublicLibrary class. */ 12   var PublicLibrary =function(books) { 13    //... 14   }; 15   // implements Library 16   implements(PublicLibrary,Library); 17 18   PublicLibrary.prototype = { 19    findBooks: function(searchString) { 20    //... 21   }, 22   checkoutBook: function(book) { 23    //... 24    }, 25   returnBook: function(book) { 26    //... 27    } 28   }; 29 30   /* PublicLibraryProxy class, a useless proxy. */ 31   var PublicLibraryProxy =function(catalog) { 32    this.library =new PublicLibrary(catalog); 33   }; 34   // implements Library 35   implements(PublicLibraryProxy,Library); 36 37   PublicLibraryProxy.prototype = { 38    findBooks: function(searchString) { 39    returnthis.library.findBooks(searchString); 40   }, 41   checkoutBook: function(book) { 42    returnthis.library.checkoutBook(book); 43    }, 44    returnBook: function(book) { 45    returnthis.library.returnBook(book); 46    } 47   };

?

觀察者模式:

觀察者模式是一種管理人與其任務(wù)之間的關(guān)系的得力工具。觀察者模式中存在兩個(gè)角色:觀察者和被觀察者。這種模式的好處是你可以對(duì)程序中某個(gè)對(duì)象的狀態(tài)進(jìn)行觀察,并且在其發(fā)生改變時(shí)能夠得到通知。

1   var f1 =function(){ 2   //code 3   } 4   var f2 =function(){ 5   //code 6   } 7   addEvent(element,'click',f1); 8   addEvent(element,'click',f2) 9 10 11   element.onclick = f1; 12   element.onclick = f2;

?

命令模式:

命令模式可以用來對(duì)方法調(diào)用進(jìn)行參數(shù)化處理和傳送,經(jīng)這樣處理過的方法調(diào)用可以在任何需要的時(shí)候執(zhí)行。好處是可以用來消除調(diào)用操作的對(duì)象和實(shí)現(xiàn)操作的對(duì)象之間的耦合,使對(duì)象間的互動(dòng)方式更高的模塊化。這為各種具體的類更換帶來了極大的靈活性。

1 car Calculator={ 2   add:function(x,y){ 3    return x+y; 4   }, 5   substract:function(x,y){ 6    return x-y; 7   }, 8   multiply:function(x,y){ 9    return x*y; 10   }, 11   divide:function(x,y){ 12    return x/y; 13   } 14   } 15   Calculator.calc =function(command){ 16   return Calculator[command.type](command.op1,command.opd2) 17   }; 18   Calculator.calc({type:'add',op1:1,op2:1}); 19   Calculator.calc({type:'substract',op1:5,op2:2}); 20   Calculator.calc({type:'multiply',op1:5,op2:2}); 21   Calculator.calc({type:'divide',op1:8,op2:4});

?

職責(zé)鏈模式:

職責(zé)鏈模式是通過實(shí)現(xiàn)一個(gè)由隱式地請(qǐng)求進(jìn)行處理對(duì)象組成的鏈而做到的。可以用來消除請(qǐng)求的發(fā)送者和接收者之間的耦合

javascript內(nèi)部就使用了這種模式來處理事件捕獲和冒泡的問題。

職責(zé)鏈由多個(gè)不同類型的對(duì)象組成:發(fā)送者是發(fā)出請(qǐng)求的對(duì)象,而接收者則是接收請(qǐng)求并且對(duì)其進(jìn)行處理或傳遞的對(duì)象,請(qǐng)求本身有時(shí)也是一個(gè)對(duì)象,它封裝著與操作有關(guān)的所有數(shù)據(jù)。其典型的流程大致是:

  • 發(fā)送者知道鏈中第一個(gè)接收者,它向這個(gè)接收者發(fā)出請(qǐng)求。
  • 每一個(gè)接收者都對(duì)請(qǐng)求進(jìn)行分析,然后要么處理它,要么將其往下傳。
  • 每一個(gè)接收者知道的其他對(duì)象只有一個(gè),即它在鏈中的下家。
  • 如果沒有任何接收者處理請(qǐng)求,那么請(qǐng)求將從鏈上離開,不同的實(shí)現(xiàn)對(duì)此也有不同的反應(yīng),一般會(huì)拋出一個(gè)錯(cuò)誤。
  • 小結(jié):

      每種模式都有自己的優(yōu)點(diǎn),選擇一種適合自己業(yè)務(wù)的模式非常重要,能夠提高代碼的可讀性、可維護(hù)性等等,希望本文能夠?qū)δ阌兴鶐椭?/p>

    ?

    本文參考電子書《javascript設(shè)計(jì)模式》

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/xiyangbaixue/p/3902699.html

    總結(jié)

    以上是生活随笔為你收集整理的模式(一)javascript设计模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。