咱們你們一聽到設計模式就感受設計模式是一個高端的東西,到底什麼是設計模式呢?其實設計模式也就是咱們的前輩在寫代碼的時候遇到的問題,提出的解決方案,爲了方便人與人之間的交流,取了個名字,叫作設計模式。css
本文今天主要寫一部分建立型設計模式,建立型設計模式呢就是我門建立對象的時候的一種模式。廢話很少說了,直接上代碼和解釋吧。html
目的:單例模式的目的是爲了解決全局命名空間污染,衝突。es6
1 function g(id) { 2 return document.getElementById(id); 3 } 4 5 function css(id,key,value) { 6 g(id).style[key] = value; 7 } 8 9 function html(id,value) { 10 g(id).innerHTML = value; 11 } 12 13 function on(id,type,fn) { 14 g(id)['on'+type] = fn; 15 }
上面的代碼在頁面中添加了許多的變量,往後其餘的人要爲頁面添加新的需求時,增長代碼或者是重寫了代碼,好比這個on方法,那麼就會和其餘人的代碼衝突,因此能夠用單例模式來書寫一下代碼。編程
代碼樣式以下設計模式
1 //工程師 z 2 var xiaoz = { 3 g : function (id) { 4 return document.getElementById(id); 5 }, 6 css : function (id,key,value) { 7 g(id).style[key] = value; 8 } 9 }; 10 //工程師 y 11 var xiaoy = { 12 css : function () { 13 //一堆代碼 14 } 15 };
這樣幾我的之間的代碼就不會相互影響了,上面的代碼調用的方式以下。dom
1 xiaoz.g('box'); ide
在單例模式中還有另一種,關於靜態變量在es6才提出來的const,靜態變量是一旦肯定就沒法修改的量,可是如今es6的兼容性還不是太好,在單例模式中一樣能夠模擬這種能夠定義可是沒法改變的變量。模塊化
1 var xiao = (function(){ 2 var bian = { 3 a : 1, 4 b : 2, 5 fn : function(){ 6 console.log('這裏是fn') 7 } 8 }; 9 return { 10 getdata:function(val){ 11 return bian[val]; 12 } 13 } 14 })(); 15 //裏面的變量只能獲取 不能修改
簡單工廠模式不是解決命名空間問題的,是爲了解決建立對象的。函數
看下面的代碼例子this
//牛排 function Steak(){ this.price = 30; this.time = 20; } //炒飯 function FriedRice(){ this.price = 10; this.time = 5; } //麪條 function Noodles(){ this.price = 15; this.time = 10; } var a = new Steak(); var b = new FriedRice(); var c = new Noodles(); //歸類 開了個飯店a賣牛排 又開了個飯店b 賣炒飯 //開一家就能夠了
上面的代碼就至關於咱們開飯店,咱們開了一家賣牛排的店,又開了一家賣炒飯的店,而後又開了一家賣麪條的店,雖然咱們比較有錢,可是其實開一家店賣這幾樣東西就能夠了
因此咱們歸類,看下面的代碼就是簡單工廠模式
1 function Shop(name){ 2 var o = null; 3 switch(name){ 4 case 'Steak' : 5 o = new Steak(); 6 break; 7 case 'FriedRice' : 8 o = new FriedRice(); 9 break; 10 case 'Noodles' : 11 o = new Noodles(); 12 break; 13 } 14 return o; 15 } 16 17 new Shop('Noodles'); 18 //好處 好比手機裏面有不少軟件 軟件歸類 好找 不用記什麼是什麼了 19 20 //缺點 這個拓展有點很差
至於說缺點拓展性很差的理由呢就是,好比咱們又要開一家烤鴨店的話,咱們不只要定義一個烤鴨的構造函數,並且還要在工廠中增長一個判斷,這個我就不寫了,下面看看工廠模式就解決了這個問題
1 function Shop(name) { 2 console.log(this); 3 return new this[name](); 4 } 5 6 7 Shop.prototype = { 8 Steak : function () { 9 this.price = 30; 10 this.time = 20; 11 }, 12 FriedRice : function () { 13 this.price = 30; 14 this.time = 20; 15 }, 16 Noodles : function () { 17 this.price = 30; 18 this.time = 20; 19 } 20 }; 21 22 var obj = new Shop('FriedRice'); 23 24 console.log(obj);
上面的若是在拓展的話直接在原型上拓展就能夠了,很是方便。也很是好用。
原型模式是爲了解決....
好了先不說解決什麼,咱們來幾個需求
好比說咱們須要寫一個輪播圖,咱們就開始寫了,樣式就不寫了哈。
<div>
<ul>
<li><img src="" alt=""></li>
<li><img src="" alt=""></li>
<li><img src="" alt=""></li>
<li><img src="" alt=""></li>
</ul>
</div>
1 var oUl = document.getElementsByTagName('ul')[0]; 2 aLi = document.getElementsByTagName('li'); 3 4 var index = 0, 5 len = aLi.length; 6 7 function Fn() { 8 oUl.style.left = 600*index; 9 index %= len; 10 index++; 11 } 12 13 setInterval(Fn,1000);
應該是能夠實現的吧,沒有實驗,若是有錯誤指正一下。有問題又來了,若是又有一個新的輪播圖須要在輪播圖上面添加上兩個前進後退按鈕,那麼你會怎麼作,你可能會想反正代碼也很少我直接拿過來複制,在添加幾行代碼不就完了嗎,是這樣的沒錯,但是你想一想若是有好多的輪播特效,你是否是每一種特效都須要複製一下上面的代碼呢,他們都是重複的,因此咱們能夠用原型模式把上面的代碼來繼承下來。
1 var oUl = document.getElementsByTagName('ul')[0], 2 aLi = document.getElementsByTagName('li'), 3 div = document.querySelector('div'); 4 5 var index = 0; 6 7 //基本滾動 8 function Banner(div){ 9 this.dom = div; 10 this.init(); 11 } 12 //原型 13 Banner.prototype.init = function(){ 14 var oUl = this.dom.getElementsByTagName('ul')[0]; 15 var aLi = oUl.getElementsByTagName('li'), 16 len = aLi.length; 17 setInterval(function () { 18 oUl.style.left = 600*index; 19 index %= len; 20 index++; 21 },1000) 22 }; 23 24 // 那麼這個時候只須要繼承過來 而後再這基礎之上進行擴展 簡單點就是原型繼承 25 function F() {} 26 F.prototype = Banner.prototype; 27 28 function Banner2(dom) { 29 Banner.call(this,dom); 30 this.goudan(); 31 } 32 Banner2.prototype = new F(); 33 Banner2.prototype.Slide = function () { 34 console.log('滾動'); 35 }; 36 37 new Banner2(div);
代碼可能不是那麼嚴謹,這裏你知道大概的目的是什麼就能夠了,你還能夠在他的原型上面拓展出來好多其餘特效,固然這種模式不只僅應用於輪播圖特效,是爲了代碼的複用問題。
好比咱們在工做需求中,需求常常發生變更,有時候一些變化可能會引發許多代碼的修改,這時咱們的解決方案出來了,能夠把一個對象分步驟建造出來,實現的功能分步驟單例出來。看一下下面的小例子
發佈簡歷
1 //簡歷 : 人,姓名,職位 2 var Human = function(param){ 3 //技能 4 this.name = param || '保密'; 5 }; 6 Human.prototype.getname = function(){ 7 return this.name; 8 }; 9 var Work = function(work){ 10 switch(work){ 11 case 'code': 12 this.work = '工程師'; 13 this.workDescript = '天天沉迷於編程'; 14 break; 15 case 'UI': 16 this.work = '設計師'; 17 this.workDescript = '設計是一種態度'; 18 break; 19 case 'teach': 20 this.work = '教師'; 21 this.workDescript = '分享也是一種態度'; 22 break; 23 default: 24 this.work = work; 25 this.workDescript = '對不起咱們還不清楚你的職位描述'; 26 } 27 }; 28 29 //最終建立的對象 30 var Person = function(skill,work){ 31 var _Person = new Human(skill); 32 _Person.work = new Work(work); 33 return _Person; 34 }; 35 //這樣就能夠 36 Person('xiaoz',teach);
前面幾種工廠模式,他們都有一個共同的特色,就是建立的結果都是一個完整的個體,對建立的過程不得而知,咱們只知道獲得的建立結果,而在建造者模式當中,咱們關心的是對象的建立過程,由於咱們一般將建立對象的類模塊化,這樣使被建立的類的每個模塊均可以獲得靈活的額運用與高質量的複用,在這個過程當中咱們又組合成一個完整的個體。
這種方式對於總體對象又變得複雜了一些,因此若是對象很小,咱們最好仍是建立總體對象。
若是你閱讀了本文章有了一些收穫,我會感到很是開心,因爲能力有限,文章有的部分解釋的不到位,但願在之後的日子裏能慢慢提升本身能力,若是不足之處,還望指正。
在接下來的時間,我還會把其餘的一些經常使用的設計模式分享給你們,但願能夠支持一下。