蜗牛的家
男儿当自强
posts - 48,  comments - 21,  trackbacks - 0
意图:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新
UML图:

适用
当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这两者封装在独立的对象中以使他们可以各自独立地改变和复用
当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变
当一个对象必须通知其他对象,而他又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的
//test.h
#include <list>

typedef 
int STATE;
using namespace std;
//////////////////////////////////////////////////////////////////////////
class Observer;

class Subject
{
public:
    Subject() : m_nSubjectState(
-1){}
    
virtual ~Subject();
    
    
void Notify();  //通知对象改变状态
    void Attach(Observer *pObserver);  //新增对象
    void Detach(Observer *pObserver);  //删除对象
    
    
virtual void Setstate(STATE nState);
    
virtual STATE Getstate();
protected:
    STATE m_nSubjectState;
    list
<Observer*> m_listObserver;
}
;

//被更新的类
class Observer
{
public:
    Observer() : m_nObserverState(
-1){}
    
virtual ~Observer(){}

    
virtual void Update(Subject* pSubject) = 0//更新状态
protected:
    STATE m_nObserverState;
}
;

class ConCreateSubject : public Subject
{
public:
    ConCreateSubject() : Subject()
{}
    
virtual ~ConCreateSubject(){}
    
    
virtual void SetState(STATE nState);
    
virtual STATE GetState();
}
;

class ConCreateObserver : public Observer
{
public:
    ConCreateObserver() : Observer()
{}
    
virtual ~ConCreateObserver(){}

    
virtual void Update(Subject* pSubject);
}
;

// test.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include 
<iostream>
#include 
<algorithm>
#include 
"test.h"

using namespace std;
//////////////////////////////////////////////////////////////////////////
void Subject::Attach(Observer *pObserver)
{
    cout 
<< "Attach an Observer\n";
    m_listObserver.push_back(pObserver);
}


void Subject::Detach(Observer *pObserver)
{
    list
<Observer*>::iterator iter;
    iter 
= find(m_listObserver.begin(),m_listObserver.end(),pObserver);
    
if (m_listObserver.end() != iter)
    
{
        m_listObserver.erase(iter);
    }

    cout 
<< "Detach an ObServer\n";
}


void Subject::Notify()
{
    cout 
<< "Notify Observer's state\n";
    list
<Observer*>::iterator iter1,iter2;
    
for (iter1 = m_listObserver.begin(),iter2 = m_listObserver.end(); iter1 != iter2; ++iter1)
    
{
        (
*iter1)->Update(this); //更新链表中所有对象的状态
    }

}


void Subject::Setstate(STATE nState)
{
    cout 
<< "SetState by Subject \n";
    m_nSubjectState 
= nState;
}


STATE Subject::Getstate()
{
    cout 
<< "Getstate by Subject\n";
    
return m_nSubjectState;
}


Subject::
~Subject()
{
    list
<Observer*>::iterator iter1,iter2,temp;
    
for (iter1 = m_listObserver.begin(),iter2 = m_listObserver.end(); iter1 != iter2;)
    
{
        temp 
= iter1;
        
++iter1;
        delete (
*temp);
    }

    
    m_listObserver.clear();
}


void ConCreateSubject::SetState(STATE nState)
{
    cout 
<< "Setstate by ConCreateSubject\n";
    m_nSubjectState 
= nState;
}


STATE ConCreateSubject::GetState()
{
    cout 
<< "Getstate by ConCreateSubject\n";
    
return m_nSubjectState;
}


void ConCreateObserver::Update(Subject* pSubject)
{
    
if (NULL == pSubject)
    
{
        
return;
    }

    m_nObserverState 
= pSubject->Getstate();
    
    cout 
<< "The ObserverState is" << m_nObserverState<< endl;
}

//////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
    Observer 
*p1 = new ConCreateObserver;
    Observer 
*p2 = new ConCreateObserver;
    
    Subject 
*= new ConCreateSubject;
    p
->Attach(p1);
    p
->Attach(p2);
    p
->Setstate(4);
    p
->Notify();
    
    p
->Detach(p1);
    p
->Setstate(10);
    p
->Notify();
    
    delete p;

    system(
"pause");
    
return 0;
}


posted on 2008-08-21 23:38 黑色天使 阅读(800) 评论(1)  编辑 收藏 引用 所属分类: 设计模式

FeedBack:
# re: C++设计模式-Observer
2012-05-09 15:58 | no7dw
ConCreateSubject::SetState(STATE nState);

STATE Subject::Setstate()

has a little typing error ,('S' should not a CAPical letter ) this error leads to ConCreateSubject::SetState NOT a virtual effect  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(2)

随笔分类

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜