设计模式之观察者模式(Observer)

Observer(观察者模式)属于行为模式

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

我们可以拿项目的npm依赖举例子:npm包与项目是一对多的关系(一个npm包被多个项目使用),当npm包发布新版本时,如果所有依赖于它的项目都能得到通知,并自动更新这个包的版本号,那么就解决了包版本更新的问题,这就是观察者模式要解决的基本问题。

举几个更生动的例子

设计模式需要在日常工作里用起来,下面再结合几个例子加深一下我们的理解

对象与视图双向绑定

观察者模式在最初提出的时候,就举了数据与 UI 相互绑定的例子。即同一份数据可以同时渲染为表格与柱状图,那么当操作表格更新数据时,如何让柱状图的数据也刷新?从这个场景引出了对观察者模式的定义,即 “数据” 与 “UI” 是一对多的关系,我们需要一种设计模式实现当 “数据” 变化时,所有依赖于它的 “UI” 都得到通知并自动更新。

拍卖

拍卖由一个拍卖员与多为拍卖者组成。拍卖时,由 A 同学喊出的竞价(我出 100)就是观察者向目标发出的 setState 同时,此时拍卖员喊出(有人出价 100,还有更高的吗?)就是一个 notify 通知行为,拍卖员通知了现场竞价全员,刷新了他们对当前最高价的信息。

聊天室

聊天室由一个中央服务器与多个客户端组成。客户端发送消息后,就是向中央服务器发送了 setState 更新请求,此时中央服务器通知所有处于同一聊天室的客户端,更新他们的信息,从而完成一次消息的发送。

这样通过几个例子了解之后是不是对观察者模式有了更深的见解?

接下来我们将用js代码体现一下观察者模式

代码

// 目标,管理所有观察者
class Target {
    constructor() {
        // 状态
        this.state = null
        // 观察者数组
        this.observerArr = []
    }
    // 通知所有观察者
    notify() {
        this.observerArr.forEach(item => {
        item.update()
    })
    }
    // 新增观察者
    addObserver(observer) {
        this.observerArr.push(observer)
    }
    // 更新状态
    setState(state) {
        this.state = state
        this.notify()
    }
    // 读取状态
    getState() {
        return this.state
    }
}
// 观察者
class Observer {
    // 维护目标
    constructor(target) {
        this.target = target
        this.target.addObserver(this)
    }
    // 更新
    update(){
        // 渲染表格 或者 渲染图表
        console.log('渲染'+this.target.getState())
    }
}

// 客户端调用,目标创建
const target = new Target()
// 创建观察者
const observer1 = new Observer(target)
const observer2 = new Observer(target)
// 更新状态
target.setState('数据')
// 会通知观察者数据更新

总结

观察者模式是非常常用的设计模式,它描述了对象一对多依赖关系下,如何通知并更新的机制,这种机制可以用在前端的 UI 与数据映射、后端的请求与控制器映射,平台间的消息通知等大部分场景,无论现实还是程序中,存在依赖且需要通知的场景非常普遍

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常用的设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,它的所有观察者都会收到通知并更新自己的状态。 在C++中,观察者模式通常由一个抽象主题类和多个具体观察者类组成。抽象主题类中定义了添加、删除和通知观察者的接口,具体观察者类实现了更新自身状态的方法。 以下是一个简单的观察者模式示例: ```c++ #include <iostream> #include <vector> class Observer { public: virtual void update() = 0; }; class Subject { public: void attach(Observer* observer) { observers.push_back(observer); } void detach(Observer* observer) { for (auto it = observers.begin(); it != observers.end(); ++it) { if (*it == observer) { observers.erase(it); break; } } } void notify() { for (auto observer : observers) { observer->update(); } } private: std::vector<Observer*> observers; }; class ConcreteObserver1 : public Observer { public: void update() override { std::cout << "ConcreteObserver1 updated" << std::endl; } }; class ConcreteObserver2 : public Observer { public: void update() override { std::cout << "ConcreteObserver2 updated" << std::endl; } }; int main() { Subject subject; ConcreteObserver1 observer1; ConcreteObserver2 observer2; subject.attach(&observer1); subject.attach(&observer2); subject.notify(); subject.detach(&observer1); subject.notify(); return 0; } ``` 在上面的示例中,Subject类是抽象主题类,Observer类是抽象观察者类,ConcreteObserver1和ConcreteObserver2是具体观察者类。当Subject对象状态发生变化时,它会通知所有观察者更新自己的状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值