观察者模式的实现(c++)

该文章已生成可运行项目,

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在事件驱动系统中非常常见,例如用户界面组件、消息传递系统等。

观察者模式的基本概念

  1. 主题(Subject):主题是被观察的对象,它维护了一个观察者列表,并提供添加、删除和通知观察者的方法。
  2. 观察者(Observer):观察者是依赖于主题的对象,当主题的状态发生变化时,观察者会收到通知并更新自己的状态。

观察者模式的实现

1. 定义主题接口

主题接口定义了添加、删除和通知观察者的方法。

#include <iostream>
#include <vector>
#include <algorithm>

// 观察者接口
class Observer {
public:
    virtual void update() = 0;
    virtual ~Observer() {}
};

// 主题接口
class Subject {
private:
    std::vector<Observer*> observers;
public:
    void attach(Observer* observer) {
        observers.push_back(observer);
    }

    void detach(Observer* observer) {
        observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
    }

    void notify() {
        for (Observer* observer : observers) {
            observer->update();
        }
    }
};
2. 定义具体主题

具体主题是主题接口的具体实现,它维护了一个观察者列表,并在状态发生变化时通知所有观察者。

class ConcreteSubject : public Subject {
private:
    int state;
public:
    ConcreteSubject(int state) : state(state) {}

    void setState(int state) {
        this->state = state;
        notify();  // 状态变化时通知所有观察者
    }

    int getState() const {
        return state;
    }
};
3. 定义具体观察者

具体观察者是观察者接口的具体实现,它在收到通知时更新自己的状态。

class ConcreteObserverA : public Observer {
private:
    ConcreteSubject* subject;
public:
    ConcreteObserverA(ConcreteSubject* subject) : subject(subject) {}

    void update() override {
        std::cout << "ConcreteObserverA received update, new state: " << subject->getState() << std::endl;
    }
};

class ConcreteObserverB : public Observer {
private:
    ConcreteSubject* subject;
public:
    ConcreteObserverB(ConcreteSubject* subject) : subject(subject) {}

    void update() override {
        std::cout << "ConcreteObserverB received update, new state: " << subject->getState() << std::endl;
    }
};
4. 客户端代码

客户端代码创建具体主题和具体观察者对象,并将观察者注册到主题中。当主题的状态发生变化时,所有观察者都会收到通知并更新自己的状态。

int main() {
    ConcreteSubject subject(0);

    ConcreteObserverA observerA(&subject);
    ConcreteObserverB observerB(&subject);

    subject.attach(&observerA);
    subject.attach(&observerB);

    // 改变主题的状态
    subject.setState(10);

    // 移除一个观察者
    subject.detach(&observerA);

    // 再次改变主题的状态
    subject.setState(20);

    return 0;
}

详细解释

  1. 主题接口 Subject

    class Subject {
    private:
        std::vector<Observer*> observers;
    public:
        void attach(Observer* observer) {
            observers.push_back(observer);
        }
    
        void detach(Observer* observer) {
            observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
        }
    
        void notify() {
            for (Observer* observer : observers) {
                observer->update();
            }
        }
    };
    • attach 方法用于添加观察者。
    • detach 方法用于移除观察者。
    • notify 方法用于通知所有观察者。
  2. 具体主题 ConcreteSubject

    class ConcreteSubject : public Subject {
    private:
        int state;
    public:
        ConcreteSubject(int state) : state(state) {}
    
        void setState(int state) {
            this->state = state;
            notify();  // 状态变化时通知所有观察者
        }
    
        int getState() const {
            return state;
        }
    };
    • state 是主题的状态。
    • setState 方法用于设置主题的状态,并在状态变化时调用 notify 方法通知所有观察者。
    • getState 方法用于获取主题的状态。
  3. 观察者接口 Observer

    class Observer {
    public:
        virtual void update() = 0;
        virtual ~Observer() {}
    };
    • update 方法是观察者接收到通知时需要执行的方法。
  4. 具体观察者 ConcreteObserverA 和 ConcreteObserverB

    class ConcreteObserverA : public Observer {
    private:
        ConcreteSubject* subject;
    public:
        ConcreteObserverA(ConcreteSubject* subject) : subject(subject) {}
    
        void update() override {
            std::cout << "ConcreteObserverA received update, new state: " << subject->getState() << std::endl;
        }
    };
    
    class ConcreteObserverB : public Observer {
    private:
        ConcreteSubject* subject;
    public:
        ConcreteObserverB(ConcreteSubject* subject) : subject(subject) {}
    
        void update() override {
            std::cout << "ConcreteObserverB received update, new state: " << subject->getState() << std::endl;
        }
    };
    • ConcreteObserverA 和 ConcreteObserverB 是观察者接口的具体实现。
    • update 方法在接收到通知时更新自己的状态,并输出当前主题的状态。
  5. 客户端代码 main

    int main() {
        ConcreteSubject subject(0);
    
        ConcreteObserverA observerA(&subject);
        ConcreteObserverB observerB(&subject);
    
        subject.attach(&observerA);
        subject.attach(&observerB);
    
        // 改变主题的状态
        subject.setState(10);
    
        // 移除一个观察者
        subject.detach(&observerA);
    
        // 再次改变主题的状态
        subject.setState(20);
    
        return 0;
    }
    • 创建一个具体主题 subject,初始状态为 0。
    • 创建两个具体观察者 observerA 和 observerB,并将它们注册到 subject 中。
    • 改变 subject 的状态为 10,所有观察者都会收到通知并更新自己的状态。
    • 移除 observerA
    • 再次改变 subject 的状态为 20,只有 observerB 会收到通知并更新自己的状态。
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值