observer_observer 数组 - CSDN
精华内容
参与话题
  • Observer模式

    2019-08-14 14:17:03
    Observer 模式应该可以说是应用最多、影响最广的模式之一,因为 Observer 的一个实例 Model/View/Control( MVC) 结构在系统开发架构设计中有着很重要的地位和意义, MVC实现了业务逻辑和表示层的解耦。 设计 ...

    Observer 模式应该可以说是应用最多、影响最广的模式之一,因为 Observer 的一个实例 Model/View/Control( MVC) 结构在系统开发架构设计中有着很重要的地位和意义, MVC实现了业务逻辑和表示层的解耦。

    • 设计

    Observer 模式要解决的问题为: 建立一个 Subject对多个Observer的依赖关系, 并且做到当“一” 变化的时候, 依赖这个“一”的多也能够同步改变。 最常见的一个例子就是: 对同一组数据进行统计分析时候, 我们希望能够提供多种形式的表示(例如以表格进行统计显示、 柱状图统计显示、 百分比统计显示等)。这些表示都依赖于同一组数据, 我们当然需要当数据改变的时候, 所有的统计的显示都能够同时改变。该设计模式结构图如下:

    目标 Subject 提供依赖于它的观察者 Observer 的注册( Attach) 和注销( Detach)操作,并且提供了使得依赖于它的所有观察者同步的操作( Notify)。 观察者 Observer 则提供一个 Update 操作, 注意这里的 Observer 的 Update 操作并不在 Observer 改变了 Subject 目标状态的时候就对自己进行更新, 这个更新操作要延迟到 Subject 对象发出 Notify 通知所有Observer 进行修改(调用 Update)。

    Observer 模式也称为发布---------订阅( publish-subscribe),目标就是通知的发布者,观察者则是通知的订阅者(接受通知)。

    •  实现

    在Observer 模式的实现中, Subject 维护一个 list 作为存储其所有观察者的容器。每调用Notify操作就遍历list中的Observer对象, 并广播通知改变状态(调用Observer 的 Update操作)。 目标的状态 state 可以由 Subject 自己改变, 也可以由 Observer 的某个操作引起 state 的改变(可调用 Subject 的 SetState 操作)。 Notify 操作可以由 Subject 目标主动广播(示例),也可以由 Observer 观察者来调用(利用Observer维护一个指向Subject的指针)。运行示例程序, 可以看到当 Subject 处于状态“ old” 时候, 依赖于它的两个观察者都显示“ old”,当目标状态改变为“ new”的时候,依赖于它的两个观察者也都改变为“ new”。

    1. subiect被观察者
    • Subject.h
    #include <iostream>
    using namespace std;
    #ifndef _SUBJECT_H_
    #define _SUBJECT_H_
    #include <list>
    #include <string>
    using namespace std;
    typedef string State;
    class Observer;
    class Subject
    {
      public:
       virtual ~Subject();
       virtual void Attach(Observer* obv);
       virtual void Detach(Observer* obv);
       virtual void Notify();
       virtual void SetState(const State& st) = 0;
       virtual State GetState() = 0;
      protected:
       Subject();
      private:
       list<Observer* >* _obvs;
    };
    
    class ConcreteSubject:public Subject
    {
      public:
       ConcreteSubject();
       ~ConcreteSubject();
       State GetState();
       void SetState(const State& st);
      private:
       State _st;
    };
    #endif
    • Subject.cpp
    #include "Subject.h"
    #include "Observer.h"
    #include <iostream>
    #include <list>
    using namespace std;
    typedef string state;
    
    Subject::Subject()
    { 
      //在模板的使用之前一定要 new,创建
      _ obvs = new list<Observer*>;
    }
    Subject::~Subject()
    { }
    void Subject::Attach(Observer* obv)
    {
      _obvs->push_front(obv);
    }
    void Subject::Detach(Observer* obv)
    {
      if (obv != NULL)
      _obvs->remove(obv);
    }
    void Subject::Notify()
    {
      list<Observer*>::iterator it;
      it = _obvs->begin();
      for (;it != _obvs->end();it++)
      {
       //关于模板和 iterator 的用法
       (*it)->Update(this);
      }
    }
    
    ConcreteSubject::ConcreteSubject()
    {
      _st = '\0';
    }
    
    ConcreteSubject::~ConcreteSubject()
    { }
    
    State ConcreteSubject::GetState()
    {
      return _st;
    }
    
    void ConcreteSubject::SetState(const State& st)
    { 
      _st = st;
    }
    1.  观察者
    • Observer.h
    #ifndef _OBSERVER_H_
    #define _OBSERVER_H_
    #include "Subject.h"
    #include <string>
    using namespace std;
    typedef string State;
    class Observer
    {
      public:
       virtual ~Observer();
       virtual void Update(Subject* sub) = 0;
       virtual void PrintInfo() = 0;
      protected:
       Observer();
       State _st;
      private:
    };
    
    class ConcreteObserverA:public Observer
    {
      public:
       virtual Subject* GetSubject();
       ConcreteObserverA(Subject* sub);
       virtual ~ConcreteObserverA();
       //传入 Subject 作为参数,这样可以让一个
       View 属于多个的 Subject。
       void Update(Subject* sub);
       void PrintInfo();
      protected:
      private:
       Subject* _sub;
    };
    
    class ConcreteObserverB:public Observer
    {
      public:
       virtual Subject* GetSubject();
       ConcreteObserverB(Subject* sub);
       virtual ~ConcreteObserverB();
       //传入 Subject 作为参数,这样可以让一个
       View 属于多个的 Subject。
       void Update(Subject* sub);
       void PrintInfo();
      private:
       Subject* _sub;
    };
    #endif
    • ObserverA.cpp
       
    #include "Observer.h"
    #include "Subject.h"
    #include <iostream>
    #include <string>
    using namespace std;
    Observer::Observer()
    {
       _st = '\0';
    }
    Observer::~Observer(){}
    ConcreteObserverA::ConcreteObserverA(Subject* sub)
    {
       _sub = sub;
       _sub->Attach(this);
    }
    ConcreteObserverA::~ConcreteObserverA()
    {
       _sub->Detach(this);
       if (_sub != 0)
        delete _sub;
    }
    Subject* ConcreteObserverA::GetSubject()
    {
       return _sub;
    }
    void ConcreteObserverA::PrintInfo()
    {
       cout<<"ConcreteObserverA observer...."<<_sub->GetState()<<endl;
    }
    void ConcreteObserverA::Update(Subject* sub)
    {
       _st = sub->GetState();
       PrintInfo();
    }
    ConcreteObserverB::ConcreteObserverB(Subject* sub)
    {
       _sub = sub;
       _sub->Attach(this);
    }
    • ObserverB.cpp
    ConcreteObserverB::~ConcreteObserverB()
    {
        _sub->Detach(this);
    if (_sub != 0)
    {
        delete _sub;
    }
    Subject* ConcreteObserverB::GetSubject()
    {
        return _sub;
    }
    void ConcreteObserverB::PrintInfo()
    {
        cout<<"ConcreteObserverB observer...."<<_sub->GetState()<<endl;
    }
    void ConcreteObserverB::Update(Subject* sub)
    {
        _st = sub->GetState();
        PrintInfo();
    }
    • main.cpp
    #include "Subject.h"
    #include "Observer.h"
    #include <iostream>
    using namespace std;
    
    int main(int argc,char* argv[])
    {
        ConcreteSubject* sub = new ConcreteSubject();
    
        Observer* o1 = new ConcreteObserverA(sub);
    
        Observer* o2 = new ConcreteObserverB(sub);
    
        sub->SetState("old");
        sub->Notify();
    
        sub->SetState("new");  // 也可由Observer调用
        sub->Notify();
    
        return 0;
    }

     

    展开全文
  • 解决vue的{__ob__: observer}取值问题

    万次阅读 2019-11-14 15:33:32
    vue编码中经常出现获取到的数据是:{__ob__: Observer} 格式的,详细如下 可能导致后续数据操作错误,如何获取其中的数值呢 解决方法如下: 将返回的数据data先转换为JSON字符串形式,然后再从字符串形式...

    vue编码中经常出现获取到的数据是:{__ob__: Observer} 格式的,详细如下

     

     

    可能导致后续数据操作错误,如何获取其中的数值呢

     

    解决方法如下:

    将返回的数据data先转换为JSON字符串形式,然后再从字符串形式转换成JSON格式JSON.parse(JSON.stringify(data))

                let resdata=JSON.parse(JSON.stringify(that.runlogData));  
                console.log("运行记录组件接到的数据",resdata);

    结果会转换成一般对象

    展开全文
  • 操作数据库返回的数据时,发现访问属性值为undefined 解决方法如下: 将返回的数据data先转换为JSON字符串形式,然后再从字符串形式转换成JSON格式JSON.parse(JSON.stringify(data)) var self = this;...

    操作数据库返回的数据时,发现访问属性值为undefined 

     

    解决方法如下:

    将返回的数据data先转换为JSON字符串形式,然后再从字符串形式转换成JSON格式JSON.parse(JSON.stringify(data))

      var self = this;
        var query = new AV.Query("MenuItem");
        query.find("name").then(function(res) {
          var result = JSON.parse(JSON.stringify(res));
          self.menusItem = result;
        });

     

    展开全文
  • Vue原理解析之observer模块

    千次阅读 2018-05-08 15:51:45
    Vue原理解析之observer模块vue.js JoeRay61 2017年02月16日发布本文是针对Vue@2.1.8进行分析observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。...

    本文是针对Vue@2.1.8进行分析

    observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。

    observer模块在Vue项目中的代码位置是src/core/observer,模块共分为这几个部分:

    • Observer: 数据的观察者,让数据对象的读写操作都处于自己的监管之下

    • Watcher: 数据的订阅者,数据的变化会通知到Watcher,然后由Watcher进行相应的操作,例如更新视图

    • DepObserverWatcher的纽带,当数据变化时,会被Observer观察到,然后由Dep通知到Watcher

    示意图如下:

    clipboard.png

    Observer

    Observer类定义在src/core/observer/index.js中,先来看一下Observer的构造函数

    constructor (value: any) {
      this.value = value
      this.dep = new Dep()
      this.vmCount = 0
      def(value, '__ob__', this)
      if (Array.isArray(value)) {
          const augment = hasProto
          ? protoAugment
          : copyAugment
        augment(value, arrayMethods, arrayKeys)
        this.observeArray(value)
      } else {
        this.walk(value)
      }
    }

    value是需要被观察的数据对象,在构造函数中,会给value增加__ob__属性,作为数据已经被Observer观察的标志。如果value是数组,就使用observeArray遍历value,对value中每一个元素调用observe分别进行观察。如果value是对象,则使用walk遍历value上每个key,对每个key调用defineReactive来获得该key的set/get控制权。

    解释下上面用到的几个函数的功能:

    • observeArray: 遍历数组,对数组的每个元素调用observe

    • observe: 检查对象上是否有__ob__属性,如果存在,则表明该对象已经处于Observer的观察中,如果不存在,则new Observer来观察对象(其实还有一些判断逻辑,为了便于理解就不赘述了)

    • walk: 遍历对象的每个key,对对象上每个key的数据调用defineReactive

    • defineReactive: 通过Object.defineProperty设置对象的key属性,使得能够捕获到该属性值的set/get动作。一般是由Watcher的实例对象进行get操作,此时Watcher的实例对象将被自动添加到Dep实例的依赖数组中,在外部操作触发了set时,将通过Dep实例的notify来通知所有依赖的watcher进行更新。

    如果不太理解上面的文字描述可以看一下图:

    clipboard.png

    Dep

    DepObserverWatcher之间的纽带,也可以认为Dep是服务于Observer的订阅系统。Watcher订阅某个ObserverDep,当Observer观察的数据发生变化时,通过Dep通知各个已经订阅的Watcher

    Dep提供了几个接口:

    • addSub: 接收的参数为Watcher实例,并把Watcher实例存入记录依赖的数组中

    • removeSub: 与addSub对应,作用是将Watcher实例从记录依赖的数组中移除

    • dependDep.target上存放这当前需要操作的Watcher实例,调用depend会调用该Watcher实例的addDep方法,addDep的功能可以看下面对Watcher的介绍

    • notify: 通知依赖数组中所有的watcher进行更新操作

    Watcher

    Watcher是用来订阅数据的变化的并执行相应操作(例如更新视图)的。Watcher的构造器函数定义如下:

    constructor (vm, expOrFn, cb, options) {
      this.vm = vm
      vm._watchers.push(this)
      // options
      if (options) {
        this.deep = !!options.deep
        this.user = !!options.user
        this.lazy = !!options.lazy
        this.sync = !!options.sync
      } else {
        this.deep = this.user = this.lazy = this.sync = false
      }
      this.cb = cb
      this.id = ++uid // uid for batching
      this.active = true
      this.dirty = this.lazy // for lazy watchers
      this.deps = []
      this.newDeps = []
      this.depIds = new Set()
      this.newDepIds = new Set()
      this.expression = process.env.NODE_ENV !== 'production'
        ? expOrFn.toString()
        : ''
      if (typeof expOrFn === 'function') {
        this.getter = expOrFn
      } else {
        this.getter = parsePath(expOrFn)
        if (!this.getter) {
          this.getter = function () {}
          process.env.NODE_ENV !== 'production' && warn(
            `Failed watching path: "${expOrFn}" ` +
            'Watcher only accepts simple dot-delimited paths. ' +
            'For full control, use a function instead.',
            vm
          )
        }
      }
      this.value = this.lazy
        ? undefined
        : this.get()
    }

    参数中,vm表示组件实例,expOrFn表示要订阅的数据字段(字符串表示,例如a.b.c)或是一个要执行的函数,cb表示watcher运行后的回调函数,options是选项对象,包含deepuserlazy等配置。

    watcher实例上有这些方法:

    • get: 将Dep.target设置为当前watcher实例,在内部调用this.getter,如果此时某个被Observer观察的数据对象被取值了,那么当前watcher实例将会自动订阅数据对象的Dep实例

    • addDep: 接收参数dep(Dep实例),让当前watcher订阅dep

    • cleanupDeps: 清除newDepIdsnewDep上记录的对dep的订阅信息

    • update: 立刻运行watcher或者将watcher加入队列中等待统一flush

    • run: 运行watcher,调用this.get()求值,然后触发回调

    • evaluate: 调用this.get()求值

    • depend: 遍历this.deps,让当前watcher实例订阅所有dep

    • teardown: 去除当前watcher实例所有的订阅

    Array methods

    src/core/observer/array.js中,Vue框架对数组的pushpopshiftunshiftsortsplicereverse方法进行了改造,在调用数组的这些方法时,自动触发dep.notify(),解决了调用这些函数改变数组后无法触发更新的问题。在Vue的官方文档中对这个也有说明:http://cn.vuejs.org/v2/guide/list.html#变异方法

    本文转自https://segmentfault.com/a/1190000008377887

    展开全文
  • __ob__: Observer这些数据是vue这个框架对数据设置的监控器,一般都是不可枚举的。 console.log这样的打印函数,被打印的变量会执行自身的toString(),这样,即便内部属性是不可枚举,实际上也能看到。 操作数据的...
  • 文章目录描述定义类型动机UML类图时序图实现主要角色示例适用场景优点缺点相关模式 描述 定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。...
  • observer 简单实例

    2018-01-30 16:04:59
    #include "Publicinc.hpp" ...class Observer { public:  virtual ~Observer() { }  virtual void Update(int n) = 0; }; class Subject {  typedef std::vector ObserverList;  type
  • Observer (观察者) 模式

    2020-09-08 14:49:50
    17.1 Observer模式   Observer 的意思是 “进行观察的嗯”,也就是 “观察者” 的意思。   在 Observer 模式中,当观察对象的状态发生变化时,会通知观察者。Observer 模式适用于根据对象状态进行相应处理的场景...
  • 设计模式——Observer模式

    千次阅读 2019-07-18 14:10:25
    观察者模式(Observer Pattern) —— 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。 观察者模式可以理解为发布-订阅模式,即多个订阅者(观察...
  • vue的[__ob__: Observer]

    万次阅读 2018-12-14 13:27:22
    这是被vue接管的数据,observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。 在初次渲染以后,常规方法对data里面的数据(官方可以相应的操作只有7种,还有...
  • Android中内容观察者的使用---- ContentObserver类详解

    万次阅读 多人点赞 2012-09-16 17:35:52
           前言: 工作中,需要开启一个线程大量的查询某个数据库值发送了变化,导致的开销很大,后来在老大的指点下,利用了  ContentObserver完美的解决了该问题,感到很兴奋,做完之后自己也对...
  • 需求是这样的 就是构建月份的组件中,月份小于10月的时候 显示的数字都是一个位数,需要转换成两位数, 比如8月份是8 ,那就要转换为08 ,同理可得 其他低于十月份的月份也是要这样做: 打开组件的js文件 ...
  • vue 中 [__ob__: Observer]问题

    万次阅读 2019-03-13 10:43:50
    __ob__: Observer这些数据是vue这个框架对数据设置的监控器,一般都是不可枚举的。 首先我们要把这个数据获取原始数据 JSON.stringify([data]) 变成字符串 然后在用JSON.parse()将数据转换为 JavaScript 对象 ...
  • Zookeeper之基于Observer部署架构

    千次阅读 2019-01-28 23:06:08
    Observers:在不伤害写性能的情况下扩展Zookeeper 尽管通过Client直接连接到Zookeeper集群的性能已经非常好了,但是这种架构如果要承受超大规模的Client,就必须增加Zookeeper集群的Server数量,随着Server的增加,...
  •  Observer模式:定义了一种一对多的依赖关系,让多个观察者(Observer)同时监听某一主题对象(Subject)。当这个主题对象(Subject)的状态发生变化时,会通知观察者对象(Observer),让他们能够自动更新自己。 ...
  • 设计模式 观察者模式 以微信公众服务为例

    万次阅读 多人点赞 2016-08-10 19:20:09
    继续设计模式的文章,今天给大家带来观察者模式。 先来看看观察者模式的定义: 定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。 好了,对于定义的理解总是...
  • Java_观察者模式(Observable和Observer

    万次阅读 多人点赞 2013-04-11 23:28:27
    一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。 如果画面A是显示数据库里面的数据,而画面B修改了数据库里面的数据,那么这时候画面...
  • 观察者模式及c++实现

    万次阅读 2012-02-07 16:06:52
    观察者模式概念:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。“Define a one-to-many dependency between objects so that when one object ...
  • ZooKeeper学习之Observer模式及其配置

    千次阅读 2015-01-04 16:14:09
    除了leader和follow模式之外,还有第三种模式:observer模式。observer和follower在一些方面是一样的。详细点来讲,他们都向leader提交proposal。但与follower不同,observer不参与投票的过程。它简单的通过接收...
  • 前言: 包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图。观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,...
1 2 3 4 5 ... 20
收藏数 97,844
精华内容 39,137
关键字:

observer