body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

常见设计模式的解析和实现(C++)之十五-Observer模式  
作用:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.
解析:
Observer 模式定义的是一种一对多的关系,这里的一就是图中的 Subject 类,而多则是 Obesrver 类,当 Subject 类的状态发生变化的时候通知与之对应的 Obesrver 类们也去相应的更新状态,同时支持动态的添加和删除 Observer 对象的功能.Obesrver 模式的实现要点是,第一一般 subject 类都是采用链表等容器来存放 Observer 对象,第二抽取出 Observer 对象的一些公共的属性形成 Observer 基类,而 Subject 中保存的则是 Observer 类对象的指针,这样就使 Subject 和具体的 Observer 实现了解耦,也就是 Subject 不需要去关心到底是哪个Observer对放进了自己的容器中.生活中有很多例子可以看做是 Observer 模式的运用,比方说,一个班有一个班主任(Subject),他管理手下的一帮学生(Observer),当班里有一些事情发生需要通知学生的时候,班主任要做的不是逐个学生挨个的通知而是把学生召集起来一起通知,实现了班主任和具体学生的关系解耦.
#ifndef __OBSERVE_H__
#define __OBSERVE_H__
#include<iostream>
#include<list>
typedef int state;
using namespace std;
class Observer;
class Subject
{
        public:
                Subject():_subjectState(-1){}
                virtual ~Subject();  // 这边要删除开辟的空间
                void attach(Observer*);
                void detach(Observer*);
                void notify();
                virtual int getState();
                virtual void setState(state);
        protected:
                state _subjectState;
                list<Observer*> _observerList;
};
class ConcreteSubject:public Subject
{
        public:
                ConcreteSubject(){}
                int getState();
                void setState(state);
                virtual ~ConcreteSubject(){}
};
class Observer
{
        public:
                Observer():_obState(-1){}
                virtual void update(Subject*) = 0;
                virtual ~Observer(){}
        protected:
                state _obState;
};
class ConcreteObserver:public Observer
{
        public:
                ConcreteObserver(){}
                void update(Subject*);
                ~ConcreteObserver(){}
};
#endif
#include"observer.h"
#include<algorithm>
#include<iterator>
#include<iostream>
using namespace std;
Subject::~Subject()
{
        cout<<"~Subject()"<<endl;
        list<Observer*>::iterator it = _observerList.begin();
        for(;it!=_observerList.end();++it)
        {
                delete *it;
        }
        _observerList.clear();
}
void Subject::attach(Observer* pObs)
{
        if(NULL!=pObs)
                _observerList.push_back(pObs);
}
void Subject::detach(Observer* pObs)
{
        list<Observer*>::iterator it = find(_observerList.begin(),_observerList.end(),pObs);
        if(it!=_observerList.end())
                _observerList.erase(it);
}
void Subject::notify()
{
        list<Observer*>::iterator it = _observerList.begin();
        for(;it!=_observerList.end();++it)
                //(*(*it)).update(this); // 这里必须要两个括号,*(*it).update(this);  是错的
                (*it)->update(this);
//        for(auto& it:_observerList) // 不知道为什么在这里不行啊,说是C++11不让声明没有类型的变量
//                it->update(this);
}
int Subject::getState()
{
        return _subjectState;
}
void Subject::setState(state newState)
{
        _subjectState = newState;
}
/*   ConcreteSubject   */
int ConcreteSubject::getState()
{
        return _subjectState;  // 要访问这个,基类就不能是私有成员,重新设置成保护
}
void ConcreteSubject::setState(state newState)
{
        _subjectState = newState;
}
/*   Observer   */
//直接传消息,叫推模式 string = ""
//传指针,    叫拉模式
void ConcreteObserver::update(Subject* pSub)
{
        if(_obState!=pSub->getState())
        {
                _obState = pSub->getState();
                cout<<"update state,Observer state now is "<<_obState<<endl;
        }
}
#include<iostream>
#include"observer.h"
using namespace std;
int main()
{
        Observer* p1 = new ConcreteObserver;
        Observer* p2 = new ConcreteObserver;
        Subject* p = new ConcreteSubject;
        p->attach(p1);
        p->attach(p2);
        p->setState(5);
        p->notify();  // subject对象通知所有observer对象
        p->detach(p1);
        p->setState(10);
        p->notify();
        delete p;
        return 0;
}

Observer,观察者模式,C++描述的更多相关文章

  1. C++设计模式-Observer观察者模式

    Observer观察者模式作用:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己 UML图: S ...

  2. Observer 观察者模式

    简介       观察者模式(Observer),有时又被称为[发布]publish-[订阅]Subscribe模式.模型-视图(View)模式.源-收听者(Listener)模式或从属者模式.在此种 ...

  3. 委托、事件、Observer观察者模式的使用解析二

    一.设计模式-Observer观察者模式 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新.Observer模式是一种 ...

  4. Observer观察者模式与OCP开放-封闭原则

    目录 场景引入 在联网坦克项目中使用观察者模式 总结 在学习Observer观察者模式时发现它符合敏捷开发中的OCP开放-封闭原则, 本文通过一个场景从差的设计开始, 逐步向Observer模式迈进, ...

  5. Observer 观察者模式 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  7. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

  8. 设计模式 ( 十七 ):Observer 观察者模式 -- 行为型

    1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是 ...

  9. 设计模式(19)--Observer(观察者模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图( ...

  10. 【pattern】设计模式(3) - Observer观察者模式

    源码地址:https://github.com/vergilyn/design-patterns 另外一个大神很全的Github:https://github.com/iluwatar/java-de ...

随机推荐

  1. Python 闭包(Closure)

    Python  闭包 (Closure) 这里介绍一下python 的闭包 基本概念 闭包(closure)是函数式编程的重要的语法结构. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函 ...

  2. Python Appium 滑动、点击等操作

    Python Appium 滑动.点击等操作 1.手机滑动-swipe # FileName : Tmall_App.py # Author : Adil # DateTime : 2018/3/25 ...

  3. Unity Shader入门精要之 screen post-processing effect

    本篇记录了学习Unity Shader入门精要的屏幕后处理的一些知识点. OnRenderImage(RenderTexture src, RenderTexture dest) 以上函数是Unity ...

  4. LeetCode--011--盛最多水的容器(java)

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...

  5. 20170923xlVBA_UpdateClientDetailSQL_Dictionary

    Sub UpdateClientDetailWGQ() Dim Wb As Workbook Dim Sht As Worksheet Dim Rng As Range Dim Arr As Vari ...

  6. Luffy之虚拟环境.项目搭建,目录日志等配置信息

    1. 项目开发前 1.1 虚拟环境virtualenv 如果在一台电脑上, 想开发多个不同的项目, 需要用到同一个包的不同版本, 如果使用上面的命令, 在同一个目录下安装或者更新, 新版本会覆盖以前的 ...

  7. Subordinates CodeForces - 737C (树,构造)

    大意: 求构造一棵树, 每个节点回答它的祖先个数, 求最少打错次数. 挺简单的一个构造, 祖先个数等价于节点深度, 所以只需要确定一个最大深度然后贪心即可. 需要特判一下根的深度, 再特判一下只有一个 ...

  8. CF-413E-线段树

    http://codeforces.com/problemset/problem/413/E 给出一个2*N的格子图,每个格子要么是障碍要么是空地,M次询问(A,B)之间的最短距离. 采用分治的思想, ...

  9. CRM ORDER_MAINTAIN

    H: GUID CRMT_OBJECT_GUID RAW CRM 订单对象的 GUID BP_NUMBER BU_PARTNER 业务伙伴编号 FIRSTNAME BU_NAMEP_F 业务伙伴(人员 ...

  10. Docker Nginx 配置多个子域名

    参考:nginx server_name实用:配置多个子域名 在腾讯购置了域名服务,想直接配置二级域名映射到指定端口,发现腾讯不支持端口映射的方式. 想了一下,域名默认解析80端口,只能通过nginx ...