设计模式之观察者模式

设计模式

组件模式之"Observer"(观察者模式)

未经授权,禁止转载!创作不易,尊重原创!~~

背景

在软件构建过程中, 我们需要为某些对象建立一种“通知依赖关系”–一个对象(目标对象)的状态发生改变, 所有的依赖对象(观察者对象)都将得到通知,如果这样的依赖过于紧密,将使软件不能很好的抵御变化。
使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

case

王者荣耀游戏在新赛季通常会更新一次,需要用户重新下载安装包(class DownloadPkg)并进行安装。由于下载的安装包通常都比较大,因此下载界面的下方通过都会有一个进度条用来显示下载的进度,供召唤师们参考。“显示进度条”可以抽象成一个独立的功能,不仅在下载的过程中可以用,也可以在其他的场景下使用,例如“解压缩安装包”, 甚至打怪升级的游戏,在对战模式下怪物的血量(class HeroHP),本质上也是一个进度条(class ProgressBar)。
进度条可以进行各种花里胡哨的改进升级,但我们不希望每次升级进度条操作后, 还要对DownloadPkg, HeroHP这些类里的进度条功能跟着修改,这样维护的成本就太高了(上层调用的类千千万,一个个维护,累死个人)。我们希望修改完ProgressBar这个类后,自动通知到所有依赖它的类中,这样维护的成本就大大降低了。这就是观察者模式,

代码实现。

#include<iostream>

class ProgressBar {
 public:
  void showProgress(int cur_num, int total_num) {
    std::cout << "current progrss is: " << 100 * (cur_num*1.0 /total_num) << "% ." << std::endl;
  }
};

class DownloadPkg {
 public:
  void download() {
    int total_num = 10; 
    for (int i = 0; i < total_num; i++) {
      // fake download

      // show download progress
      progress_bar_.showProgress(i, total_num);
    }   
  }

 private:
  ProgressBar progress_bar_;
};
// main.cc
#include<iostream>
#include "progress_bar.h"

int main() {
  DownloadPkg pb;
  pb.download(); 
  
  return 0;
}

//方案2

class DownloadPkg {
 public:
  void download() {
    int total_num = 10;
    for (int i = 0; i <= total_num; i++) {
      // fake download

      // show download progress
      for (Progress* p : progress_vec_) {
        p->doProgress(i, total_num);
      }
    }
  }
..
 void add_progress(Progress* p) {
  progress_vec_.push_back(p);
 }

 void remove_progress() {
   if (!progress_vec_.empty()) {
     progress_vec_.pop_back();
   }
 }

 private:
  std::vector<Progress*> progress_vec_ ;
};

class HeroHP {
 public:
  void showHP() {
    int total_num = 10;
    for (int i = total_num; i > 0; i--) {
      // show download progress
      for (Progress* p : progress_vec_) {                                                                                                                                                                   
        p->doProgress(i, total_num);
      }
    }
  }

 void add_progress(Progress* p) {
  progress_vec_.push_back(p);
 }

 void remove_progress() {
   if (!progress_vec_.empty()) {
     progress_vec_.pop_back();
   }
 }

 private:
  std::vector<Progress*> progress_vec_ ;
..
};

// main.cc
#include<iostream>                                                                                                                                                                                          
#include "progress_bar.h"

int main() {
  DownloadPkg d_pkg;
  ProgressPercent p_percent;
  ProgressBar p_bar;
  d_pkg.add_progress(&p_percent);
  d_pkg.add_progress(&p_bar);
  d_pkg.download();

  HeroHP h_hp;
  h_hp.add_progress(&p_percent);
  h_hp.showHP();
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值