场景:
1. 比如在界面开发中,多个窗口之间需要通讯,比较常见的方法就是各个窗口之间包含对其他窗口的引用,之后在需要时通过其他窗口的引用来调用相应的函数获取相应的值;
但是这个确定还是比较明显的,就是会造成窗口之间的依赖和耦合,想想测试或变异某个窗口时另一个窗口必须是没问题的,而另一个窗口编译又依赖它,这样成了反复依赖
导致编译不过或修改其中一个另一个就得相应的该。很麻烦,不好维护。
2. 还有的不切实际的解决办法是在窗口之间发送事件,比如qt得信号或win32的消息,但是这样会造成消息的泛滥,资源的滥用,而且都是主线程来处理事件,何必发事件呢?
解决办法:
1. 使用观察者模式来给观察者发送通知,让观察者及时响应,减少耦合。看实际的例子吧:
main.cpp
/*
 * File:   main.cpp
 */
#include <list>
#include <stdio.h>
#include <time.h>
#include <string>
#include <iostream>
using namespace std;
enum NotifyType 
{
    kUpdateOutputDir = 0,
    kUpdateTitle
};
class Observer;
/**
 * 1.抽象父类,不能实例化,目标.
 */
class Subject
{
public:
    virtual ~Subject()
    {
    }
    virtual void Attach(Observer* observer);
    virtual void Detach(Observer* observer);
    virtual void Notify(void *userdata,int type);
protected:
    Subject()
    {
    }
private:
    list<Observer*> observers_;
};
/**
 * 1.抽象父类,不能实例化,观察者.
 */
class Observer
{
public:
    virtual ~Observer()
    {
    }
    virtual void Update(void* userdata,int type)
    {
    }
protected:
    Observer()
    {
    }
private:
};
//Subject
void Subject::Attach(Observer* observer)
{
    observers_.push_back(observer);
}
void Subject::Detach(Observer* observer)
{
    observers_.remove(observer);
}
void Subject::Notify(void *userdata,int type)
{
    list<Observer*>::iterator theIterator;
    for (theIterator = observers_.begin(); theIterator != observers_.end();
            theIterator++)
    {
        (*theIterator)->Update(userdata,type);
    }
}
class DhDialog : public Subject, public Observer
{
public:
    DhDialog(){}
    ~DhDialog(){}
    void Update(void* userdata,int type)
    {
        //1.增加判断类型就是只想处理指定的消息
        switch(type)
        {
            case kUpdateOutputDir:
              {
                output_dir_ =  *((string*)userdata);
                std::cout << "I am in DhDialog: " << output_dir_ << std::endl;
                break;
             } 
        }
    }
    std::string title_;
    std::string output_dir_;
};
class DhOutputWindow : public Subject, public Observer
{
    public:
    DhOutputWindow(){}
    ~DhOutputWindow(){}
    void Update(void* userdata,int type)
    {
        //1.增加判断类型就是只想处理指定的消息
        switch(type)
        {
            case kUpdateTitle:
            {
                string title =  *((string*)userdata);
                //修改输出目录
                std::cout << "I am DhOutputWindow: " << title << std::endl;
                break;
            } 
        }
    }
}; 
int main(int argc, char* argv[])
{
    DhDialog dialog;
    DhOutputWindow output_window_;
    //1.互相监听,注意,这里是动态添加监听,并不是互相之间直接引用各自的对象.
    dialog.Attach(&output_window_);
    output_window_.Attach(&dialog);
    dialog.title_ = "I am infoworld";
    dialog.Notify(&dialog.title_,kUpdateTitle);
    string output = "C:\\";
    output_window_.Notify(&output,kUpdateOutputDir);
}
输出:
I am DhOutputWindow: I am infoworld I am in DhDialog: C:\
原文:http://blog.csdn.net/infoworld/article/details/39451909