js的設計模式


  起源:

 設計模式並非是軟件開發中的專業術語。實際上‘模式’最早誕生於建築學。20世紀30年代,哈佛大學建築學博士和他的研究團隊花了約20年的時間,

研究了為解決同一問題而設計出不同結構建築,從中發現了那些高質量設計中的相似性,並且用‘模式’來指代相似性。

設計模式:在面向對象軟件設計中針對特定問題的簡潔而優雅的解決方案。

 單例模式:

  保證一個類只有一個實例,並提供一個訪問它的全局訪問點,如window對象。當我們單擊登錄按鈕的時候,頁面出現

一個登錄浮窗,這個懸浮窗是唯一的,無論點擊多少次登錄按鈕,這個浮窗都只會被創建一次,這個登錄的浮窗就適合用單例模式創建。

  var CreateDiv=(function(){
                var instance;
                var CreateDiv=function(html){
                     console.log(instance)
                    if(instance){ //instance參數,如果沒有則執行下面的,如果有則直接返回
                        return instance;
                    }
                    this.num=html;//this.num 為CreateDiv對象的一個屬性   html為實例化的時候傳進的參數
                    this.init();
                    console.log(this)
                    return instance = this;//返回CreateDiv對象
                }
                CreateDiv.prototype.init=function(){
                    var div=document.createElement('div');
                    div.innerHTML=this.num;//將num屬性寫在div里面
                    document.body.appendChild(div);
                }
                return CreateDiv;
            })();
            var a = new CreateDiv('a');
            var b = new CreateDiv('b');//因為只會被創建一次,所以實例化b的時候a已經實例化過了,所以CreateDiv對象是沒有變化的
            a==b;//true
            a===b;//true

 

代理模式定義

    為一個對象提供一個代用品或占用符,以便控制對它的訪問。很多明星都有自己的經紀人,比如開演唱會經紀人會代替明星細節和談好薪酬之后

再跟明星簽合同。即核心是當客戶不方便直接訪問一個對象或者不滿足需要的時候,提供一個替身對象控制了這個對象的,替身對象對請求最初一些

處理之后再把請求轉交給本體請求。

  var myImage=(function(){
                var imgNode=document.createElement('img');
                document.body.appendChild(imgNode);
                return {
                    setSrc:function(src){
                        imgNode.src=src;
                    }
                }
            })();
            var proxyImage=(function(){
                var img=new Image();
                img.onload=function(){
                    myImage.setSrc(this.src)//傳入的圖片路徑
                };
                return{
                    setSrc:function(src){
                        myImage.setSrc('load.gif');
                        img.src=src;//把傳入的圖片路徑傳給真正的對象,顯示在頁面上
                    }
                }
            })()
            proxyImage.setSrc();

 

命令模式

  命令模式中的命令指的是一個執行某些特定事情的指令,有時候需要向某些特定事情的指令。常見的應用場景有時候需要向某些對象發送請求,

但是並不知道請求的接受者是誰,也不知道被請求的操作是什么。假如我們去快餐店,我們可以點餐取消餐,但是我們並不用關心廚師是誰,怎么做。

    var makeCommand=function(receiver,state){
                return function(argument){
                    receiver[state]();//調用方法
                }
            }
            var Ryn={  //對象上面的三個屬性
                attack:function(){
                    console.log('攻擊')
                },
                defense:function(){
                    console.log('防御');
                },
                crouch:function(){
                    console.log('蹲下');
                }
            }
            var command=makeCommand(Ryn,'attack');
            command();//攻擊

 

發布訂閱模式

  發布訂閱模式又稱觀察者模式,它定義對象間的一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴它的對象都將得到通知。現實生活中,

如我們去售樓中心,服務人員A接待了我們,然后再有客戶找到A,這個時候暫時沒房了,等到有房的時候不可能服務人員A挨個打電話通知,而是訂閱A的

公共服務提醒。

      (function($){
                var o = $({});
                $.subscribe=function(){
                    o.on.apply(o,arguments);
                }
                $.unsubscribe=function(){
                    o.off.apply(o,arguments);
                }
                $.publish=function(){
                    o.trigger.apply(o,arguments);
                }
            })(jQuery)

 

 職責鏈模式

使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關系,將這些關系連成一條鏈,並沿着這條鏈傳遞該請求,直到一個對象處理它為止。

現實生活中,如我們坐公交車人太多,我們把公交卡交給售票員,讓前面的人不停的往前遞,直到售票員刷卡結束。

    var fn1=function(data){
                if(data==1){
                    console.log('fn1->'+data);
                }else{
                    return 'next';
                }
            }
            var fn2=function(data){
                    console.log('fn2->'+data);
                    return 'next';
            }
            var fn3=function(data){
                    console.log('fn3->'+data);
                    console.log('done');
            }
            Function.prototype.after=function(fn){
                var self=this;
                return function(){
                    var ret=self.apply(this,arguments);// 當前函數本身
                    if(ret=='next'){
                        return fn.apply(this,arguments); //fn下一個要直執行的函數
                    }
                    return ret;
                }
            }
            var order=fn1.after(fn2).after(fn3);
            order(3);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM