JavaScript 23 种设计模式之 18 观察者模式

JavaScript 23 种设计模式之 18 观察者模式

概念与特点

概念:
观察者模式也叫订阅/发布模式和模型-视图模式,指多个对象之间存在一对多的依赖关系。当一个对象状态发生改变时,所有依赖于它的对象都得到通知自动更新。

但是有些地方会把观察者模式和发布/订阅模式区分开。其区别主要在于,发布/订阅模式中发布者与订阅者双方没有感知。两者的区别可以抽象地理解租房子。观察者模式是自己找房东,两个人协商好生意就达成了。发布/订阅模式则是房东将租房信息挂在中介方,租房者也可以把自己的租房需求告知中介方。交易由中介方来促成。

特点:

  1. 降低目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  2. 目标与观察者之间建立了一套触发机制。
  3. 当观察者对象很多时,通知的发布会花费很多时间,影响效率。

结构与实现

结构:
观察者模式包含抽象主题、具体主题、抽象观察者和具体观察者。
抽象主题:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察对象的方法以及通知所有观察者的抽象方法。
具体主题:也叫具体目标类,实现抽象目标中的通知方法。当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者:更新观察者自身的抽象方法,接到具体主题的更改通知时调用。
具体观察者:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

案例
人民币汇率升值或贬值对进口和出口公司的影响。
当汇率升值时,进口公司的进口产品成本降低且利润率提升,出口公司的出口产品收入降低且利润率降低。
当汇率贬值时,进口公司的进口产品成本提升且利润率降低,出口公司的出口产品收入提升且利润率提升。

<!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>

应用场景

  1. 对象之间存在一对多的关系。一个对象的状态改变会影响其他状态的改变。
  2. 当一个抽象对象有两个方面。其中一方面依赖于另一个方面时,可将两者封装在独立的对象中,使它们可以独自复用和改变。

应用实例

暂无。

总结

在 React 中组件之间的传值是层层传递的。父组件跟孙组件之间传值需要父组件传给子组件,再由子组件传给孙组件。这种传值比较麻烦,更麻烦的是出现跨组件传值的现象。即一个组件的状态更新,会引起其他跨组件之间的变化。这些可以通过 context 的形式进行传值。但是一种更优雅的处理方式是通过 redux。而 redux 的实现方式就是将需要更新的 state 通过 reducer 纯函数的方式进行更新,然后将所有的业务 reducer 都 push(添加) 到一个函数集中。最后通过 subscribe 订阅函数统一发布(执行)。

【目标对象】:
1、在构造函数中定义 list 用来管理观察者对象。
1、提供添加、删除观察者对象的方法,
2、提供 change 方法,当状态发生变化时,通知所有观察者做出更新。

【观察者对象】:
1、提供 response 方法,当状态发生变化时,做出反应。

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/106017592