JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式

news2025/1/21 18:42:57

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒Three.js 🍖JS版算法
🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

设计模式

内容参考链接
JavaScript设计模式(一)构造器模式、原型模式、类模式
JavaScript设计模式(二)简单工厂模式、抽象工厂模式、建造者模式
JavaScript设计模式(三)单例模式、装饰器模式、适配器模式

文章目录

  • 设计模式
    • ✨✨前言
    • 一、发布订阅模式
    • 二、桥接模式
    • 三、组合模式
    • 🎉🎉本篇小结


✨✨前言

大家好,这里是前端杂货铺。

上一节,我们学习了策略模式、代理模式、观察者模式。这一节,我们学习发布订阅模式、桥接模式和组合模式…

一、发布订阅模式

观察者和目标要互相知道,发布者和订阅者 不用相互知道,通过第三方实现调度,属于 经过解耦合的 观察者模式。

我们定义 PubSub 类(发布订阅),里面的 message 对象用于存放要订阅的信息。

subscribe 方法期待两个参数(type 和 cb),type 表示要订阅的类型,cb 表示订阅的详细信息,直接把 cb 赋值给 type 即可。

publish 方法也期待两个参数(type 和 data),如果发布的时候没有该类型,则直接 return,否则发布出该类型。

unsubscribe 同 subscribe 一样,期待两个参数,用于取消订阅。

class PubSub {
    message = {};
    // 发布
    publish(type, data) {
        // 发布的时候没有该类型,直接 return
        if (!this.message[type]) return;
        this.message[type].forEach(item => item(data));
    }
    // 订阅
    subscribe(type, cb) {
        this.message[type] = [cb];
    }
    // 取消订阅
    unsubscribe(type, cb) {
        // 取消订阅的时候如果没有该类型,直接 return
        if (!this.message[type]) return;

        if (!cb) {
            this.message[type] && (this.message[type].length = 0);
        } else {
            this.message[type] = this.message[type].filter(item => item !== cb);
        }
    }
}

// 创建 pubsub 实例
const pubsub = new PubSub();

function milk(data) {
    console.log('milk', data);
}

function apple(data) {
    console.log('apple', data);
}

function chicken(data) {
    console.log('chicken', data);
}

// 订阅 牛奶、苹果、大盘鸡
pubsub.subscribe('milk', milk);
pubsub.subscribe('apple', apple);
pubsub.subscribe('chicken', chicken);

// 发布 牛奶、苹果、大盘鸡
pubsub.publish('milk', '牛奶');
pubsub.publish('apple', '苹果');
pubsub.publish('chicken', '大盘鸡');

console.log('分-----割-----线')

// 取消对大盘鸡的订阅
pubsub.unsubscribe('chicken');

// 发布 牛奶、苹果、大盘鸡(大盘鸡不会被发布,因为被取消订阅了)
pubsub.publish('milk', '牛奶');
pubsub.publish('apple', '苹果');
pubsub.publish('chicken', '大盘鸡');

在这里插入图片描述


二、桥接模式

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

使用场景:一个类存在两个或多个独立变化的维度,且这两个维度都需要进行扩展。

优点:把抽象与实现隔开,有助于独立地管理各组成部分。

缺点:每使用一个桥接元素都要增加一次函数调用,这对程序的性能会有一些负面影响,还提高了系统的复杂程度。

举个栗子:汽车厂商会把同一型号的发动机放到多款车型上使用。拿奥迪为例,假如它有 V6、V8 两款发动机,那么这两款发动机会装载到奥迪轿车或奥迪SUV两种车型中。

在这里插入图片描述

// 奥迪轿车(车型一)
class Aodi1 {
    constructor(engine) {
        this.engine = engine;
    }
}

// 轿车平台
Aodi1.prototype.platform = function() {
    console.log('aodi1 轿车平台');
}

// 加载轿车发动机
Aodi1.prototype.loadEngine = function() {
    this.engine.run();
}

// 奥迪SUV(车型二)
class Aodi2 {
    constructor(engine) {
        this.engine = engine;
    }
}

// SUV平台
Aodi2.prototype.platform = function() {
    console.log('aodi2 SUV平台');
}

// 加载SUV发动机
Aodi2.prototype.loadEngine = function() {
    this.engine.run();
}

// V6 发动机
function V6() {
    this.run = () => {
        console.log('v6发动机');
    }
}

// V8 发动机
function V8() {
    this.run = () => {
        console.log('v8发动机');
    }
}

// 搭载 V6 发动机的轿车
let car1 = new Aodi1(new V6());
// 搭载 V8 发动机的轿车
let car2 = new Aodi1(new V8());
// 搭载 V8 发动机的SUV
let suv1 = new Aodi2(new V8());

car1.platform();
car1.loadEngine();

car2.platform();
car2.loadEngine();

suv1.platform();
suv1.loadEngine();

在这里插入图片描述


三、组合模式

组合模式在对象间形成 树形结构
组合模式中基本对象和组合对象被一致对待;
无须关系对象有多少层,调用时只需在根部进行调用;

比如我们扫描文件夹和文件夹里面的文件,它是一种树形结构,我们从根文件夹出发,扫描二级文件夹,再扫描二级文件夹里的文件…,类似于如下结构:

在这里插入图片描述

// 文件夹
const Folder = function(folder) {
    this.folder = folder;
    this.list = [];
}

// 添加文件夹
Folder.prototype.add = function(res) {
    this.list.push(res);
}

// 扫描文件夹
Folder.prototype.scan = function() {
    console.log('扫描文件夹', this.folder);
    for (let i = 0; i < this.list.length; i++) {
        this.list[i].scan();
    }
}

// 文件
const File = function(file) {
    this.file = file;
}

// 扫描文件
File.prototype.scan = function() {
    console.log('开始扫描文件', this.file);
}

// 根文件夹
let rootFolder = new Folder("root");

// 子文件夹
let htmlFolder = new Folder("html");
let cssFolder = new Folder("css");
let jsFolder = new Folder("js");

// 文件
let html4 = new File("html4");
let html5 = new File("html5");
let css2 = new File("css2");
let css3 = new File("css3");
let es5 = new File("es5");
let es6 = new File("es6");

// 添加文件夹
rootFolder.add(htmlFolder);
rootFolder.add(cssFolder);
rootFolder.add(jsFolder);

// 添加文件
htmlFolder.add(html4);
htmlFolder.add(html5);
cssFolder.add(css2);
cssFolder.add(css3);
jsFolder.add(es5);
jsFolder.add(es6);

// 从根扫描
rootFolder.scan();

在这里插入图片描述


🎉🎉本篇小结

本文我们了解了发布订阅模式、桥接模式、组合模式。

发布订阅模式 的发布者和订阅者不用相互知道,通过第三方实现调度,属于经过解耦合的观察者模式。

桥接模式是一种 结构型设计模式,用于把抽象化与实现化解耦,使得二者可以独立变化。

组合模式 又叫部分整体模式,是一种 结构型设计模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. 百度百科 · 软件设计模式(设计模式)
  2. 菜鸟教程 · 设计模式
  3. JavaScript设计模式 【作者:千锋教育】

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/996707.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rokid Jungle--Max pro

介绍和功能开发 YodaOS-Master操作系统&#xff1a;以交换计算为核心&#xff0c;实现单目SLAM空间交互&#xff0c;具有高精度、实时性和稳定性。发布UXR2.0SDK&#xff0c;为构建空间内容提供丰富的开发套件 多模态交互 算法原子化 多种开发工具协同 多生态支持 骁龙XR2…

无swing,高级javaSE毕业之贪吃蛇游戏(含模块构建,多线程监听服务),已录制视频

JavaSE&#xff0c;无框架实现贪吃蛇 B站已发视频&#xff1a;无swing&#xff0c;纯JavaSE贪吃蛇游戏设计构建 文章目录 JavaSE&#xff0c;无框架实现贪吃蛇1.整体思考2.可能的难点思考2.1 如何表示游戏界面2.2 如何渲染游戏界面2.3 如何让游戏动起来2.4 蛇如何移动 3.流程图…

Jetsonnano B01 笔记7:Mediapipe与人脸手势识别

今日继续我的Jetsonnano学习之路&#xff0c;今日学习安装使用的是&#xff1a;MediaPipe 一款开源的多媒体机器学习模型应用框架。可在移动设备、工作站和服务 器上跨平台运行&#xff0c;并支持移动 GPU 加速。 介绍与程序搬运官方&#xff0c;只是自己的学习记录笔记&am…

QT 完成登陆界面跳转到聊天室+完成学生管理系统的查找和删除功能

一、完成登陆界面跳转到聊天室 1> 项目结构 2> 源码 ① .pro ②main #include "mywnd.h" #include"chatCli.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWnd w;w.show();Form f;QObject::co…

Vue2+Vue3基础入门到实战项目(前接六 副线一)—— 面经 项目

day1 接口文档地址&#xff1a;https://www.apifox.cn/apidoc/project-934563/api-20384515 一、项目功能演示 1.目标 启动准备好的代码&#xff0c;演示移动端面经内容&#xff0c;明确功能模块 2.项目收获 二、项目创建目录初始化 vue-cli 建项目 1.安装脚手架 (已安装…

对Spring核心思想的理解(二)

Spring的第二大核心思想&#xff0c;面向切面编程。 官方定义是&#xff1a;通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续&#xff0c;是软件开发中的一个热点&#xff0c;也是Spring框架中的一个重要内容&#xff0c;是函数式编程的一种衍…

【大数据实训】用Hbase模拟电影搜索引擎(四)

博主介绍&#xff1a;✌全网粉丝6W,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌ &#x1f345;文末获取项目联系&#x1f345; 《云计算与大数据处理》课程大作业评分表 项目考核内…

python读取监控流通过websocket连接发送到java服务端,服务端推流到前端

python读取逐帧读取监控 import websocket import base64 import cv2 import numpy as npvideoPath "rtmp://ns8.indexforce.com/home/mystream" // 此为公开RTSP流def on_message(ws, message):print(1)def connection_tmp(ws):websocket.enableTrace(True)ws w…

时序分解 | MATLAB实现基于小波分解信号分解分量可视化

时序分解 | MATLAB实现基于小波分解信号分解分量可视化 目录 时序分解 | MATLAB实现基于小波分解信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于小波分解的分量可视化&#xff0c;MATLAB编程程序&#xff0c;用于将信号分解成不同尺度和频率的子信…

动态库的制作和使用

动态库和静态库的工作原理 配置环境变量 方式1&#xff1a; 坏处&#xff1a;环境变量是临时的 方式2&#xff1a; 1 用户级别的配置&#xff1a; 进入到/home&#xff0c;找到.bashrc&#xff0c;进入 先去找到库的路径 然后再到.bashrc最后一行输入路径 使其生效 2 系统…

芯片产业链补齐,中国成全球唯一拥有全部工业门类的国家

随着一款国产5G手机的发布&#xff0c;中国制造在芯片产业链方面也形成了自己的完整体系&#xff0c;成为全球唯一一个拥有全部工业门类的国家&#xff0c;这是非常值得高兴的消息。 中国早在2010年就成为全球最大制造国&#xff0c;不过当时中国制造所需要的芯片大多都需要从海…

解决img标签和p标签不能水平居中对齐的问题

现象如下&#xff1a; <div class"children"><div class"wrap"><ul><li class"product"><a href"#"><img src"./images/miphone1.jpg"><p>小米手机</p></a></li&…

【LeetCode-中等题】27. 移除元素

文章目录 题目方法一&#xff1a;快慢指针 题目 方法一&#xff1a;快慢指针 int fast 0;// 快指针 用于扫描需要的元素int slow 0;//慢指针 用于记录需要存放元素的位置class Solution { // 快慢指针public int removeElement(int[] nums, int val) {int fast 0;// 快指针…

页面分布引导新手指引(driver.js)

页面分布引导&#xff08;driver.js&#xff09; 最近由于有一个需求——做新手指引&#xff0c;在新用户进入页面的时候提供指引和帮助,快速让用户熟悉页面的功能,但是为了不要过多影响现有的页面逻辑和样式,找到一款非常好用的工具driver.js:Driver.js是一个功能强大且高度可…

golang-bufio 缓冲扫描

前面两篇博客&#xff0c;介绍了 bufio 包中的缓冲读和写&#xff08;bufio.go&#xff09;&#xff0c;下面再来介绍一下缓冲扫描&#xff08;scan.go&#xff09;。这个扫描的是用来对缓存读的更高级封装&#xff0c;提供了一些更易用的方法。 缓冲扫描 Scanner 提供了一个…

电子技术基础(三)__第2章放大电路原理__英文简称

静态分析&#xff0c; 又称为直流分析&#xff0c; 用于求出电路的直流工作状态&#xff0c; 即l输入信号 。 一 . 先看几个英文符号 : 集电极及发射极间电压, 简称管压降 : 发射结电压降&#xff0c; 二. 接着看 加上Q点的英文简称 Q点: 放大电路的静态工作点&#…

【Spring面试】二、BeanFactory与IoC容器的加载

文章目录 Q1、BeanFactory的作用是什么&#xff1f;Q2、BeanDefinition的作用是什么&#xff1f;Q3、BeanFactory和ApplicationContext有什么区别&#xff1f;Q4、BeanFactory和FactoryBean有什么区别&#xff1f;Q5、说下Spring IoC容器的加载过程&#xff08;※&#xff09;Q…

《向量数据库》——向量数据库的使用场景有哪些?

向量数据库在许多应用领域都有广泛的用途,特别是那些需要存储、检索和分析向量数据的场景。以下是一些常见的向量数据库使用场景: 1、相似性搜索: 推荐系统:用于根据用户的历史行为或兴趣,搜索相似用户或物品,以提供个性化推荐。图像检索:允许用户通过图像查询相似的图像…

Leangoo领歌 -敏捷任务管理软件,任务管理更轻松更透明

​任务管理&#xff0c;简单易懂&#xff0c;就是对任务进行管理。那怎么可以更好进行任务管理呢&#xff1f;怎么样样可以让任务进度可视化&#xff0c;一目了然呢&#xff1f;有效的管理可以让我们事半功倍。 接下来我们看一下如何借助任务管理软件高效的做任务管理。 首先…

机器学习实战-系列教程6:SVM分类实战1(鸢尾花数据集/软间隔/线性SVM/非线性SVM/scikit-learn框架)项目实战、原理解读、代码解读

&#x1f308;&#x1f308;&#x1f308;机器学习 实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 SVM分类实战1 SVM分类实战2 支持向量机&#xff08;Support Vector Machines&#xff0c;SVM&#xff09;&#xff0c;用于分类和…