二、结构型设计模式

295 阅读2分钟

js

结构型设计模式

  1. 外观型设计模式
function addEvent(dom, type, fn) {
  if (dom.addEventListener) {
    dom.addEventListener(type, fn, false)
  } else if (dom.attachEvent) {
    dom.attachEvent('on' + type, fn)
  } else {
    dom['on' + type] = fn
  }
}
function getEvent(event) {
  return event || window.event
}
function getTarget(event) {
  var event = getEvent(event)
  
  return event.target || event.srcElement
}
function preventDefault(event) {
  var event = getEvent(event)
  
  if (event.preventDefault) {
    event.preventDefault()
  } else {
    event.returnValue = false
  }
}
  1. 适配器模式
var A = A || {}

A.g = function (id) {
  return document.getElementById(id)
}

A.on = function(id, type, fn) {
  // 如果传递参数为字符串则以 id 处理,否则以元素对象处理
  var dom = typeof id === 'string' ? this.g(id) : id
  
  // 标准 DOM2 级添加事件方式
  if (dom.addEventListener) {
    dom.addEventListener(type, fn, false)
    
    // IE DOM2 级添加事件方式
  } else if (dom.attachEvent) {
    dom.attachEvent('on' + type, fn)
    
    // 简单添加事件方式
  } else {
    dom['on' + type] = fn
  }
}
// 参数适配器

function doSomething(name, title, age, color, size, prize)

// vs

/**
 * obj.name: name
 * obj.title: title
 * obj.age: age
 * obj.color: color
 * obj.size: size
 * obj.prize: prize
*/
function doSomething(obj)
// 数据适配

var arr = ['JS', 'book', 2020.8.3]

// vs

var obj = {
  name: '',
  type: '',
  time: '',
}

function arrayToObject(arr) {
  return {
    name: arr[0],
    type: arr[1],
    time: arr[2],,
  }
}
  1. 代理模式
// 站长统计

var Count = (function() {
  // 缓存图片
  var _img = new Image()
  // 返回统计函数
  return function(params) {
    // 统计请求字符串
    var str = 'http://www.***.com/a.gif?'
    // 拼接请求字符串
    for (var i in params) {
     str += i '=' params[i]
    }
    
    // 发送统计请求
    _img.src = str
  }
})()

Count({ num: 10 })
  1. 装饰者模式
// 装饰者
function decorator(input, fn) {
  // 获取事件源
  var input = document.getElementById(input)
  
  // 若事件源已经绑定事件
  if (typeof input.onclick === 'function) {
    // 缓存事件源原有回调函数
    var oldClickFunc = inputx.onclick
    // 为事件源定义新的事件
    input.onclick = {
      // 事件源原有回调函数
      oldClickFunc()
      // 事件源新增回调函数
      fn()
    }
  } else {
    // 事件源未绑定事件,直接为事件源添加新增回调函数
    input.onclick = fn
  }
  
  // do otherthing
}
  1. 桥接模式
var spans = document.getElementByTagName('span')

spans[0].onmouseover = function() {
  this.style.color = 'red'
  this.style.background = '#ddd'
}
spans[0].onmouseout = function() {
  this.style.color = '#333'
  this.style.background = '#f5f5f5'
}

spans[1].onmouseover = function() {
  this.getElementByTagName('strong')[0].style.color = 'red'
  this.getElementByTagName('strong')[0].style.background = '#ddd'
}
spans[1].onmouseout = function() {
  this.getElementByTagName('strong')[0].style.color = '#333'
  this.getElementByTagName('strong')[0].style.background = '#f5f5f5'
}
// 提取共同点
// 抽象
function changeColor(dom, color, bg) {
  dom.style.color = color
  dom.style.background = bg
}

// 业务与业务逻辑之间的桥梁
var spans = document.getElementByTagName('span')

spans[0].onmouseover = function() {
  changeColor(this, 'red', '#ddd')
}
spans[0].onmouseout = function() {
  changeColor(this, '#333', '#f5f5f5')
}

spans[1].onmouseover = function() {
  changeColor(this.getElementByTagName('strong')[0], 'red', '#ddd')
}
spans[1].onmouseout = function() {2
  changeColor(this.getElementByTagName('strong')[0], '#333', '#f5f5f5')
}
// 多元化对象

// 多维变量类
// 运动单元
function Speed(x, y) {
  this.x = x
  this.y = y
}
Speed.prototype.run = function() {
  console.log('run')
}
// 着色单元
function Color(cl) {
  this.color = cl
}
Color.prototype.draw = function() {
  console.log('draw')
}
// 变形单元
function Shape(sp) {
  this.shape = sp
}
Shape.prototype.change = function() {
  console.log('changeShape')
}
// 说话单元
function Speek(wd) {
  this.word = wd
}
Speek.prototype.say = function() {
  console.log('speek')
}

// 创建一个球类
function Ball(x, y, c) {
  this.speed = new Speed(x, y)
  this.color = new Color(c)
}
Ball.prototype.init = function() {
  this.speed.run()
  this.color.draw()
}

// 创建一个人类
function People(x, y, f) {
  this.speed = new Speed(x, y)
  this.speek = new Speek(f)
}
People.prototype.init = function() {
  this.speed.run()
  this.speek.say()
}

// 使用
var p = new People(10, 12, 16)
p.init()
  1. 组合模式