我觉的很多文章都不保留版权的,我很多文章都被抄袭,却没有标明原作者和出处。
比如:
http://www.linuxidc.com/Linux/2013-04/82537p3.htm
http://www.07net01.com/linux/yizhiLINUXdewaiweishebeiqudongdaoQNXxitongzhong_162232_1365594620.html
http://www.cnblogs.com/xinyuyuanm/archive/2013/04/11/3014086.html
http://blog.chinaunix.net/uid-28305718-id-3577390.html
达内培训:http://www.sctarena.com/Article/Article.asp?nid=4133
 
原封不动照抄我的,无一注明出处,有的还注明原创,我那个去也,这是我的文章(日期2013年4月9号),原文链接:
http://www.cppblog.com/TianShiDeBaiGu/archive/2013/04/09/Driver__Linux_to_qnx.html
不止这一篇,希望以后有朋友转走的留个出处,盗取别人的文章然后用自己的签名是不道德的。


观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。


观察者 

(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。观察者模式的作用是:当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
观察者模式有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式。

我在面试的时候被问道观察者模式、MVC,结果没反应过来。
在PPTV被问道点击事件是怎么传给图形界面的,我也没理解他在问这个问题,后来才恍然大悟,估计被鄙视了。
这片文章也算是顺便证明一下我对设计模式的理解深度吧,我敢肯定的说,你们错过了一个C++高手。

在C++的许多库实现中、在MVC模型中、在博客订阅系统中,都使用了观察者模式。
对C++而言,这个模式最大的用处在于为C++添加事件概念(比如C#就直接在语法层面提供了事件的概念),像 object-c和JAVA提供委托,也是为了支持事件机制。

在《UNIX编程艺术》中提到软件设计最重要的是正交,解耦。作为UNIX程序员我原本只知道这么告诉别人“数据与逻辑分离”、“将策略和机制分开”,后来应用程序界面设计者就是告诉我:这个东西是符合“Model-View-Control”的,然后我整理了一下才明白MVC也是观察者模式的一种机制.

好了,我们省事一点,改百度百科的代码吧。
原地址:
http://baike.baidu.com/view/1854779.htm

业务逻辑是:在MVC中,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。
UML图如下:

观察者

(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。

被观察

被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。

撤销观察

观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。

C++代码:
//filename observer.h
#include <iostream>
#include <set>
#include <string>
using namespace std;
/////////////////////抽象模式定义
class CObservable;
//观察者,纯虚基类
class CObserver
{
public:
    CObserver(){};
    virtual ~CObserver(){};
    //当被观察的目标发生变化时,通知调用该方法
    
//来自被观察者pObs, 扩展参数为pArg
    virtual void Update(CObservable* pObs, void* pArg = NULL) = 0;
};
//被观察者,即Subject
class CObservable
{
public:
    CObservable() : m_bChanged(false) {};
    virtual ~CObservable() {};

    void Attach(CObserver* pObs);   //注册观察者
    void Detach(CObserver* pObs);   //注销观察者
    void DetachAll();               //注销所有观察者
    void Notify(void* pArg = NULL); //若状态变化,则遍历观察者,逐个通知更新
    bool HasChanged();              //测试目标状态是否变化
    int GetObserversCount();        //获取观察者数量
protected:
    void SetChanged();              //设置状态变化!!!必须继承CObservable才能设置目标状态
    void ClearChanged();            //初始化目标为未变化状态
private:
    bool m_bChanged;                //状态
    set<CObserver*> m_setObs;       //set保证目标唯一性
};
/////////////////////抽象模式实现
void CObservable::Attach(CObserver* pObs){
    if (!pObs) return;
    m_setObs.insert(pObs);
}
void CObservable::Detach(CObserver* pObs){
    if (!pObs) return;
    m_setObs.erase(pObs);
}
void CObservable::DetachAll(){
    m_setObs.clear();
}
void CObservable::SetChanged(){
    m_bChanged = true;
}
void CObservable::ClearChanged(){
    m_bChanged = false;
}
bool CObservable::HasChanged(){
    return m_bChanged;
}
int CObservable::GetObserversCount(){
    return m_setObs.size();
}
void CObservable::Notify(void* pArg /* = NULL */){
    if (!HasChanged()) return;
    cout << "notify observers…" << endl;
    ClearChanged();
    set<CObserver*>::iterator itr = m_setObs.begin();
    for (; itr != m_setObs.end(); itr++){
        (*itr)->Update(this, pArg);
    }
}
/////////////////////具体应用类定义和实现
//bloger是发布者,即被观察者(subject)
class CBloger : public CObservable
{
public:
    void Publish(const string &strContent){
        cout << "bloger publish, content: " << strContent << endl;
        SetChanged();
        Notify(const_cast<char*>(strContent.c_str()));
    }
};
//portal是发布者,即被观察者(subject)
class CPortal : public CObservable
{
public:
    void Publish(const string &strContent){
        cout << "portal publish, content: " << strContent << endl;
        SetChanged();
        Notify(const_cast<char*>(strContent.c_str()));
    }
};
//RSS阅读器,观察者
class CRSSReader : public CObserver
{
public:
    CRSSReader(const string &strName) : m_strName(strName){}
    virtual void Update(CObservable* pObs, void* pArg = NULL){
        char* pContent = static_cast<char*>(pArg);
        //观察多个目标
        if (dynamic_cast<CBloger*>(pObs)){
            cout << m_strName << " updated from bloger, content: " << pContent << endl;
        }else if (dynamic_cast<CPortal*>(pObs)){
            cout << m_strName << " updated from portal, content: " << pContent << endl;
        }
    }
private:
    string m_strName;
};
//Mail阅读器,观察者
class CMailReader : public CObserver
{
public:
    CMailReader(const string &strName) : m_strName(strName){}
    virtual void Update(CObservable* pObs, void* pArg = NULL){
            char* pContent = static_cast<char*>(pArg);
            if (dynamic_cast<CBloger*>(pObs)){
                cout << m_strName << " updated from bloger, content: " << pContent << endl;
            }
            if (dynamic_cast<CPortal*>(pObs)){
                cout << m_strName << " updated from portal, content: " << pContent << endl;
            }
        }
private:
    string m_strName;
};

测试用例:

#include "observer.h"
int main()
{
                                  //目标(被观察者)
    CBloger* pBloger = new CBloger();
    CPortal* pPortal = new CPortal();
                                  //观察者. 一个观察者可以观察多个目标
    CRSSReader* pRssReader = new CRSSReader("rss reader");
    CMailReader* pMailReader = new CMailReader("mail reader");
    pBloger->Attach(pRssReader);  //bloger注册观察者
    pBloger->Attach(pMailReader); //bloger注册观察者
    pPortal->Attach(pRssReader);  //portal注册观察者
    pPortal->Attach(pMailReader); //portal注册观察者
                                  
//博客发布信息
    pBloger->Publish("博客分享设计模式");
    cout << endl;
                                  //门户发布信息
    pPortal->Publish("门户分享设计模式");
    cout << "\nportal detached mail reader" << endl;
    
    pPortal->Detach(pMailReader);
    
    cout << "portal observers count: " << pPortal->GetObserversCount() << endl << endl;
    pPortal->Publish("门户分享设计模式");
    
    system("pause");
    return 0;
}