首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

观察者模式的疑惑

2013-01-05 
观察者模式的困惑1. 一个被观察的类A 有多个成员函数 a, b 假如观察他的B只关心a函数的变化, 另外一个观察

观察者模式的困惑
1. 一个被观察的类A 有多个成员函数 a, b 假如观察他的B只关心a函数的变化, 另外一个观察者C只关心b的变化
  那么如何设计A, 我现在的方案是 在a, b里都notify, 但这样a变化时C也会收到冗余消息.
  
  那么是否应保证大多数情况下A的成员尽量相关, 把关心不大的函数/变量移出A类, 则冗余消息将减少, 但仍不可避免?

2. B同时观察多个对象A, D, 但当一个对象改变是可能会在A内notify多次, 或A只notify1次但D也被改变导致D里也notify了一次
   这样B就会收到重复的消息, 如何避免这个问题

3. 被观察的对象A,有几个要被观察的成员a, b, 如何确保在a, b发生变化的时候肯定在里面写了notify, 只能靠仔细?
   尤其是A又有派生类的时候, 在代码中会出现很多的notify函数调用
[解决办法]
1. 基本同意, 如果一个类会产生两个不同的 notify, 把他们分成两个类应该是对的.如果还有冗余说明类分得还不够细.
2. 如果 A 的状态变化了多次,收到多个 notify 很正常呀. 如果 A 只变化了一次, 看不出什么情况会导致 A 内 notify 多次.
   D 是另外一个目标,他产生的 notify 和 A 是不同类型的,怎么能算重复的 notify?
3. 把变化的相关操作封装起来, 和 notify 绑定. 外面只能访问封装后的方法,不能直接改变状态不就可以了吗?
[解决办法]
1.
那是否说明a,b是不同组的观察者呢

值看过一点观察者模式没有实际用过
来学习学习
[解决办法]
1、对于第一个可以把A设置为C、B的父类,使用类的继承机制,然后设置两个标记变量,分别用于a和b,B、C只需要访问像应的变量就行。

2、避免重复的notify,这要看A、D这两个类是不是应该更细的划分一下,使两者有更少的关联

3、定义两个适当的变量,分别记录a函数和b函数,在a、b方法体中分别实现对变量的改变
[解决办法]
第一个问题
项目里有一个类似的需求,比LZ的情况复杂很多,这边简要介绍观察者这部分的
本质上是多subject和在observer下面增加一层抽象:
对于关注不同成员的类集合,归一到成不同的group
observer下面增加一层observer2,分别为处理不同消息的基类,通过一个flag,已确定自身处理的消息,observer2下面是具体的实例累。


第二个问题
对于多nodify的问题,个人感觉从设计的角度可以尽量遵循SRP原则,从代码的角度来看,可以考虑加标示~

第三个问题
封装变化
[解决办法]
楼主的问题是在缺乏项目经验的情况下具有很大想当然的成分。首先,如果一个subject要通知多个observer,且不同的observer观察不同的数据,则应在notify时加上事件成员,这点在设计模式中讲得很清除。
第二个问题本人在设计中尚未遇到,设计模式给出的观点是通过manager来代理处理A,D前后发生的变化,直到变化均完成以后再行通知。再者,即使都发生通知,应考虑A,D数据变化是否得到不同的展现,则通知到的观察者显然应分辨出通知来自A,和D的不同。
第三个问题还是个发生事件通知的问题,观察者应向目标注册自己感兴趣的事件。无论你怎样继承,不同类中发生变化的事件应是不同的。
最后要强调一点,观察者绝不会脱离目标而观察,能复用的观察者都是保留了对特定目标的接口操作。而一般的项目中,非特殊情况是不用提炼目标接口的,所以这也是为什么在Qt的模型视图框架中的视图在接收模型时仅接收一个模型。如果楼主有兴趣学习Qt,可以思考下这个问题。更大的复用来自目标---->领域模型。

[解决办法]

引用:
1. 基本同意, 如果一个类会产生两个不同的 notify, 把他们分成两个类应该是对的.如果还有冗余说明类分得还不够细.
2. 如果 A 的状态变化了多次,收到多个 notify 很正常呀. 如果 A 只变化了一次, 看不出什么情况会导致 A 内 notify 多次.
  D 是另外一个目标,他产生的 notify 和 A 是不同类型的,怎么能算重复的 notify?
3. 把变化的相关操……


也可以不需要细分,但是要做判断
[解决办法]
在注册观察者时需要根据观察的不同注册不同的消息 
比如:
AddObserver(const char* msg, Observer* pObserver)

在类A中针对不同的消息 建立不同的观察者列表

热点排行