大家都知道java当中有23种设计模式,而JS当中也有这同样的23种设计模式。这 23 种设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性的运用,写到这里,可能就会疑惑了,java肯定是面向对象编程的,javascript到底是面向对象编程还是函数式编程呢?
javascript是基于对象的,编程过程中可以发现我们遇到的大部分都是对象,却又不是真正的面向对象编程语言,虽然ES6中引入了类的概念,通过class关键字来定义类,使用extends关键字和super方法来实现继承,使得js面向对象编程的语法更加简洁和清晰,但是ES6中的类只是一个语法糖,并没有改变其本质。JS虽不是真正的面向对象的语言,但用它也能达到面向对象的封装、继承、多态等的效果。当然每个人的观点可能都不同,也欢迎大家来发表自己的见解。
言归正传,回到刚开始的话题,主要是来了解一下观察者模式,因为在项目中可能经常用到。观察者模式的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态,这是一种一对多的依赖关系。
观察者模式的角色通常有Subject(被观察者),ConcreteSubject(被观察者的具体实现),Observer(观察者),ConcreteObserver(观察者的具体实现);
这里的观察者被称为订阅者,被观察者称为发布者
下面通过一个小例字来具体了解一下,以读者订阅杂志为例子
<script>
//声明对象 杂志
class Records {
constructor(recordsname) {
this.recordsname = recordsname
//保存观察者
this.list = [];
}
//将观察者添加到列表
addList(sub) {
console.log(`读者${sub.name}订阅了${this.recordsname}`);
this.list.push(sub);
return this;
}
//删去观察者
removelist(sub) {
console.log(`读者${sub.name}取消了${this.recordsname}的订阅`);
this.list = this.list.filter(item => {
return item != sub;
});
}
//通知所有的观察者
notify(RecSub) {
let subname = RecSub.recordsname;
this.list.forEach(item => {
return item.update(subname);
});
}
}
//观察者 读者
class Reader {
constructor(name) {
//接受参数
this.name = name;
}
//目标对象收到通知,调用此方法
update(subname) {
console.log(`读者${this.name}收到${subname}更新的消息`);
}
}
//实例化目标(被观察者,杂志)
let records1 = new Records('Zara时尚杂志');
let records2 = new Records('时尚COSMO杂志');
//实例化观察者(读者)
let ob1 = new Reader('小明');
let ob2 = new Reader('小雪');
let ob3 = new Reader('小丽');
//将观察者添加到目标
records1.addList(ob1);
records1.addList(ob2);
records1.addList(ob3);
records2.addList(ob1);
records2.addList(ob2);
//目标通知所有观察者
records1.notify(records1);
//移除观察者obj3小丽;
records1.removelist(ob3);
records1.notify(records1);
records2.notify(records2);
</script>
这里只是对观察者模式的简单实现。其实jQuery中有观察者模式,实际上是让on方法绑定的自定义事件先不执行,直到使用trigger方法来触发事件,这里感兴趣的可以自己去了解一下。