Observer(观察者)模式又被称作发布-订阅(Publish-Subscribe)
设计模式吧
全部回复
仅看楼主
level 5
2005年10月19日 01点10分 1
level 5
五、举例Observer模式是一个应用比较广泛的模式,在Java中,Observer模式的应用随处可见(可参考笔记13中关于Java中CoR与Observer模式的对比部分内容),此外,JDK中特别提供了java.util.Observable类和Observer接口来方便程序员应用Observer模式,而C++方面,ATL则提供了IConnectionPointContainer、IConnectionPoint、IEnumConnectionPoints、IEnumConnections等以支持所谓的连接点及可连接对象等(相关示例见参考1),而在MFC中,一个文档可以对应多个视图,而当文档发生更新后,可以通过UpdateAllViews来同步更新所有视图,这虽然并非严格意义上的Observer模式的应用,但其本质是相似的。前面曾经从Mediator模式的角度实现过一个ChatRoom的例子,这里用Observer模式来解决同一问题:#include
#include
using namespace std;class ChatRoom;struct Observer{ virtual void SetChatRoom(ChatRoom* pChatRoom) = 0; virtual void Notify(const string& from, const string& to, const string& msg) = 0;};class ChatRoom // Subject{private: vector
vo;public: virtual ~ChatRoom() { vector
::iterator vi = vo.begin(); for (; vi != vo.end(); vi++) { delete *vi; } } void Login(Observer* po) { vo.push_back(po); po->SetChatRoom(this); } void Logout(Observer* po) { vector
::iterator vi = vo.begin(); for (; vi != vo.end(); vi++) { if (*vi == po) vo.erase(vi); } } void Notify(const string& from, const string& to, const string& msg) { vector
::iterator vi = vo.begin(); for (; vi != vo.end(); vi++) { (*vi)->Notify(from, to, msg); } }};class Chater : public Observer // ConcreteObserver{private: string name; ChatRoom* pChatRoom;public: Chater(const string& name) : name(name) {} void SetChatRoom(ChatRoom* pChatRoom) { this->pChatRoom = pChatRoom; } void Send(const string& to, const string& msg) { pChatRoom->Notify(name, to, msg); } void Notify(const string& from, const string& to, const string& msg) { if (0 == to.compare(name)) { cout << "[" << from.c_str() << "] to [" << to.c_str() << "]: " << msg.c_str() << endl; } }};int main(){ ChatRoom cr; Chater* c1 = new Chater("David"); Chater* c2 = new Chater("Jordan"); Chater* c3 = new Chater("O'Neal"); cr.Login(c1); cr.Login(c2); cr.Login(c3); c1->Send("Jordan", "You are a great basketball player"); // Send message to change subject state c2->Send("O'Neal", "Work hard, you are great!"); return 0;}在上述示例中,引起Subject(即ChatRoom)发生变化的是Observer(即Chater),而接收Subject发出的Notify消息的同样是Observer,这在有些应用中可能是两个/类不同的实体。此外,在上述示例中,当ChatRoom接收到消息时,不会对消息的内容进行解析,而是直接通过Notify通知所有Chater,由所有 Chater自己负责检查该消息是否是发送给自己的(实际的ChatRoom不可能采用这种形式),这在一定程度上与广播非常相似,所以有时候,我们可以采用Observer模式来模拟软件广播。以上示例中,Subject不对消息的内容进行检查,而是盲目地进行广播,在具体应用中,我们可以结合使用Mediator模式和Observer模式,将Subject设计成一个Mediator,对消息内容进行检查,进而根据消息内容进行消息的Publish。
2005年10月19日 01点10分 3
1