浅析js设计模式

1.了解设计模式
+ 什么是设计模式?
=> 针对 特定问题, 给出的简洁而优化的处理方案
+ 一个设计模式 A
=> 只能解决 A 类型的问题
=> 针对 B 类型的问题, 设计模式 A 解决不了
+ 同一个问题, 再不同的位置, 是不一定能用同一种方案解决
+ 设计模式, 只在特定的情况, 特定的时期, 针对特定的问题使用

  市场上常用的设计模式
    + 单例模式
    + 组合模式
    + 观察者模式
    + 适配器模式
    + 代理模式
    + 工厂模式
    + 构建模式
    + ...

我大概说一下前三种
2.单例模式
+ 单: 单一, 一个, 独个
+ 例: 实例(构造函数的实例化对象)
+ 让一个构造函数一辈子只有一个实例对象
=> 当你需要一个构造函数一生只能 new 出一个对象的时候
=> 就可以使用单例模式
单例模式的简单应用
+ 弹出层 alert() 比较丑, 用户体验极度不好
+ 好多网站会使用一个自己写的 div 盒子, 当作弹出层
+ 再自己写的过程中, 一个网站不可能只弹出一次
=> 不能每次弹出就创建一个 div
=> 每次弹出的都是之前创造好的那个 div, 只是文字改变了
+ 创造 div 并显示出来的构造函数
=> 如果不用单例模式, 每次 new 就是创造一个 div
=> 如果用了单例模式, 每次 new 都是用的第一次的 div, 只是改变文字内容

单例模式 核心代码

function Person() {
  this.name = 'Jack'
} 
var instance = null

function singleton() {
  if (instance === null) {
    instance = new Person()
  }
  return instance
}

var p1 = singleton()
var p2 = singleton()
console.log(p1 === p2) 

应用会对核心代码进行升级

 var Person = (function fn() {
  function Person() {
    this.name = 'Jack'
  }
  var instance = null
  return function () {
    return !instance ? instance = new Person() : instance
  }
})()
var p1 = new Person()
var p2 = new Person()

console.log(p1)
console.log(p2)
console.log(p1 === p2) 

3.组合模式
+ 组合模式:
=> 把我们若干这启动方式一样的构造函数放在一起
=> 准备一个总开关, 总开关一启动, 那么这些个构造函数就都启动了

实现组合模式:
+ 需要一个承载所有构造函数实例的数组
+ 需要一个方法, 向数组里面添加内容
+ 需要一个方法, 能把数组里面的所有内容启动了

应用场景
+ 轮播图:

	class Play {
  	constructor () {}
  	init () {
    console.log('开始玩游戏')
  	}
	}

    class Compose {
	  constructor () {
    this.composeArr = []
  	}
  	add (instance) {
    this.composeArr.push(instance)
  	}
  	init () {
    console.log('总开关启动了')
    this.composeArr.forEach(item => item.init())
  	}
	}
	var c = new Compose()
	c.add(new Play())
	c.init()
	console.log('c')
	}

4.观察者模式
+ 又称 发布/订阅 模式
+ 目前市场上的开发人员, 分成两派人员
=> 一派人, 认为 观察者 和 发布/订阅 是一个设计模式
=> 一派人, 认为 观察者 和 发布/订阅 是两个设计模式
+ 两派人到现在也没有定论
=> 目前还在互相想说服对方,因此分两个角度
=> 一个从 观察者 角度出发
=> 一个从 发布/订阅 角度出发

  **观察者角度**
  + 目的:
      => 让 观察者 看着 被观察者, 只要数据改变了
      => 就让 观察者 做一些事情
   + 就像我们小时候的班主任一样
      => 班主任, 年级主任, 教务主任, 都有一个共同的能力叫做 请家长
      => 他们就是暗中观察我们的人, 一旦我们做的事情和他们想的不一样, 就回触发技能
      => 他们就是观察者, 当被观察者一旦出现变化, 立马触发他们的技能
    + 被观察者
      => 就是一个学生, 你的状态就应该是 好好学习
      => 一旦你的状态改变为 玩手机
      => 立马就会通知正在观察着你的人, 观察着你的人, 就会触发技能
    
// 1. 被观察者
class Student {
  constructor () {
    this.state = '好好学习'
    this.observers = []
  }
  // 方法
  // 1. 可以改变状态的方法
  setState (value) {
    this.state = value
    // 状态一旦改变, 就要通知看着你的人
    this.notify()
  }
  // 2. 获取自己的状态
  getState () {
    return this.state
  }
  // 3. 添加观察着
  // 向 this.observers 里面追加一个看着这个同学的人
  attach (observer) {
    this.observers.push(observer)
  }
  // 4. 通知 this.observers 数组里面的每一个人, 状态改变了
  notify () {
    this.observers.forEach(item => item.qingjiazhang( this.state ))
  }

}

// 2. 观察者
class Observer {
  constructor (name) {
    this.name = name
  }
  // 方法, 就是这些老师能触发的技能
  qingjiazhang (state) {
    console.log(`我是 ${ this.name }, 因为你 ${ state } 了, 我要请你家长来!`)
  }
}
var xiaoming = new Student()
var banzhuren = new Observer('班主任')
xiaoming.attach(banzhuren)
xiaoming.setState('玩手机')
console.log(xiaoming)

**发布/订阅 角度**
    + 分成三个状态
      => 订阅
      => 取消订阅
      => 发布
    + js 里面由实际应用
      => addEventListener('click', fn)
      => 当 click 行为触发的时候, 就会执行 fn 函数
      => 还可以绑定多个事件处理函数
      => 当 click 行为触发的时候, 所有的事件处理函数 都会执行
    + 做的事情
      => 就是模仿 addEventListener 自己定一个事件监听

  发布/订阅 需要的内容
    1. 消息盒子 {}
      => click: [fn1, fn2, fn3]
      => mouseover: [fn4, fn5, fn6]
    2. 订阅的方法
      => 向消息盒子里面添加内容
    3. 取消订阅的方法
      => 把已经订阅的方法从消息盒子内部拿走
    4. 发布事件的方法
      => 把消息盒子里面的对应的处理函数执行了
class Observer {
  constructor () {
    // 准备的消息盒子
    this.message = {}
  }

  // 订阅的方法
  on (type, fn) {
  
    if (!this.message[type]) {
      this.message[type] = []
    }
    this.message[type].push(fn)
  }

  // 取消订阅的方法
  off (type, fn) {
    if (!this.message[type]) return
    this.message[type] = this.message[type].filter(item => item !== fn)
  }

  // 发布的方法
  emit (type, ...arg) {
    if (!this.message[type]) return
    console.log(arg)
    // 自己组装一个事件对象
    var event = {
      type: type,
      // 参数
      data: arg
    }

    // 调用每一个事件处理函数的时候, 都给你带上一个事件对象
    this.message[type].forEach(item => item(event))
  }
}

// 将来使用的时候
var o = new Observer()

// 订阅事件
o.on('click', handlerA)
o.on('click', handlerB)

o.emit('click', 'hello world', 100, true, { name: 'Jack' })

// 准备几个事件处理函数, 因为我老要用到, 先准备好
function handlerA(e) { console.log('我是事件处理函数 handlerA', e) }
function handlerB(e) { console.log('我是事件处理函数 handlerB', e) }
function handlerC(e) { console.log('我是事件处理函数 handlerC', e) }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值