# 代理模式

# 介绍

  • 使用者无权访问目标对象
  • 中间加代理,通过代理做授权和控制

# 示例

  • 科学上网,访问 github.com
  • 明星经纪人

# 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()

# 场景

# 网页事件代理

    let div1 = document.getElementById('div1')
    // 不可能每个a标签加一个点击事件,通过给父级添加一个代理实现
    div1.addEventListener('click', function (e) {
      let target = e.target
      // 判断如果点击的是a标签
      if (target.nodeName === 'A') {
        console.log(target.innerHTML)
      }
    })

# jQUery $.proxy

    $('#div1').click(function () {
      const _this = this
      setTimeout(function () {
        // console.log(this)// windows
        // $(this).css('background-color', 'yellow')
        $(_this).css('background-color', 'yellow')
      }, 1000);
    })
    // 或者使用$.proxy
    $('#div1').click(function () {
      setTimeout($.proxy(function () {
        $(this).css('background-color', 'yellow')
      }, this), 1000);
    })

# ES6 Proxy

// 明星
let star = {
  name: 'jiegiser',
  age: 18,
  phone: '88888888888'
}

// 经纪人
let agent = new Proxy(star, {
  get: function(target, key) {
    if(key === 'phone') {
      // 返回经纪人自己的电话
      return 33333333333
    }
    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
      }
    }
  }
})

// test
console.log(agent.name)
console.log(agent.age)
console.log(agent.phone)
console.log(agent.price)

agent.customPrice = 150000
console.log(agent.customPrice)

# 设计原则

  • 代理类和目标类分离,隔离开目标类和使用者
  • 符合开放封闭原则

评 论:

更新: 11/21/2020, 7:00:56 PM