【行为型】Observer模式
观察者模式意图解决一对多的依赖关系情形中,当被依赖对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新的问题。举个很简单的例子说,假如一个游戏中的角色的某个属性状态发生了变化,此处不妨假设为角色的等级升级了,则相应的在游戏场景中的模型展现([依赖点1])需要跟着调整,并且在UI界面上的角色属性([依赖点2])描述细节中还需要及时更新成新等级值展现给玩家。这边的[依赖点1]与[依赖点2]就依赖于角色的属性,并且对于这两个依赖点来说,属性对它们都是很敏感的,它们需要能够及时感知到这些属性的变动。这种情形下就可考虑使用Observer模式。模式的类关系结构图参考如下:

模式的编码结构参考如下:
namespace observer
{
// -------- observer --------
class Subject;
class IObserver
{
public:
// some code here........
virtual void update(Subject* pSubject) = ; };//class IObserver class ConcreteObserver1 : public IObserver
{
public:
// some code here........
virtual void update(Subject* pSubject) override {
// some code here........
const auto& theState = pSubject->getState();
// some other code here........
} };//class ConcreteObserver1 // -------- subject --------
class Subject
{
public:
// some code here........
virtual void registeObserver(IObserver* pObserver) = ;
virtual void unregisterObserver(IObserver* pObserver) = ;
virtual void notify() = ; };//class Subject class ConcreteSubject : public Subject
{
public:
// some code here........
virtual void registeObserver(IObserver* pObserver) override {
// some code here........
m_listObservers.push_back(pObserver);
} virtual void unregisterObserver(IObserver* pObserver) override {
// some code here........
auto iter = std::find(m_listObservers.begin(), m_listObservers.end(), pObserver);
if (iter != m_listObservers.end()) {
m_listObservers.erase(iter);
}
} virtual void notify() override {
for_each(m_listObservers.begin(), m_listObservers.end(), [](const IObserver* pObj){ pObj->update(this); });
} private:
std::list<IObserver*> m_listObservers; };//class ConcreteSubject }//namespace observer
Observer模式编码结构参考
Observer模式对于面向对象的设计来说,个人认为其意义还是非常重大。试想如果没有该模式的设计,则Observer与Subject间的耦合性将会大大增强。更可怕的是如果一个Observer所依赖的Subject又不止一个的话,那系统 将会是错综复杂的,后期维护将相当可怕。Observer模式使得Observer与Subject的依赖性降到最小,仅仅只是简单地notify出去即可,并且对于Subject根本不知道(也不需要知道)不同的Observer是什么样的对象,它只负责将状态变动及时通知给注册进来的观察者即可。从而Observer与Subject可以很自然地形成层次结构设计,各自的职责分明。
在某些没有面向对象机制的语言中,是否也有办法实现Observer了?比如c语言。答案是肯定的。实现的技术手段也很简单:function pointer,具体就不详述了。当然该技术在c++中也是适用的,只是既然人家支持面向对象,自然多数人就不会想着函数指针这种费劲的技术手段。但是随着语言的发展、演变,std::function技术的出现,其实会让Observer模式的设计更加便捷,而且其耦合性会更进一步降低,有兴趣的同学可自行思想下。(提示:std::function+auto|std::bind)
【行为型】Observer模式的更多相关文章
- Java 实现观察者(Observer)模式
1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservab ...
- C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介
委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...
- Observer 模式
Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变.最常见的一个例子就是:对同一组数据进行 ...
- Behavioral模式之Observer模式
1.意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并被自己主动更新. 2.别名 依赖(dependents).公布-订阅(Publish-Subscr ...
- 3)Javascript设计模式:Observer模式
Observer模式 var Observer = (function() { var instance = null; function Observe() { this.events = {} } ...
- Java设计模式(20)观察者模式(Observer模式)
Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...
- Observer模式实践
Observer 模式在实践中的应用场景: 为 Point 类设计一个数据绑定机制,当其坐标 x 或 y 被更改时,可以通知外界其更改的过程.将更改过程打印在控制台上.考虑使用松耦合设计. 代码: # ...
- 设计模式之——Observer模式
Observer模式又叫做观察者模式,当观察对象状态发生变化的时候,就会通知给观察者.这种模式适用于根据对象状态进行响应的场景! 实例程序是一个输出数字的程序. 观察者Observer类用于每500m ...
- Observer模式(观察者设计模式)
Observer 设计模式? 在Observer模式中,当观察对象的状态发生变化时,会通知给观察者.Observer模式适用于根据对象状态进行相应处理的场景. Observer 并非主动观察,而是被动 ...
随机推荐
- 数学概念——J - 数论,质因数分解
J - 数论,质因数分解 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...
- 2012蓝桥杯本科组C/C++预赛题
微生物增殖 假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍). 一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y. ...
- git如何clone所有的远程分支
问题: 文/赖忠标 周末在家里改了下代码,新建了个angular版本的分支,然后push到coding.net上面了. 今天,到公司却不知道怎么拉取这个angular分支到公司的电脑上面.如下图(1) ...
- 跨平台通信中间件thrift学习【Java版本】(转)
转自:http://neoremind.com/2012/03/%E8%B7%A8%E5%B9%B3%E5%8F%B0%E9%80%9A%E4%BF%A1%E4%B8%AD%E9%97%B4%E4%B ...
- Spring Boot(spring mvc升级版)
周末挤出了一些时间,学了点东西,总结了一下,可能还有自己理解不到位的地方,希望大家一起交流学习,好东西要大家一起分享嘛~.时间有点紧张,所以样式没有来及做很好的调整,大家就凑活着看吧. Spring ...
- JVM运行数据区
1.java虚拟机在运行的时候会把内存分为以下几个区域,如图:
- HDU 4622 多校第三场1002 后缀自动机
比赛的时候我是用后缀数组的,但是T了. 赛后看了解题报告说,后缀数组貌似是卡你常数的时间,我算了下复杂度O(T * Q * n).这是10 ^ 8,但是考虑到每次询问的时候都要重新构造字符,所以那个n ...
- [yueqian_scut]蓝牙防丢器原理、实现与Android BLE接口编程
本文是对已实现的蓝牙防丢器项目的总结,阐述蓝牙防丢器的原理.实现与Android客户端的蓝牙BLE接口编程.在这里重点关注如何利用BLE接口来进行工程实现,对于BLE的协议.涉及到JNI的BLE接口内 ...
- LNMP wget 记录
源码下载 下载cmake(MySQL编译工具) http://www.cmake.org/files/v3.0/cmake-3.0.0.tar.gz 下载libmcrypt(PHPlibmcrypt模 ...
- Android系统移植与驱动开发——第五章--搭建开发板的测试环境
开发板上安装嵌入式系统要比手机上简洁很多,有很多扩展的接口,适合对程序进行测试,这里所提及的是S3C6410开发板.它是由三星公司推出的一款低功耗/高性价比的RISC处理器.,其中包含强大的硬件加速器 ...