概念与特点
概念:
观察者模式也叫订阅/发布模式和模型-视图模式,指多个对象之间存在一对多的依赖关系。当一个对象状态发生改变时,所有依赖于它的对象都得到通知自动更新。
但是有些地方会把观察者模式和发布/订阅模式区分开。其区别主要在于,发布/订阅模式中发布者与订阅者双方没有感知。两者的区别可以抽象地理解租房子。观察者模式是自己找房东,两个人协商好生意就达成了。发布/订阅模式则是房东将租房信息挂在中介方,租房者也可以把自己的租房需求告知中介方。交易由中介方来促成。
特点:
- 降低目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
- 目标与观察者之间建立了一套触发机制。
- 当观察者对象很多时,通知的发布会花费很多时间,影响效率。
结构与实现
结构:
观察者模式包含抽象主题、具体主题、抽象观察者和具体观察者。
抽象主题:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察对象的方法以及通知所有观察者的抽象方法。
具体主题:也叫具体目标类,实现抽象目标中的通知方法。当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者:更新观察者自身的抽象方法,接到具体主题的更改通知时调用。
具体观察者:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
案例:
人民币汇率升值或贬值对进口和出口公司的影响。
当汇率升值时,进口公司的进口产品成本降低且利润率提升,出口公司的出口产品收入降低且利润率降低。
当汇率贬值时,进口公司的进口产品成本提升且利润率降低,出口公司的出口产品收入提升且利润率提升。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Rate{
constructor(){
this.observers = [];
}
add(observer){
this.observers.push(observer);
}
remove(observer){
this.observers = this.observers.filter((item)=>item!=observer);
}
change(number){
}
}
class RMBrate extends Rate{
change(number){
for(let i of this.observers){
i.response(number);
}
}
}
class Company{
response(number){
}
}
class ImportComponent extends Company{
response(number){
if(number>0){
console.log("人民币汇率升值了"+number+"个基点,进口公司的进口产品成本降低且利润率提升")
}else if(number<0){
console.log("人民币汇率贬值了"+(-number)+"个基点,进口公司的进口产品成本提升且利润率降低")
}
}
}
class ExportComponent extends Company{
response(number){
if(number>0){
console.log("人民币汇率升值了"+number+"个基点,出口公司的出口产品收入降低且利润率降低")
}else if(number<0) {
console.log("人民币汇率贬值了"+(-number)+"个基点,出口公司的出口产品收入提升且利润率提升")
}
}
}
class Customer{
static main(){
let rate = new RMBrate();
rate.add(new ImportComponent());
rate.add(new ExportComponent());
rate.change(6);
rate.change(-3);
}
}
Customer.main();
</script>
</body>
</html>
应用场景
- 对象之间存在一对多的关系。一个对象的状态改变会影响其他状态的改变。
- 当一个抽象对象有两个方面。其中一方面依赖于另一个方面时,可将两者封装在独立的对象中,使它们可以独自复用和改变。
应用实例
暂无。
总结
在 React 中组件之间的传值是层层传递的。父组件跟孙组件之间传值需要父组件传给子组件,再由子组件传给孙组件。这种传值比较麻烦,更麻烦的是出现跨组件传值的现象。即一个组件的状态更新,会引起其他跨组件之间的变化。这些可以通过 context 的形式进行传值。但是一种更优雅的处理方式是通过 redux。而 redux 的实现方式就是将需要更新的 state 通过 reducer 纯函数的方式进行更新,然后将所有的业务 reducer 都 push(添加) 到一个函数集中。最后通过 subscribe 订阅函数统一发布(执行)。
【目标对象】:
1、在构造函数中定义 list 用来管理观察者对象。
1、提供添加、删除观察者对象的方法,
2、提供 change 方法,当状态发生变化时,通知所有观察者做出更新。
【观察者对象】:
1、提供 response 方法,当状态发生变化时,做出反应。