实现解耦:观察者模式的应用

观察者模式,开始接触开发的时候,就有使用到。某个值的变化,引起其他值也发生变化。这个是使用比较多的设计模式。掌握该设计模式,对开发而言是比较重要得。今天,就对该设计模式进行分析

什么是观察者模式

观察者模式:定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

观察者模式的优点

  1. 降低耦合性:观察者模式允许主题和观察者之间解耦,因为它们之间只存在抽象的观察者接口,而不存在直接的依赖关系。
  2. 增加可扩展性:观察者模式使得添加新的观察者变得容易,只需要实现观察者接口并注册到主题即可。
  3. 提高系统灵活性:观察者模式使得主题和观察者之间的通信变得灵活,可以根据需要实现推送或拉取信息的功能。

模式UML

观察者模式包含如下角色:

  • Subject: 目标
  • ConcreteSubject: 具体目标
  • Observer: 观察者
  • ConcreteObserver: 具体观察者

从UML图中,可以看出,在抽象类Subject中,通过attach将观察者加入objList中。ConcreteSubject对象中,在被观察的对象变更时,通知objList中的观察者。以达到对目标变化的监听。核心在于objList的观察者存储,与ConcreteSubject属性变化的通知。

javascript 实现

JAVASCRIPT 复制代码
let Subject = function () {
        this.objlist = []
    }

    Subject.prototype.attach = function (pObeserver) {
        this.objlist.push(pObeserver);
    }

    Subject.prototype.detach = function () {
        throw (new Error("子类必须实现此方法"))
    }

    Subject.prototype.notify = function () {
        throw (new Error("子类必须实现此方法"))
    }

    let ConcreteSubject = function () {
        Subject.apply(this, arguments)
    }
    ConcreteSubject.prototype = Object.create(Subject.prototype)
    ConcreteSubject.prototype.constructor = ConcreteSubject

    ConcreteSubject.prototype.attach = function (pObeserver) {
        this.objlist.push(pObeserver);
    }

    Subject.prototype.detach = function (pObeserver) {

        for (let index = 0; index < this.objlist.length; index++) {
            const element = this.objlist[index];
            if (element == pObeserver) {
                this.objlist.splice(index, 1)
                return
            }
        }

    }

    Subject.prototype.notify = function () {
        this.objlist.forEach(obj => {
            obj.update(this)
        });
    }

    ConcreteSubject.prototype.setState = function (state) {
        this.state = state;
        this.notify()
    }

    ConcreteSubject.prototype.getState = function () {
        return this.state
    }


    let Obsever = function () {}
    Obsever.prototype.update = function () {
        throw (new Error("子类必须实现此方法"))
    }

    let ConcreteObsever = function (name) {
        this.name = name
        this.obeserverState = ""
    }
    ConcreteObsever.prototype = Object.create(Obsever.prototype)
    ConcreteObsever.prototype.constructor = ConcreteObsever
    ConcreteObsever.prototype.update = function (sub) {
        this.obeserverState = sub.getState()

        console.log("收到" + this.name + "状态更新为:" + this.obeserverState);
    }

    let _ConcreteSubject = new ConcreteSubject();
    let _ConcreteObseverA = new ConcreteObsever("观察者A");
    let _ConcreteObseverB = new ConcreteObsever("观察者B");

    _ConcreteSubject.attach(_ConcreteObseverA)
    _ConcreteSubject.attach(_ConcreteObseverB)

    _ConcreteSubject.setState(1)
    // 收到观察者A状态更新为:1
    // 收到观察者B状态更新为:1

    _ConcreteSubject.detach(_ConcreteObseverB)
    _ConcreteSubject.setState(2)
    // 收到观察者A状态更新为:2
相关推荐
崎岖Qiu17 分钟前
【设计模式笔记06】:单一职责原则
java·笔记·设计模式·单一职责原则
Yeniden22 分钟前
【设计模式】适配器模式大白话讲解!
设计模式·适配器模式
孤狼warrior1 小时前
爬虫进阶 JS逆向基础超详细,解锁加密数据
javascript·爬虫
前端炒粉1 小时前
18.矩阵置零(原地算法)
javascript·线性代数·算法·矩阵
listhi5201 小时前
利用React Hooks简化状态管理
前端·javascript·react.js
华仔啊2 小时前
这个Vue3旋转菜单组件让项目颜值提升200%!支持多种主题,拿来即用
前端·javascript·css
CsharpDev-奶豆哥3 小时前
JavaScript性能优化实战大纲
开发语言·javascript·性能优化
金色熊族5 小时前
装饰器模式(c++版)
开发语言·c++·设计模式·装饰器模式
yume_sibai6 小时前
TS 常用内置方法
前端·javascript·typescript
新知图书6 小时前
ArkTS语言、基本组成与数据类型
前端·javascript·typescript