Skip to content

Latest commit

 

History

History
104 lines (91 loc) · 3.24 KB

05代理模式.md

File metadata and controls

104 lines (91 loc) · 3.24 KB

代理模式

又称委托模式,它为对象创造一个代理对象,以控制对目标对象的访问。例如:拦截器

  • 目标对象
  • 代理对象

代理模式分类:

  • 保护代理:对访问过滤
  • 虚拟代理:为开销很大的操作先占位,之后执行。例如:菊花图、低像素图、骨架屏等
  • 正向代理:代理客户端,通常用于vpn、缓存等
  • 反向代理:代理服务器,通常用于跨域、负载均衡、缓存等

解决问题:

  • 控制对目标对象的访问

优点:

  • 保护目标对象
  • 扩展目标对象
  • 解耦合:访问者和目标对象

缺点:

  • 增加复杂度

与其他设计模式区别:

  • 代理模式:原有功能不变,但一般经过限制访问
  • 装饰者模式:扩展功能,原有功能不变且可以直接使用
  • 适配器模式:功能不变,只转换了原有接口访问格式

实现代码

/* 明星 */
var SuperStar = {
    name: '小鲜肉',
    playAdvertisement: function(ad) {
        console.log(ad)
    }
}

/* 经纪人 */
var ProxyAssistant = {
    name: '经纪人张某',
    playAdvertisement: function(reward, ad) {
        if (reward > 1000000) {             // 如果报酬超过100w
            console.log('没问题,我们小鲜鲜最喜欢拍广告了!')
            SuperStar.playAdvertisement(ad)
        } else
            console.log('没空,滚!')
    }
}

ProxyAssistant.playAdvertisement(10000, '纯蒸酸牛奶,味道纯纯,尽享纯蒸')
// 输出: 没空,滚
// Proxy 版本
/* 明星 */
const SuperStar = {
    name: '小鲜肉',
    scheduleFlag: false,            // 档期标识位,false-没空(默认值),true-有空
    playAdvertisement(ad) {
        console.log(ad)
    }
}

/* 经纪人 */
const ProxyAssistant = {
    name: '经纪人张某',
    scheduleTime(ad) {
        const schedule = new Proxy(SuperStar, { 			// 在这里监听 scheduleFlag 值的变化
            set(obj, prop, val) {
                if (prop !== 'scheduleFlag') return
                if (obj.scheduleFlag === false &&
                  val === true) {                     // 小鲜肉现在有空了
                    obj.scheduleFlag = true
                    obj.playAdvertisement(ad)         // 安排上了
                }
            }
        })
        
        setTimeout(() => {
            console.log('小鲜鲜有空了')
            schedule.scheduleFlag = true              // 明星有空了
        }, 2000)
    },
    playAdvertisement(reward, ad) {
        if (reward > 1000000) {             // 如果报酬超过100w
            console.log('没问题,我们小鲜鲜最喜欢拍广告了!')
            ProxyAssistant.scheduleTime(ad)
        } else
            console.log('没空,滚!')
    }
}

ProxyAssistant.playAdvertisement(10000, '纯蒸酸牛奶,味道纯纯,尽享纯蒸')
// 输出: 没空,滚

ProxyAssistant.playAdvertisement(1000001, '纯蒸酸牛奶,味道纯纯,尽享纯蒸')
// 输出: 没问题,我们小鲜鲜最喜欢拍广告了!
// 2秒后
// 输出: 小鲜鲜有空了
// 输出: 纯蒸酸牛奶,味道纯纯,尽享纯蒸

参考

JavaScript 设计模式精讲 - 第三章 11代理模式