设计模式(三):观察者模式

设计模式(三):观察者模式

定义:

​ ·多个观察者对象同时建通某一主题(通知者)对象,当该主题对象状态变化时会通知所有观察者对象,是他们能更新自己。

​ ·也就是说定义对象间的一种多对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决

​ ·一个对象状态的改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:

​ ·一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

以代码为例:

​ 类关系图如下

在这里插入图片描述

一、定义观察父类

#include <iostream>
#include <vector>//使用vector模板类,后面主题类需要使用

class Subject;//声明Subject主题类,作为observer观察类的友元类

class Observer
{
public:
  virtual ~Observer() {}
  
  virtual int getState() = 0;
  virtual void update( Subject *subject ) = 0;
  // ...
};

这里导入了vector模板库,方便主题类对已订阅的观察类进行管理。

二、定义ConcreateObserver子类来实现观察父类

class ConcreteObserver : public Observer
{
public:
  ConcreteObserver( const int state ) :
    observer_state( state ) {}
  
  ~ConcreteObserver() {}
  
  int getState()     //存储订阅的主题类的状态
  {
    return observer_state;
  }
  
  void update( Subject *subject );  //订阅主题状态何时更新
  // ...

private:
  int observer_state;
  // ...
};

三、定义主题类

class Subject
{
public:
  virtual ~Subject() {}
  
  void attach( Observer *observer )//定义函数存储订阅数
  {
    observers.push_back(observer);
  }
  
  void detach( const int index ) //定于函数输出取消订阅数
  {
    observers.erase( observers.begin() + index );
  }
  
  void notify()   //定义函数分发本主题通知给订阅本主题的所有订阅者(观察者)
  {
    for ( unsigned int i = 0; i < observers.size(); i++ )
    {
      observers.at( i )->update( this );
    }
  }
  
  virtual int getState() = 0;
  virtual void setState( const int s ) = 0;
  // ...

private:
  std::vector<Observer*> observers;
  // ...
};

四、实现主题类

class ConcreteSubject : public Subject
{
public:
  ~ConcreteSubject() {}
  
  int getState()
  {
    return subject_state;
  }
  
  void setState( const int s )
  {
    subject_state = s;
  }
  // ...
  
private:
  int subject_state;
  // ...
};

定义完所有类后对观察类的成员函数update()进行定义

void ConcreteObserver::update( Subject *subject )
{
  observer_state = subject->getState();
  std::cout << "Observer state updated." << std::endl;
}//函数作用就是获得订阅主题的更新信息并且存储信息。

五、main函数实现

int main()
{
  ConcreteObserver observer1( 1 );//定义观察者1
  ConcreteObserver observer2( 2 );//定义观察者2
  
  std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
  std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
  
  Subject *subject = new ConcreteSubject();
  subject->attach( &observer1 );//主题被观察者1订阅
  subject->attach( &observer2 );//主题被观察者2订阅
  
  subject->setState( 10 );//主题数据更新
  subject->notify();//主题把更新后信息分发给所有观察者
  
  std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
  std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
  
  delete subject;
  return 0;
}

运行后的结果

在这里插入图片描述

这样就简单实现了观察者模式。

观察者模式优缺点:

优点:

​ 1、观察者和被观察者是抽象耦合的。
​ 2、建立一套触发机制。

缺点:

​ 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

​ 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
观察者模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值