行为型模式-观察者(observer)

观察者

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新.

实例

main.cc:

#include <windows.h>
#include "runner_people.h"
#include "volunteer_people.h"
#include "sponsor_subject.h"

/*
design_pattern:"observer"
Marathon, the organizers need to send some information to the participants 
according to the weather conditions, if it rains, athletes and volunteers will 
wear a disposable raincoat, if it does not rain, we will as usual
*/
int main(){
    SponsorSubject *sponsor = new SponsorSubject();
    RunnerPeople *zhang_san = new RunnerPeople(sponsor,"zhang san");
    RunnerPeople *li_si = new RunnerPeople(sponsor,"li si");
    VolunteerPeople *volunteer = new VolunteerPeople(sponsor,"wang wu");

    sponsor->Add(zhang_san);
    sponsor->Add(li_si);
    sponsor->Add(volunteer);

    sponsor->Notify("rainy day,putting on a raincoat!");
    /*
    sponsor->Notify("sunny day,as usual!");
    */

    //clear
    delete sponsor;
    delete zhang_san;
    delete li_si;
    delete volunteer;
    system("Pause");
    return 0;
}

Subject:

//subject.h
#ifndef HELENDP_SOURCE_SUBJECT_H_
#define HELENDP_SOURCE_SUBJECT_H_
#include "people.h"
#include <list>

class Subject{
public:
    Subject();
    ~Subject();
    virtual void Add(People *people) = 0;
    virtual void Remove(People *people) = 0;
    virtual void Notify(string message) = 0;
protected:  
    list<People *> people_list_;
};
#endif


//subject.cc
#include "subject.h"

Subject::Subject(){

}

Subject::~Subject(){

}

SponsorSubject:

//sponsor_subject.h
#ifndef HELENDP_SOURCE_SPONSOR_SUBJECT_H_
#define HELENDP_SOURCE_SPONSOR_SUBJECT_H_
#include "people.h"
#include <string>
#include <list>
#include "subject.h"
using namespace std;

class SponsorSubject : public Subject{
public:
    SponsorSubject();
    ~SponsorSubject();
    void Add(People *people);
    void Remove(People *people);
    void Notify(string message);
    string notify_message_;
};
#endif


//sponsor_subject.cc
#include "sponsor_subject.h"

SponsorSubject::SponsorSubject(){

}

SponsorSubject::~SponsorSubject(){

}

void SponsorSubject::Add(People * people){
    people_list_.push_back(people);
}

void SponsorSubject::Remove(People * people){
    people_list_.remove(people);
}

void SponsorSubject::Notify(string message){
    notify_message_ = message;
    for(list<People *>::iterator iterator = people_list_.begin();
    iterator != people_list_.end();++iterator){
        (*iterator)->Update();
    }
}

People:

//people.h
#ifndef HELENDP_SOURCE_PEOPLE_H_
#define HELENDP_SOURCE_PEOPLE_H_
#include <string>
using namespace std;

class People{
public:
    People(string name);
    ~People();
    virtual void Update() = 0;
    void SetName(string name);
    string GetName();
private:
    string name_;
};
#endif


//people.cc
#include "people.h"

People::People(string name){
    name_ = name;
}

People::~People(){

}

void People::SetName(string name){
    name_ = name;
}

string People::GetName(){
    return name_;
}

RunnerPeople:

//runner_people.h
#ifndef HELENDP_SOURCE_RUNNER_PEOPLE_H_
#define HELENDP_SOURCE_RUNNER_PEOPLE_H_
#include "people.h"
#include "sponsor_subject.h"

class RunnerPeople : public People{
public:
    RunnerPeople(SponsorSubject *sponsor_subject,string name);
    ~RunnerPeople();
    void Update();
private:
    SponsorSubject *sponsor_subject_;
};
#endif


//runner_people.cc
#include "runner_people.h"
#include <iostream>
using namespace std;

RunnerPeople::RunnerPeople(SponsorSubject *sponsor_subject,string name)
    :People(name){
    sponsor_subject_ = sponsor_subject;
}

RunnerPeople::~RunnerPeople(){

}

void RunnerPeople::Update(){
    cout << "runner(" << this->GetName() << ") get message:" << sponsor_subject_->notify_message_<< endl;
}

VolunteerPeople:

//volunteer_people.h
#ifndef HELENDP_SOURCE_VOLUNTEER_PEOPLE_H_
#define HELENDP_SOURCE_VOLUNTEER_PEOPLE_H_
#include "people.h"
#include "sponsor_subject.h"


class VolunteerPeople : public People{
public:
    VolunteerPeople(SponsorSubject *sponsor_subject,string name);
    ~VolunteerPeople();
    void Update();
private:
    SponsorSubject *sponsor_subject_;
};
#endif


//volunteer_people.cc
#include "volunteer_people.h"
#include <iostream>
using namespace std;

VolunteerPeople::VolunteerPeople(SponsorSubject *sponsor_subject,string name)
    :People(name){
    sponsor_subject_ = sponsor_subject;
}

VolunteerPeople::~VolunteerPeople(){

}

void VolunteerPeople::Update(){
    cout << "volunteer(" << this->GetName() << ") get message:" << sponsor_subject_->notify_message_ << endl;
}

代码和UML图(EA)工程文件,最后会整理打包上传.

UML类图

这里写图片描述

结构

  • Subject(Subject):目标类,观察者所关注的目标.
  • ConcreteSubject(SponsorSubject):具体目标类.
  • Observer(People):观察者抽象类.
  • ConcreteObserver(RunnerPeople,VolunteerPeople):具体观察者类.

优点

  • 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色.
  • 观察者模式在观察目标和观察者之间建立一个抽象的耦合.
  • 观察者模式支持广播通信.
  • 观察者模式符合“开闭原则”的要求.

缺点

  • 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间.
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃.
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值