提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


文章目录

  • 什么是观察者模式
  • 一、观察者模式包含两大角色
  • 二、JavaScript样例
  • 1.天气(被观察对象)
  • 2.观察者(接收消息提示)
  • 3.测试代码
  • 总结
  • 被观察包含设计要素
  • 观察者包含包含设计要素



什么是观察者模式

观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。


一、观察者模式包含两大角色

设计一个观察者模式需要设计两大重要角色:
* 被观察者,当自身状态改变时能够自动向观察它的对象发送消息
* 观察者, 它接收被观察者发送的消息

二、JavaScript样例

1.天气(被观察对象)

我们根据观察者模式的形式设计一个天气信息,当天气信息更新的时候,观察者就是接收消息的对象会收到消息提示。
代码如下(示例):

/**
         * 观察者模式
         */
        //观察对象,天气
        function Weather(date, temp) {
            this.date = date;	//日期
            this.temp = temp;	//气温
            this.observers = [];  //观察者列表
            this.getTemp = function () {
                return this.temp;
            };
            this.setTemp = function (tmp) {
                this.temp = tmp;
                this.notify();
            };
            //注册观察者
            this.attach = function (observer) {
                console.log(observer.name + "订阅了天气预报!");
                this.observers.push(observer);
            };
            //发送消失提示
            this.notify = function () {
                this.observers.forEach((observer) => {
                    observer.update(this);
                });
            }
        }

2.观察者(接收消息提示)

接收天气预报的观察者,可以接收天气预报信息,也可以根据讯息处理一些相关任务。
代码如下(示例):

//观察者
        function Observer(name, weather) {
            this.name = name; 			//观察者自身属性
            this.weather = weather;     //被观察对象
            this.weather.attach(this);  //创建观察者同时就订阅了被观察对象
            this.effects = [];			//这里也可以存储观察者自己需要处理的任务队列

            this.update = function (weather) {
                console.log(this.name + "收到了天气预报通知: 今天日期"+weather.date+"  天气温度"+weather.temp+"度");
                this.effects.forEach(obj=>{
                    //do something for obj
                    //这里其实他自身又可以成为了另一个被观察者向其他观察者观察的对象。
                })
            }
            //添加任务
            this.addEffects = function (effect) {
                this.effects.add(effect);
            }
        }

3.测试代码

代码如下(示例):

//创建天气预报
        let wea1 = new Weather("20230310", 28);
		//创建3个观察者接收天气预报
        let obj1 = new Observer("obj1", wea1);
        let obj2 = new Observer("obj2", wea1);
        let obj3 = new Observer("obj3", wea1);
        //输出
        //obj1订阅了天气预报!
		//obj2订阅了天气预报!
		//obj3订阅了天气预报!
        
        //第一种发布方式,通过自定义的设置温度方法这个方法里调用了this.notify();
        wea1.setTemp(20);

		//第二种方式发布,使用了代理方式拦截了对象的set方法
        let proxy = new Proxy(wea1,{set});

        function set(target, key, value, receiver){
            Reflect.set(target, key, value, receiver);
            target.notify();
        }
        proxy.temp = 30;
        //输出
        //obj1收到了天气预报通知: 今天日期20230310  天气温度30度
		//obj2收到了天气预报通知: 今天日期20230310  天气温度30度
		//obj3收到了天气预报通知: 今天日期20230310  天气温度30度

总结

通过观察我们发现只要观察者和被观察者只要包含一下设计元素,就能成功一个成功的观察者模型

被观察包含设计要素

1. 数组或列表用来存储观察者对象
2. 消失提示方法notify(), 循环观察者列表发送消息

观察者包含包含设计要素

1. 接收被观察者方法update()