【行为型】Observer模式

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

模式的编码结构参考如下:

 1 namespace observer
 2 {
 3     // -------- observer --------
 4     class Subject;
 5     class IObserver
 6     {
 7     public:
 8         // some code here........
 9         virtual void update(Subject* pSubject) = 0;
10
11     };//class IObserver
12
13     class ConcreteObserver1 : public IObserver
14     {
15     public:
16         // some code here........
17         virtual void update(Subject* pSubject) override {
18             // some code here........
19             const auto& theState = pSubject->getState();
20             // some other code here........
21         }
22
23     };//class ConcreteObserver1
24
25     // -------- subject --------
26     class Subject
27     {
28     public:
29         // some code here........
30         virtual void registeObserver(IObserver* pObserver) = 0;
31         virtual void unregisterObserver(IObserver* pObserver) = 0;
32         virtual void notify() = 0;
33
34     };//class Subject
35
36     class ConcreteSubject : public Subject
37     {
38     public:
39         // some code here........
40         virtual void registeObserver(IObserver* pObserver) override {
41             // some code here........
42             m_listObservers.push_back(pObserver);
43         }
44
45         virtual void unregisterObserver(IObserver* pObserver) override {
46             // some code here........
47             auto iter = std::find(m_listObservers.begin(), m_listObservers.end(), pObserver);
48             if (iter != m_listObservers.end()) {
49                 m_listObservers.erase(iter);
50             }
51         }
52
53         virtual void notify() override {
54             for_each(m_listObservers.begin(), m_listObservers.end(), [](const IObserver* pObj){ pObj->update(this); });
55         }
56
57     private:
58         std::list<IObserver*>   m_listObservers;
59
60     };//class ConcreteSubject
61
62 }//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)

时间: 2024-12-17 08:04:19

【行为型】Observer模式的相关文章

Java 实现观察者(Observer)模式

1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservable extends Observable { private int data; public UpdateObservable(Observer observer) { addObserver(observer); /* * add other observer */ } public int

C++ 实现观察者(Observer)模式详解

观察者(Observer)模式,是常见的模式之一.比如一份报纸,有很多订户.订阅者并不知道报纸何时会送来,他只知道自己订了这份报纸.订阅者在这里担任着观察者的角色,而报社则是被观察者. 报纸一旦印刷完毕,就应该及时送到订户手中,如果将报社看作一个对象,则报纸便是观察者(订户)和被观察者(报社)之间的纽带.观察者需要维护一个与报纸相关的变量或函数,在这个具体问题中,这个变量就是订户是否收到报纸,可设置为一个布尔型,当收到时,订户需要更新这个变量. 下面是源码: // "Observer.H&quo

Observer模式实践

Observer 模式在实践中的应用场景: 为 Point 类设计一个数据绑定机制,当其坐标 x 或 y 被更改时,可以通知外界其更改的过程.将更改过程打印在控制台上.考虑使用松耦合设计. 代码: #include <list> #include <iostream> using namespace std; struct Observer; struct Subject { virtual void attach(Observer*) = 0; virtual void deta

用java.util.Observable实现Observer模式

本文转载自:dada360778512的博客 原文链接:http://blog.csdn.net/dada360778512/article/details/6977758 Observer模式  主要是观察者与被观察者之间的关系 观察者为羊,被观察者为狼  模仿的场景为狼叫羊跑 代码如下: 1.被观察者类 [java] view plaincopy package test.pattern.observer; import java.util.Observable; public class 

创建型-生成器模式(Builder)

1.意图: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 2.场景描述: 编辑软件的“另存为”功能便是生成器模式的一个体现.例如,Word的另存为功能,可以选择将文件存储为doc.docx.pdf.txt等格式,但是通过word的另存为功能转变文档的存储格式时都采用了“文件 --> 另存为”,相同的创建过程.当需要对word支持新的类型转换时,例如,添加*.newtype类型的转换,此时只需在“另存为”对话框的“选择存储类型”中添加一行"*.newtype&q

Observer 模式

Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当"一"变化的时候,依赖这个"一"的多也能够同步改变.最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望 能够提供多种形式的表示 (例如以表格进行统计显示. 柱状图统计显示. 百分比统计显示等) .这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变.Observer模式就是解决了这一个问题. 1 ////////

Android 适配器(Adapter)、观察者(Observer) 模式

适配器(Adapter)详述:http://blog.csdn.net/jjwwmlp456/article/details/39893723 观察者(Observer)详述:http://blog.csdn.net/jjwwmlp456/article/details/39967021 AdapterView 体系 AdapterView中会使用Adapter Adapter 体系 BaseAdapter 实现了 SpinnerAdapter.ListAdapter 这样的形式,就是 适配器模

R型思维模式对软件开发的影响(草稿)

The pragmatic programmers 一直在工作之余读些书,之前主要是纯英文版的计算机相关的算法,编译器,数学等,想通过读这些书来提高自己每日工作效能,结果收效甚微.一是,因为纯英文的书,阅读的慢,第二,也是最重要的一点,发现掌握的很慢,思前想后感觉可能是和工作的内容距离较远,两者不能互相辅助,第三,不能直接的回馈工作本身. 索性就换一换类型,最先入手的,是<agile software development-principles, patterns, and practices

Observer模式详解--设计模式(15)

Observer模式来源: Observer模式应该可以说是应用最多.影响最广的模式之一. 因为Observer的一个实例Model/View/Control(MVC)结构在系统开发架构设计中有着很重要的地位和意义,MVC实现了业务逻辑和表示层的解耦.在MFC中,Doc/View(文档视图结构)提供了实现MVC的框架结构(有一个从设计模式(Observer模式)的角度分析分析Doc/View的文章正在进一步的撰写当中,遗憾的是时间:)).在Java阵容中,Struts则提供和MFC中Doc/Vi