定义:观察者模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。事实上,只要你曾经在DOM节点上绑定过事件函数,那么你就曾经使用过观察者模式了!
实现:Event模块实现自定义事件,绑定事件,触发事件,移除事件。
代码中用到工厂方法模式工厂方法模式实现
PlaneFactory.prototype = new Event();
function PlaneFactory() {
}
PlaneFactory.create = function (type) {
let newPlane;
if (!PlaneFactory.prototype[type]) {
throw '没有此类型';
}
if (PlaneFactory.prototype[type].prototype.__proto__ != PlaneFactory.prototype) {
PlaneFactory.prototype[type].prototype = new PlaneFactory();
}
const arg = [].slice.call(arguments, 1);
newPlane = new PlaneFactory.prototype[type](...arg);
return newPlane;
}
PlaneFactory.prototype.die = function () {
console.log('boom');
}
PlaneFactory.prototype.touch = function () {
this.boold -= 100;
if (this.boold == 0) {
console.log('die')
}
}
PlaneFactory.prototype.smallPlane = function (x, y) {
this.x = x;
this.y = y;
this.boold = 100;
this.name = 'smallPlane';
}
PlaneFactory.prototype.bigPlane = function (x, y) {
this.x = x;
this.y = y;
this.boold = 200;
this.name = 'bigPlane';
}
function Event() {//发布者
this.cache = {}//缓存列表,存放回调函数通知订阅者
}
//绑定事件
Event.prototype.on = function (type, handle) {
if (!this.cache[type]) {
this.cache[type] = [handle];
} else {
this.cache[type].push(handle);
}
}
//触发事件 发布消息,发布者遍历缓存列表,依次触发存放的回调函数
Event.prototype.emmit = function () {
const type = arguments[0];
const arg = [].slice.call(arguments, 1);
for (let i = 0; i < this.cache[type].length; i++) {
this.cache[type][i].apply(this, arg);
}
}
//清空缓存列表
Event.prototype.empty = function (type) {
this.cache[type] = [];
}
//移除事件
Event.prototype.remove = function (type, handle) {
this.cache[type] = this.cache[type].filter(ele => {
return ele != handle;
})
}
//once 绑定事件(只能绑定一次某一类型事件)
Event.prototype.once = function (type, handle) {
if (Object.keys(this.cache).indexOf(type) > -1) {
throw '已经绑定过此事件';
} else {
if (!this.cache[type]) {
this.cache[type] = [handle];
}
}
}
const small = PlaneFactory.create('smallPlane', 10, 20);
small.on('over', function () {
this.die()
});
small.emmit('over');//飞机死亡
small.on('touch', function () {
this.touch();
});
small.emmit('touch');//飞机血量减少
small.once('once', function () {//只可以绑定一次
console.log('once');
})