资讯专栏INFORMATION COLUMN

设计模式之观察者模式

kamushin233 / 1668人阅读

摘要:一什么是观察者模式观察者模式,引用维基百科的说法,一个目标对象管理所有相依与它的观察者对象,并在它本身状态改变时发生通知。四观察者模式的用途观察者模式主要用于解耦合,一个对象变了,可以通知多个对象,而不是在回调里来处理各种情况。

一、什么是观察者模式

观察者模式,引用维基百科的说法,一个目标对象管理所有相依与它的观察者对象,并在它本身状态改变时发生通知。这通常通过调用各观察者所提供的方法来实现。在前端应用的范围还挺多,最常见的事件监听,addEventListener,我们在一个元素上注册了各类事件,而当对象发生相应改变时,通过调用绑定的事件告诉观察者。就相当于在一个对象上绑定了各类观察者。

举个与前端不相关的例子,小偷警察的故事。小偷数量就是我们这里的目标对象,有三个警察负责看管(观察者),当小偷数量大于3了,一个警察要去报告上级,一个警察要去警告市民引起重视,一个去和小偷谈话。在程序里通过调用这三个警察的方法来相当于告诉这三个警察小偷数量大于3了。

二、用代码看观察者模式思路

/*
    被观察类
    addObserver()方法把观察者对象添加到观察者对象列表中
    setChange()方法用来设置一个内部标志位注明数据发生了变化
    notifyObservers()方法会去调用观察者对象列表中所有的Observer的update()方法,通知它们数据发生了变化。
 */
function Observable(){
    this.observerArray = new Set();
    this.updateFlage = false;
}

Observable.prototype.addObserver = function(data){
    this.observerArray.add(data);
}

Observable.prototype.setChange = function(){
    this.updateFlage = true;
}

Observable.prototype.notifyObservers = function(data){
    if(this.updateFlage){
        for(let item of this.observerArray){
            item.update(data)
        }
    }
    this.updateFlage = false
}

/*
    观察者类
    实现Observer接口的唯一方法update
 */
function Observer(){
    this.update = function(){ }
}

皮一下,这其实是看了Java里的观察者模式思想,我用Js实现了一下。因为我看这个实现思路是更能体会到观察者模式的。这里有两个类,一个是被观察类,实现了上述三个方法,一个是观察者类。每个观察者都有update方法,当被观察者改变了,执行相应的观察者的update方法来通知观察者被观察者改变了。下面看示例:

function thief(){
    var data = 0;
    Observable.call(this); 
    this.setData = function(param){
        data = param;
        if(data > 3){
            this.setChange();
        }
        this.notifyObservers();
    }
    this.getData = function(){
        return data
    }
}
thief.prototype = new Observable();
thief.prototype.constructor = thief;

let thief1 = new thief();
let police1 = new Observer;
let police2 = new Observer;

thief1.addObserver(police1)
thief1.addObserver(police2)

police1.update = function(){
    console.log("警察1接收到现在有"+thief1.getData()+"个小偷")
}

police2.update = function(){
    console.log("警察2接收到现在有"+thief1.getData()+"个小偷")
}

thief1.setData(1)    //无输出
thief1.setData(4)    //警察1接收到现在有4个小偷 警察2接收到现在有4个小偷

这个例子小偷继承了被观察者,当小偷内部数据大于3的时候,就通知观察各个警察引起重视。因为是参照Java的思想来的,所以看到实现是通过将小偷继承被观察者类,警察继承观察者类。这个结构其实用java来写很清晰,观察者的模式也体现的很清晰,能帮助我们很好的理解观察者模式,值得借鉴。比起前端有些写法在被观察中存入对应的观察者,和观察者的回调,这种写法其实更分离。

三、前端代码写观察者模式

前端的写法跟Java里的实现类是有差别的,看代码:

/**
 * 实现一个类
 * on():存入被观察者
 * fire():手动触发某个观察者,可带参数
 * delete():删除指定观察者
 * update():被观察者更新了,执行观察者回调通知观察者
 * one():某个观察者只执行一次
 * 可链式调用
 */
function Emiter(){
    this.storage = new Map();
}
Emiter.prototype.on = function(key,callback){
    this.storage.set(key,callback);
    return this
}
Emiter.prototype.fire = function(key,data){
    this.storage.has(key) ? this.storage.get(key)(data) :  console.log("请先注册对应的事件");
    return this
}
Emiter.prototype.delete = function(key){
    this.storage.has(key) ? this.storage.delete(key) :  console.log("请先注册对应的事件");
    return this
}
Emiter.prototype.update = function(data){
    for (let [key, value] of this.storage) {
        value(data);
      }
    return this
}
Emiter.prototype.one = function(key,data){
    if(this.storage.has(key)){
        this.storage.get(key)(data);
        this.storage.delete(key);
    }else{
        console.log("请先注册对应的事件")
    }
    return this
   
}

//示例
let emiter = new Emiter();
emiter.on("view1",function(data){
    console.log("view1收到的数据"+data)
})

emiter.on("event",function(){
    console.log("emiter")
}).on("click",function(){
    console.log("click啦")
})

emiter.update([1,2,3]) //view1收到的数据1,2,3 emiter click啦

前端抛开一些复杂规范性,可以直接把观察者和观察者的回调保存在被观察者里,当被观察者更新了,执行所有观察者的回调。这里之所以有one fire 等方法提供,主要是考虑前端addEventListner也是采用观察者模式,所以一起提供了。只不过更相当于一对一模式,没有对应的update,更新所有观察者的操作。我们这里探讨的设计模式应该是on update delete为主线。

四、观察者模式的用途

观察者模式主要用于解耦合,一个对象变了,可以通知多个对象,而不是在回调里来处理各种情况。一个场景有个模块获取了数据,其他多个view层都需要用到这个数据。我们的做法可能是会在获取数据后的模块回调里进行各个view层的处理,那如果后续某个模块的相应业务变了,我们可能还得回来改这个回调函数。那如果通过观察者模式,我们可以优化为,每个模块完全分离,当数据回来时告知每个模块即可。以后模块要改变获取数据后的处理,各个模块自己去更新。

我现在在想,event对象,是不是内部实现,是在dom改变时传的参数,而在调用相关事件时能拿到这个回调的参数。

之前看文档,Vue里数据变了,如何更新view,用的也是观察者模式,只不过不是这种实现代码,后续更新。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108225.html

相关文章

  • JS设计模式Obeserver(察者模式、Publish/Subscribe(发布/订阅)模式

    摘要:观察者模式定义设计模式中对的定义一个对象称为维持一系列依赖于它观察者的对象,将有关状态的任何变更自动通知给它们。如图模式比较观察者模式则多了一个类似于话题调度中心的流程,发布者和订阅者解耦。 Obeserver(观察者)模式 定义 《js设计模式》中对Observer的定义:一个对象(称为subject)维持一系列依赖于它(观察者)的对象,将有关状态的任何变更自动通知给它们。 《设计模...

    荆兆峰 评论0 收藏0
  • 设计模式察者设计模式

    摘要:关键概念理解观察者设计模式中主要区分两个概念观察者指观察者对象,也就是消息的订阅者被观察者指要观察的目标对象,也就是消息的发布者。 原文首发于微信公众号:jzman-blog,欢迎关注交流! 最近补一下设计模式相关的知识,关于观察者设计模式主要从以下几个方面来学习,具体如下: 什么是观察者设计模式 关键概念理解 通知观察者的方式 观察者模式的实现 观察者模式的优缺点 使用场景 下面...

    NotFound 评论0 收藏0
  • Java设计模式察者模式

    摘要:观察者模式的使用场景比如你微博关注了一个人,那么这个人发布的微博就会推送到你这。 Java设计模式之观察者模式 一直想写一篇学习观察者模式的总结没有契机,今天学习阻塞队列的原理时候看到在实现生产者消费者的时候用到了通知模式,就是所谓的观察者模式,正好顺便整理一下。 1. 简介 观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更...

    haitiancoder 评论0 收藏0
  • PHP设计模式察者模式

    摘要:概念观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。观察者模式符合接口隔离原则,实现了对象之间的松散耦合。 概念 观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。 当一个对象状态发生改变后,会影响到其他几个对象的改变,这...

    phpmatt 评论0 收藏0
  • php面向对象设计模式 察者模式

    摘要:最近在学的设计模式,看到了观察者模式,在此写下一点理解问题假如一个小贩,他把产品的价格提升了,不同的消费者会对此产生不同的反应。 最近在学php 的设计模式, 看到了观察者模式,在此写下一点理解: 问题: 假如一个小贩, 他把产品的价格提升了, 不同的消费者会对此产生不同的反应。一般的编程模式无非是获取提升的价格,然后获取所有的消费者,再循环每个消费者, 不同的消费者根据价格涨幅...

    genedna 评论0 收藏0
  • Python版设计模式监听者模式

    摘要:监听模式又名观察者模式发布订阅模式源监听器模式,模式的核心是设计时要区分谁是被观察者,谁是观察者。 监听模式 又名观察者模式、发布/订阅模式、源-监听器(Source/Listener)模式,模式的核心是:设计时要区分谁是被观察者,谁是观察者。被观察者至少有三个方法,添加观察者、删除观察者、监听目标变化并通知观察者;观察者这至少包含一个方法,当接收到被观察者的通知时,做出相应的处理(即...

    hlcfan 评论0 收藏0

发表评论

0条评论

kamushin233

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<