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>

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