设计模式 ------ 观察者模式(Observer/Event)

观察者模式

在软件架构中,我们需要对某些对象建立一种“通知依赖的关系”:一个对象的状态发生改变,所有的依赖对象都需要得到通知。

如果这样的关系过于紧密,将使得软件不能很好的抵御变化;使用观察者模式,可以将这种依赖关系弱化,形成一种稳定的依赖关系,从而实现软件体系结构的松耦合。

使用师生关系进行举例策略模式的类图关系如下:

teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <list>
#include <memory>

class Student;

using Student_ptr = std::shared_ptr<Student>;
//
/// \brief The Teacher class
/// 观察者模式
/// 在软件架构中,我们需要对某些对象建立一种“通知依赖的关系”:
/// 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都需要得到通知。
/// 如果这样的关系过于紧密,将使软件不能很好的抵御变化;使用观察者模式,可以将这种
/// 依赖关系弱化,形成一种稳定的依赖关系,从而实现 软件体系结构的松耦合。
/// Teacher作为目标对象的基类,可以根据不同的子类进行扩展目标对象;而Student作为
/// 观察者对象的基类,也可以根据不同的子类进行观察者的扩展。
//
class Teacher
{
public:
    Teacher();
    virtual ~Teacher();

    virtual void takeAClass() = 0;

    void attach(Student_ptr student);//添加观察者
    void detach(Student_ptr student);

protected:
    void notify();//通知所有的观察者

private:
    std::list<Student_ptr > m_list;
};


class TeacherA : public Teacher
{
public:
    TeacherA();
    virtual ~TeacherA();
    virtual void takeAClass();//上课(在这里边进行通知)
};


class TeacherB : public Teacher
{
public:
    TeacherB();
    virtual ~TeacherB();
    virtual void takeAClass();//上课(在这里边进行通知)
};

#endif // TEACHER_H

teacher.cpp

#include "teacher.h"
#include "student.h"
#include <iostream>

Teacher::Teacher() {
    std::cout << "Teacher::Teacher" << std::endl;
}
Teacher::~Teacher() {
    std::cout << "Teacher::~Teacher" << std::endl;
    m_list.clear();
}
void Teacher::attach(Student_ptr student) {
    if(student) m_list.push_back(student);
}
void Teacher::detach(Student_ptr student) {
    if(student) {
        m_list.remove(student);
    }
}
void Teacher::notify() {
    for(Student_ptr student : m_list) {
        if(student) student->doSomething();
    }
}
///
TeacherA::TeacherA()
    : Teacher() {
    std::cout << "TeacherA::TeacherA" << std::endl;
}
TeacherA::~TeacherA() {
    std::cout << "TeacherA::~TeacherA" << std::endl;
}
void TeacherA::takeAClass() {
    std::cout << "TeacherA::takeAClass" << std::endl;
    notify();
}
///
TeacherB::TeacherB()
    : Teacher() {
    std::cout << "TeacherB::TeacherB" << std::endl;
}
TeacherB::~TeacherB() {
    std::cout << "TeacherB::~TeacherB" << std::endl;
}
void TeacherB::takeAClass() {
    std::cout << "TeacherB::takeAClass" << std::endl;
    notify();
}
student.h
#ifndef STUDENT_H
#define STUDENT_H

class Student
{
public:
    Student();
    virtual ~Student();
    virtual void doSomething();
};
//
class StudentA : public Student
{
public:
    StudentA();
    virtual ~StudentA();
    virtual void doSomething();
};
//
class StudentB : public Student
{
public:
    StudentB();
    virtual ~StudentB();
    virtual void doSomething();
};
#endif // STUDENT_H
student.cpp
#include "student.h"
#include <iostream>

Student::Student() {
    std::cout << "Student::Student" << std::endl;
}
Student::~Student() {
    std::cout << "Student::~Student" << std::endl;
}
void Student::doSomething() {
    std::cout << "Student::doSomething" << std::endl;
}
//
StudentA::StudentA()
    : Student() {
    std::cout << "StudentA::StudentA" << std::endl;
}
StudentA::~StudentA() {
    std::cout << "StudentA::~StudentA" << std::endl;
}
void StudentA::doSomething() {
    std::cout << "StudentA::doSomething" << std::endl;
}
/
StudentB::StudentB()
    : Student() {
    std::cout << "StudentB::StudentB" << std::endl;
}
StudentB::~StudentB() {
    std::cout << "StudentB::~StudentB" << std::endl;
}
void StudentB::doSomething() {
    std::cout << "StudentB::doSomething" << std::endl;
}

main.cpp

#include <QCoreApplication>
#include "teacher.h"
#include "student.h"
#include <memory>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    std::cout << "**************************************************" << std::endl;
    {
        /
        /假设目前需求只有StudentA类型的任务
        std::shared_ptr<Student> studentA1 = std::make_shared<StudentA>();
        std::shared_ptr<Student> studentA2 = std::make_shared<StudentA>();
        std::shared_ptr<Teacher> teacherA = std::make_shared<TeacherA>();
        teacherA->attach(studentA1);
        teacherA->attach(studentA2);
        teacherA->takeAClass();
    }
    std::cout << "**************************************************" << std::endl;
    {
        /
        /新增需求StudentB类型的任务
        std::shared_ptr<Student> studentB1 = std::make_shared<StudentB>();
        std::shared_ptr<Student> studentB2 = std::make_shared<StudentB>();
        std::shared_ptr<Teacher> teacherA1 = std::make_shared<TeacherA>();
        teacherA1->attach(studentB1);
        teacherA1->attach(studentB2);
        teacherA1->takeAClass();
    }
    std::cout << "**************************************************" << std::endl;
    {
        /
        /新增需求StudentA、StudentB类型的任务等
        std::shared_ptr<Student> studentA11 = std::make_shared<StudentA>();
        std::shared_ptr<Student> studentB11 = std::make_shared<StudentB>();
        std::shared_ptr<Teacher> teacherB = std::make_shared<TeacherB>();
        teacherB->attach(studentA11);
        teacherB->attach(studentB11);
        teacherB->takeAClass();
    }
    std::cout << "**************************************************" << std::endl;
    return a.exec();
}

将观察者和被观察者分别抽象后,能够适应更多的扩展。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值