设计模式——观察者模式(C++)

上车了不说了,就直接放代码了哈,有问题可留言。

抽象观察者类、具体观察者类定义:

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:observer.h
@datetime:2016.09.10
@author:HJS
@e-mail:jingshuang_hu@163.com
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#ifndef _OBSERVER_H
#define _OBSERVER_H

#include <string>
#include"subject.h"

class Subject;

// 抽象观察者,为所有具体观察者定义一个更新接口,当得到主题的通知时,更新自己。
class Observer {
public:
    Observer();
    ~Observer();
    virtual void update(Subject* sub) = 0;  // 纯虚函数,只定义接口,并不实现,不能实例化对象。
};

// 具体观察者,实现抽象观察者的更新接口,以便使本身状态与主题状态相协调。
class ConcreteObserverA : public Observer {
private:
    std::string state;
public:
    ConcreteObserverA();
    ~ConcreteObserverA();
    // 派生类定义虚函数,覆盖基类纯虚函数。
    virtual void update(Subject* sub);      // 参数为抽象主题,这样做减少了观察者与具体主题的耦合。
};

// 具体观察者,实现抽象观察者的更新接口,以便使本身状态与主题状态相协调。
class ConcreteObserverB : public Observer {
private:
    std::string state;
public:
    ConcreteObserverB();
    ~ConcreteObserverB();
    // 派生类定义虚函数,覆盖基类纯虚函数。
    virtual void update(Subject* sub);      // 参数为抽象主题,这样做减少了观察者与具体主题的耦合。
};

#endif // _OBSERVER_H
抽象观察者类、具体观察者类实现:

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:observer.cpp
@datetime:2016.09.10
@author:HJS
@e-mail:jingshuang_hu@163.com
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include "observer.h"
#include <iostream>

using namespace std;

Observer::Observer() {

}

Observer::~Observer() {

}

ConcreteObserverA::ConcreteObserverA() {

}

ConcreteObserverA::~ConcreteObserverA() {

}

// 观察者更新自己的一系列动作
void ConcreteObserverA::update(Subject* sub) {
    state = sub->getState();
    cout << "ConcreteObserverA 收到 " + state << endl;
    // ...
}

ConcreteObserverB::ConcreteObserverB() {

}

ConcreteObserverB::~ConcreteObserverB() {

}

// 观察者更新自己的一系列动作
void ConcreteObserverB::update(Subject* sub) {
    state = sub->getState();
    cout << "ConcreteObserverB 收到 " + state << endl;
    // ...
}
抽象主题类、具体主题类定义:

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:subject.h
@datetime:2016.09.10
@author:HJS
@e-mail:jingshuang_hu@163.com
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#ifndef _SUBJECT_H
#define _SUBJECT_H

#include <iostream>
#include <string>
#include <list>

#include "observer.h"
class Observer;

// 抽象主题,将所有观察者保存在一个聚集中,可以有任何数量的观察者,并且提供一个接口,可以删除和增加观察者。
class Subject {
private:
    std::string state;
    std::list<Observer*> lst;
public:
    Subject();
    ~Subject();

    virtual void attach(Observer* obj);     // 参数为抽象观察者类,这样做减少了主题与具体观察者类的耦合。
    virtual void detach(Observer* obj);
    virtual void notify();

    virtual void setState(std::string state);
    virtual std::string getState();
};

// 具体主题,当具体主题内部发生变化时,给所有登记过的观察者发送通知。
class ConcreteSubjectA : public Subject {
public:
    ConcreteSubjectA();
    ~ConcreteSubjectA();
};

// 具体主题,当具体主题内部发生变化时,给所有登记过的观察者发送通知。
class ConcreteSubjectB : public Subject {
public:
    ConcreteSubjectB();
    ~ConcreteSubjectB();
};

#endif // _SUBJECT_H
抽象主题类、具体主题类实现:
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:subject.cpp
@datetime:2016.09.10
@author:HJS
@e-mail:jingshuang_hu@163.com
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include "subject.h"
#include <iostream>

using namespace std;

Subject::Subject() {

}

Subject::~Subject() {

}

void Subject::attach(Observer* obj) {
    lst.push_back(obj);
}

void Subject::detach(Observer* obj) {
    list<Observer*>::iterator it = find(lst.begin(), lst.end(), obj);
    if ( it != lst.end() ) {
        lst.erase(it);
    }
    cout << "Detach an Observer." << endl;
}

void Subject::notify() {
    list<Observer*>::iterator it = lst.begin();
    for (; it != lst.end(); it++) {
        (*it)->update(this);
    }
}

void Subject::setState(string state) {
    this->state = state;
}

string Subject::getState() {
    return state;
}

ConcreteSubjectA::ConcreteSubjectA() {

}

ConcreteSubjectA::~ConcreteSubjectA() {

}

ConcreteSubjectB::ConcreteSubjectB() {

}

ConcreteSubjectB::~ConcreteSubjectB() {

}
主函数入口:

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:main.cpp
@datetime:2016.09.10
@author:HJS
@e-mail:jingshuang_hu@163.com
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include <iostream>
#include "observer.h"
#include "subject.h"

using namespace std;

// 1.主题与观察者都在抽象层进行依赖,而不涉及具体层(即:具体主题与具体观察者的关联),这样降低了耦合程度。
// 2.由1知,主题发出通知时,并不需要知道它的观察者是谁,且观察者之间都不知道对方的存在(观察者之间是独立的)。
int main() {
    Observer* p1 = new ConcreteObserverA();         // 实例化 具体观察者A
    Observer* p2 = new ConcreteObserverB();         // 实例化 具体观察者B

    Subject* sub1 = new ConcreteSubjectA();         // 实例化 具体主题A
    sub1->attach(p1);                               // 观察者A 登记
    sub1->attach(p2);                               // 观察者B 登记

    sub1->setState("online");                       // 主题A状态发生变化

    sub1->notify();                                 // 通知登记过的观察者

    Subject* sub2 = new ConcreteSubjectB();         // 实例化 具体主题B
    sub2->attach(p1);                               // 观察者A 登记
    sub2->attach(p2);                               // 观察者B 登记

    sub2->setState("offline");                      // 主题B状态发生变化

    sub2->notify();                                 // 通知登记过的观察者

    system("pause");
    return 0;
}
就这样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值