美文网首页
访问者模式

访问者模式

作者: 小宇cool | 来源:发表于2020-11-06 22:33 被阅读0次

    1. 访问者模式

    1.1 定义

    访问者模式( visitor),可以在不改变对象的前提向, 定义作用于对象的新操作.

    这个模式在面向对象强类型的语言中实现起来还是比较麻烦的, 但是在JavaScript这种弱类型语言来说实现起来非常简单, 因为访问者模式几乎是原生实现的

    1.2 作用

    1. 让对象的执行算法随着访问者的改变而改变
    2. 增强代码的可扩展性
    3. 将稳定数据结构和具体的操作进行解耦

    1.3 应用场景

    • 场景一
     let person = {
         // 给执行上下文this对象添加两个属性
         addAttr(){
             this.sex = '男';
             this.hobby = '打篮球'
         }
     }
     person.addAttr();
    let obj = {};
    obj.addAttr.call(obj)
    

    对象person拥有addAttr方法, 作用是个对象添加两个属性, 现在我们想给对象obj也添加这两个属性, 但我们不希望obj拥有addAttr方法, 此时我们可以使用call指定一下addAttr执行上下文this文为obj就可以解决,因此我们可以看到原生JavaScript属性访问者模式非常简单,借助call/apply就可以实现

    • 场景二

    JavaScript里面用很多原生的API都采用访问者模式的操作, 就比如数组相关的操作

    我们都知道函数的arguments对象是一个类数组对象,它有length属性,长得很像数组,但他不是一个真正的数组类型,所以它的原型上没有数组原型上许多好用的方法. 但是我们借用访问者模式来调用数组原生的各种好用的api;

      function add(){
          return Array.prototype.reduce.call(arguments,(total,next) =>{
              return total + next
          },0)
      }
    console.log(add(1, 2, 3, 4, 5, 6))// 21
    

    通过借用数组原型的reduce方法利用call方法指定对应的context为arguments, 并传入对应的回调函数参数,我们实现了对类数组的每一项累加操作.

    我们都知道数组用push方法, 现在我们希望普通对象x也有push方法也能添加数组属性和length

    let Visitor = {
          push(obj,value){
              return Array.prototype.push.call(obj,value)
          }
      }
    let x  = {};
    Visitor.push(x,111);
    console.info(x)//{0: 111, length: 1}
    

    上面的代码我们通过定义了Visitor访问者对象,并为其添加了push方法, 内部原理还是借用call方法来改变数组push方法的执行上下文, 实现人普通对象也能调用数组的push方法.

    总结: 通过访问者模式我们可以在对象的方法上定义新的操作, 而且不会改变原对象的原有形式,这种模式非常灵活,访问者模式使得我们可以很容易的在对象的方法上定义新操作,客户端只需要对应的访问者对象就能实现不同的操作.

    相关文章

      网友评论

          本文标题:访问者模式

          本文链接:https://www.haomeiwen.com/subject/svvxbktx.html