码迷,mamicode.com
首页 > 其他好文 > 详细

[设计模式]_[观察者模式在项目中实际使用例子]

时间:2014-09-21 18:31:11      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:c++   观察者模式   项目应用   observer   subject   


场景:

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:\


[设计模式]_[观察者模式在项目中实际使用例子]

标签:c++   观察者模式   项目应用   observer   subject   

原文地址:http://blog.csdn.net/infoworld/article/details/39451909

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!