/**
*
* 观察者模式(发布-订阅者模式)
*
* 实现方法v1
*/
var Observer = (function () {
var _message = {} //防止队列暴漏而被篡改故将消息容器作为静态私有变量保存
return {
regist: function (type, fn) {
// console.log("type",type);
if (typeof _message[type] === 'undefined') {
_message[type] = [fn]
} else {
_message[type].push(fn)
}
},
fire: function (type, args) {
if (!_message[type]) {
return
}
var event = {
type: type,
args: args || {}
}
var len = _message[type].length
for (let i = 0; i < len; i++) {
_message[type][i].call(this, event)
}
},
remove: function (type, fn) {
if (_message[type] instanceof Array) {
for (let i = _message[type].length - 1; i >= 0; i--) {
//如果存在改动作就在消息队列中移除相应的动作
_message[type][i] === fn && _message[type].splice(i, 1)
}
}
}
}
})()
// console.log(Observer);
//用学生老师来充当订阅者
var Student = function (result) {
var that = this
//学生回答结果
that.result = result
//模拟学生回答问题的动作
that.say = function () {
console.log(that.result);
}
}
// console.log(Student);
Student.prototype.answer = function (question) {
Observer.regist(question, this.say)
}
Student.prototype.sleep = function (question) {
console.log(this.result + ' ' + question + ' 已被注销');
Observer.remove(question, this.say)
}
//用老师来充当观察者(发布者)
var Teacher = function () {}
Teacher.prototype.ask = function(question) {
console.log('问题是:', question);
Observer.fire(question)
}
var stu1 = new Student('学生1回答问题'),
stu2 = new Student('学生2回答问题'),
stu3 = new Student('学生3回答问题')
stu1.answer('什么是设计模式')
stu1.answer('简述观察者模式')
stu2.answer('什么是设计模式')
stu3.answer('什么是设计模式')
stu3.answer('简述观察者模式')
stu3.sleep('简述观察者模式')
var teac = new Teacher()
teac.ask('什么是设计模式')
teac.ask('简述观察者模式')
2.用proxy和reflect实现一个观察者模式
/**
* 基于es6 proxy,reflect实现
* v2
*/
class Student {
constructor(name, age) {
this.name = name
this.age = age
}
}
let stu = new Student("zhangsan", "20")
//proxy
let handler = {
set(target, key, value, receiver) {
if (key === 'name') {
console.log(`name 从 ${target[key]} 转变成 ${value}`);
}
// Reflect.set方法设置target对象的name属性等于value
Reflect.set(target, key, value, receiver)
}
}
let stuProxy = new Proxy(stu, handler)
stuProxy.name = "lizhen"
console.log(stu);