美文网首页
JS设计模式-代理模式

JS设计模式-代理模式

作者: 林海_Mense | 来源:发表于2019-03-16 15:39 被阅读0次
介绍
  • 使用者无权访问目标对象
  • 中间加代理,通过代理做授权和控制
    比如说公司的内网,当我们在家的时候也是需要一个代理才能连接访问内网的信息。
示例
  • 科学上网,访问 github.com
  • 明星的经纪人 (大多数情况下咱们不可能直接联系明星)
UML类图
UML类图-代理模式

代码说明

class ReadImg {
  constructor(filename) {
    this.filename = filename;
    this.loadFromDisk() //初始化即从硬盘中加载, 模拟
  }
  display() {
    console.log('display... ' + this.filename);
  }
  loadFromDisk() {
    console.log('loading... ' + this.filename);
  }
}

class ProxyImg {
  constructor(filename){
    this.realImg = new ReadImg(filename);
  }
  display() {
    this.realImg.display();
  }
}

// test
let proxyImg = new ProxyImg("1.png");
proxyImg.display();
场景
  • 网页事件代理(事件委托)
  • Jquery $.proxy
  • ES6 Proxy
事件委托代码实现
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>前端设计模式 - 代理模式</title>
</head>
<body>
    <div id="app">
        <p>aaa</p>
        <p>bbb</p>
        <p>ccc</p>
        <p>ddd</p>
    </div>
</body>
<script>
    const appDom = document.querySelector("#app");
    appDom.addEventListener("click", (e)=>{
        const target = e.target;
        if(target.nodeName="P"){
            console.log(target,target.innerHTML)
        }
    })
</script>
</html>
$.proxy

本示例不考虑es6箭头函数解决this指向问题,假设我们维护的还是一个用Jquery的老项目。

//正常的this使用
$('#myElement').click(function() {
    // 这个this是我们所期望的,当前元素的this.
    $(this).addClass('aNewClass');
});


//并非所期望的this
$('#myElement').click(function() {
    setTimeout(function() {
          // 这个this指向的是settimeout函数内部,而非之前的html元素
        $(this).addClass('aNewClass');
    }, 1000);
});

这时候通常做法是这样的

$('#myElement').click(function() {
    var that = this;   //设置一个变量,指向这个需要的this
    setTimeout(function() {
          // 这个this指向的是settimeout函数内部,而非之前的html元素
        $(that).addClass('aNewClass');
    }, 1000);
});

但是,在使用了jquery框架的情况下, 有一种更好的方式,就是使用$.proxy函数。

jQuery.proxy(),接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文(context )语境。
上面的例子使用这种方式就可以修改成:

$('#myElement').click(function() {
    setTimeout($.proxy(function() {
        $(this).addClass('aNewClass');  
    }, this), 1000);
});
明星经纪人
// 明星
let star = {
    // name和age可以返回,点化就需要经纪人代理给拦截了。
    name: '张XX',
    age: 25,
    phone: '13910733521'
}

// 经纪人
let agent = new Proxy(star, {
    get: function (target, key) {
        if (key === 'phone') {
            // 返回经纪人自己的手机号
            return '18611112222'
        }
        if (key === 'price') {
            // 明星不报价,经纪人报价
            return 120000
        }
        return target[key]
    },
    set: function (target, key, val) {
        if (key === 'customPrice') {
            if (val < 100000) {
                // 最低 10w
                throw new Error('价格太低')
            } else {
                target[key] = val
                return true
            }
        }
    }
})

// 主办方去找明星的经纪人
console.log(agent.name)  // 经纪人返回明星的姓名
console.log(agent.age)  // 明星的姓名
console.log(agent.phone) // 经纪人的点化,经纪人拦截了phone。
console.log(agent.price)  // 明星搞艺术,不谈钱,经纪人谈钱。

// 想自己提供报价(砍价,或者高价争抢)
agent.customPrice = 150000
// agent.customPrice = 90000  // 报错:价格太低
console.log('customPrice', agent.customPrice)
设计原则验证
  • 代理类和目标类分离,隔离开目标类和使用者
  • 符合开放封闭原则
代理模式 VS 适配器模式
  • 适配器模式: 提供一个不同的接口(比如不同版本的插座插口)
  • 代理模式: 提供一模一样的接口
代理模式 VS 装饰器模式
  • 装饰器模式: 扩展功能,原有功能不变且可直接使用,扩展功能不冲突原有功能。
  • 代理模式: 显示原有功能,但是经过限制或者阉割之后的
  1. 本文资料来自慕课网-双越老师-Javascript 设计模式系统讲解与应用视频课程。
  2. $.proxy 代码部分来自于浪漫小生博客

相关文章

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

  • 2021-11-17 - 学习记录

    适配器模式 - js: 代理模式 - js 组合模式 - js

  • JS设计模式-代理模式

    虚拟代理 虚拟代理是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行 图片懒加载 合并http请求 如果有...

  • JS设计模式-代理模式

    介绍 使用者无权访问目标对象 中间加代理,通过代理做授权和控制比如说公司的内网,当我们在家的时候也是需要一个代理才...

  • js代码题

    js对象的深度克隆 js数组去重 js常用设计模式的实现思路,单例,工厂,代理,装饰,观察者模式等

  • 《JS设计模式》读书笔记(一)

    标签:JS 设计模式 《JS设计模式》读书笔记(二) 《JS设计模式》读书笔记(三) 《JS设计模式》读书笔记(四...

  • Mybatis代理设计模式(Proxy)与编程实现原理

    最易懂设计模式解析适配器设计模式模板方法设计模式Mybatis多级代理 1. 认识代理模式 1.1 模式定义 给某...

  • 模板方法设计模式(Template Method)

    最易懂设计模式解析适配器设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识模板方法模式 1.1 ...

  • 适配器设计模式(Adapter)

    最易懂设计模式解析模板方法设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识适配器模式 1.1 ...

  • 理解java的代理模式和动态代理

    代理模式 代理模式是23种设计模式之一,属于结构型模式。代理模式是最常见也是最常用的模式之一,只不过有很多设计模式...

网友评论

      本文标题:JS设计模式-代理模式

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