JavaScript設計模式4---迭代器模式、備忘錄設計模式、觀察者模式

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>設計模式4</title>
    </head>
    <body>
        <script type="text/javascript">


//十一、迭代器模式可以統一遍歷集合對象的方式,並且十分容易擴展,開發者可以十分容易的讓自定義的集合支持統一提供的迭代器
//使用者:統一的接口可以更加便於進行代碼的組織和管理
    
    //1、定義一個迭代器協議
    var MyIterator = {
        next:function(){
            throw '必須實現next'
        }
    }
    //2、迭代器方法
    function tool(obj,callback){
        var item=obj.next();
        while(item!==undefined){
            callback(item);
            item=obj.next();

        }
    }
    //3、實現迭代器的對象
    var  myObj = {
        name:'Owen',
        age:'30',
        subject:'typescript',
        teaching:function(){
            console.log('teaching')
        },
        _keys:['name','age','subject'],
        _tip:0,

        next:function(){
            return this._keys[this._tip++]
        }

    }
    
    myObj.__proto__=MyIterator;
    
    //驗證
    tool(myObj,function(item){console.log(item)});// name  age  subject
    // 當有新的集合對象需要支持迭代時,只需要在其中實現next方法,tool函數就能進行很好的工作了
        </script>
        <script type="text/javascript">

 


//十二、備忘錄設計模式(備份設計模式)
 //用來進行對象內部狀態的備份:備份的可能不是完整的對象,我們使用文本編輯器時可以撤銷,瀏覽器可以返回,都是備忘錄模式的實際應用
 //場景狀態恢復,有時也可以用來緩存網絡數據
 var EditProtocol = {//核心的協議對象,任何需要支持撤銷操作的對象,只要以它爲原型並實現重寫的方法,就可以完成狀態的保存與恢復
     _stateArray:[],
     revoke:function(){
         this._refresh(this._stateArray.pop())
     },
     save:function(){
         this._stateArray.push(this._state())
     },
     _refresh:function(){
         throw '必須實現_refresh'
     },
     _state:function(){
         throw '必須實現_state'
     }
 }
 var teacher = {
     name:'Owen',
    age:30,
    subject:'typescript',
    _refresh:function(state){
        this.name=state.name;
        this.age = state.age;
        this.subject=state.subject;
    },
    _state:function(){
        return {
            name:this.name,
            age:this.age,
            subject:this.subject
        }
    }
 }
 
 teacher.__proto__=EditProtocol;//以EditProtocol爲原型
 teacher.save();//保存
 console.log(teacher.name,teacher.age,teacher.subject)// Owen 30 typescript
 teacher.name='jack';
 teacher.age=45;
 console.log(teacher.name,teacher.age,teacher.subject)//jack 45 typescript
 teacher.revoke();//撤銷
 console.log(teacher.name,teacher.age,teacher.subject);// Owen 30 typescript
        </script>

 


        <script type="text/javascript">
//十三、觀察者模式

vue使用了觀察者模式:參閱:https://www.cnblogs.com/qisi007/p/11002583.html
//用來實現 訂閱邏輯,當對象出現一對多的交互關係時,也可以使用觀察者模式來處理
//觀察者模式一般右服務端和客戶端兩方組成,客戶端通過訂閱來監聽服務端的信息,由服務端發送信息給已經訂閱的客戶端
  
  //教務處作爲服務端,會給老師發佈任務, 當教師接收到任務後,開始執行教學任務
  var Service = {
      _customer:new Set(),
      addObserver:function(obj,func){
          this._customer.add({obj:obj,func:func})
      },
      deleteObserver:function(obj){
          var has;
          this._customer.forEach(function(object){
              if(object.obj===obj){
                  has=object
              }
          });
          if(has!==undefined){
              this._customer.delete(has)
          }
      },
      publish:function(msg){
          console.log("發佈了訂閱消息");
          this._customer.forEach(function(obj){
              obj.func.call(obj.obj,msg)
          })
      }
      
  }
  
  var teacher1 = {// 觀察者1
         name:'Owen',
         teach:function(msg){
              console.log(this.name+"開始教學"+msg);//Owen開始教學phyon
         }
  }
   var teacher2 = {// 觀察者1
         name:'Jack',
         teach:function(msg){
              console.log(this.name+"開始教學"+msg);//Jack開始教學phyon
         }
  }
   
   // 調用 服務端添加訂閱的方法,即給相關老師發教學任務(教師通過訂閱監聽)
   Service.addObserver(teacher1,teacher1.teach)
   Service.addObserver(teacher2,teacher2.teach)
   
   //服務端發佈訂閱消息
   Service.publish('phyon')//發佈了訂閱消息     Owen開始教學phyon Jack開始教學phyon
  
   //調用服務端刪除訂閱的方法,即刪除對應的觀察者
   Service.deleteObserver(teacher1);// 刪除一個訂閱者
   
   //服務端發佈訂閱消息(發消息給已經訂閱的觀察者)
   Service.publish('javascript')//發佈了訂閱消息   Jack開始教學javascript
        </script>
    </body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章