MyException - 我的异常网
当前位置:我的异常网» C++ » 观察者模式的困惑,该怎么处理

观察者模式的困惑,该怎么处理

www.MyException.Cn  网友分享于:2013-03-14  浏览:8次
观察者模式的困惑
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中针对不同的消息 建立不同的观察者列表

文章评论

程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
代码女神横空出世
代码女神横空出世
为什么程序员都是夜猫子
为什么程序员都是夜猫子
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
我是如何打败拖延症的
我是如何打败拖延症的
编程语言是女人
编程语言是女人
我的丈夫是个程序员
我的丈夫是个程序员
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
旅行,写作,编程
旅行,写作,编程
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
一个程序员的时间管理
一个程序员的时间管理
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
Java程序员必看电影
Java程序员必看电影
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
漫画:程序员的工作
漫画:程序员的工作
程序员应该关注的一些事儿
程序员应该关注的一些事儿
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
鲜为人知的编程真相
鲜为人知的编程真相
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
中美印日四国程序员比较
中美印日四国程序员比较
如何成为一名黑客
如何成为一名黑客
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
10个调试和排错的小建议
10个调试和排错的小建议
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
那些争议最大的编程观点
那些争议最大的编程观点
程序员都该阅读的书
程序员都该阅读的书
程序员必看的十大电影
程序员必看的十大电影
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有