博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《设计模式》学习笔记——观察者模式
阅读量:4111 次
发布时间:2019-05-25

本文共 2429 字,大约阅读时间需要 8 分钟。

        当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。用于定义对象间一对多的关系

意图:
    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:
    一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:
    一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:
    使用面向对象技术,可以将这种依赖关系弱化。
关键代码:
    在抽象类里有一个 ArrayList 存放观察者们。
应用实例:
    1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
    2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
优点: 
    1、观察者和被观察者是抽象耦合的。 
    2、建立一套触发机制。
缺点:
    1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 
    2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 
    3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
    一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
    一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
    一个对象必须通知其他对象,而并不知道这些对象是谁。

    需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项
    1、JAVA 中已经有了对观察者模式的支持类。
    2、避免循环引用。 
    3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
 

ObserverPattern.h

#pragma once#include
#include
#include
// 秘书类前向声明class Secretary;//观察者class ObserverPattern{public: ObserverPattern(Secretary * secretary):m_secretary(secretary){}; ~ObserverPattern() {}; void update(std::string action) // 事件更新 { std::cout << "action:" << action << std::endl; }private: Secretary * m_secretary;};// 秘书class Secretary{public: Secretary() { m_observerList.clear(); } ~Secretary() {} // 通知事件 void Notify(std::string action) { // 给所有的观察者发送事件消息 for (std::list
::iterator it= m_observerList.begin(); it!= m_observerList.end();it++) { (*it)->update(action); } } void setObserver(ObserverPattern* observer) { m_observerList.push_back(observer); }private: std::list
m_observerList;protected:};

 

ObserverPattern.cpp

#include "ObserverPattern.h"

 

mainTest.cpp

#include
#include
#include "ObserverPattern.h"int main(void){ // 创建一个秘书 Secretary* secretary = new Secretary; // 创建一些观察者,同时指定其秘书 ObserverPattern* observerpattern1 = new ObserverPattern(secretary); ObserverPattern* observerpattern2 = new ObserverPattern(secretary); ObserverPattern* observerpattern3 = new ObserverPattern(secretary); // 给秘书绑定其观察者 secretary->setObserver(observerpattern1); secretary->setObserver(observerpattern2); secretary->setObserver(observerpattern3); // 秘书通知消息 secretary->Notify("老虎来了!"); secretary->Notify("老虎吃人了!"); delete observerpattern3; delete observerpattern2; delete observerpattern1; delete secretary; system("pause"); return 0;}

 

转载地址:http://demsi.baihongyu.com/

你可能感兴趣的文章
LeetCode第48题思悟——旋转图像(rotate-image)
查看>>
驱动力3.0,动力全开~
查看>>
记CSDN访问量10万+
查看>>
Linux下Oracle数据库账户被锁:the account is locked问题的解决
查看>>
极客算法训练营学习笔记(一)
查看>>
记CSDN访问20万+
查看>>
Windows 环境下Webstorm 2020.3 版本在右下角找不到Git分支切换部件的一种解决方法
查看>>
Electron-Vue项目中遇到fs.rm is not a function问题的解决过程
查看>>
飞机换乘次数最少问题的两种解决方案
查看>>
有向无回路图的理解
查看>>
设计模式中英文汇总分类
查看>>
MFC实现五子棋游戏
查看>>
WPF实现蜘蛛纸牌游戏
查看>>
单例模式
查看>>
工厂方法模式
查看>>
模板方法模式
查看>>
数据结构之队列、栈
查看>>
数据结构之树
查看>>
数据结构之二叉树
查看>>
二叉树非递归遍历算法思悟
查看>>