/***
* 使用闭包外部不能直接访问,和修改 保证安全
* 使用对象减小全局变量,更好管理
**/
// 定义观察者
let Observer = (() => {
var _messages = {};
return {
// 注册信息接口
regist: (type,fn) => {
// 检测该类型是否已经创建,未创建则创建并添加函数
if(typeof _messages[type] === 'undefined'){
_messages[type] = [];
_messages[type].push(fn);
}else{
// 已经创建,新增一个函数
_messages[type].push(fn);
}
},
// 发布信息接口
fire: (type,args) => {
// console.log(_messages.test);
// 方法未注册,不执行,或返回提示信息;
if(!type){return;}
// 定义消息信息
let events ={
type: type,
args: args || {}
},
i = 0, // 消息动作循环的环境变量
len = _messages[type].length; // 消息动作的总长度
// 遍历消息动作
for(; i < len; i++){
// console.log(typeof(_messages[type]))
_messages[type][i].call(this, events);
};
},
// 移除信息接口
remove: (type,fn) => {
// 如果消息动作队列存在
if(_messages[type] instanceof Array){
// 从最后一个消息动作开始遍历
let i = _messages[type].length - 1;
for(; i >= 0; i--){
// 如果存在则删除,巧妙的用&&进行判断
_messages[type][i] === fn && _messages[type].splice(i, 1);
// 如果类型没有方法则删除类型
_messages[type].length === 0 && delete _messages[type];
}
}
}
}
})();
// // 注册动作(挂载事件)
// Observer.regist('test', (e)=>{
// console.log(e.type, e.args.msg);
// });
// // 发布信息(调用事件)
// Observer.fire('test', {msg: '传递参数'});
// 学生类
class Student {
constructor(result){
this.result = result;
this.say = this.say.bind(this);
this.answer = this.answer.bind(this);
}
// 答题动作
say(){
console.log(this.result);
}
// 回答问题方式
answer(question){
Observer.regist(question, this.say);// 注册参数问题
}
// 睡觉的学生取消对提问的监听
sleep(question){
console.log(this.result+" "+question +" "+ '已被注销');// 弹出提示
Observer.remove(question ,this.say);// 取消老师对问题的监听
}
}
// 老师类
class Teacher{
ask(question){
console.log('问题是:'+question); // 打印提示
Observer.fire(question); // 发布问题
}
}
let teacher = new Teacher();
let student1 = new Student('第1个学生回答问题'),
student2 = new Student('第2个学生回答问题'),
student3 = new Student('第3个学生回答问题');
student1.answer('什么是设计模式');
student1.answer('什么是观察者模式');
student2.answer('什么是设计者模式');
student2.answer('什么是设计者模式');
student3.answer('简述观察者模式');
student3.sleep('简述观察者模式');
teacher.ask('什么是设计模式');
console