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

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉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) {// 发布的时候没有该类型,直接 returnif (!this.message[type]) return;this.message[type].forEach(item => item(data));}// 订阅subscribe(type, cb) {this.message[type] = [cb];}// 取消订阅unsubscribe(type, cb) {// 取消订阅的时候如果没有该类型,直接 returnif (!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.mzph.cn/news/74286.shtml

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

相关文章

前后端分离项目-基于springboot+vue的it职业生涯规划系统的设计与实现(内含代码+文档+报告)

it职业生涯规划系统在jdk环境中&#xff0c;使用Java语言进行编码&#xff0c;使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务。总之&#xff0c;it职业生涯规划系统集中管理信息&#xff0c;有着保密性强&#xff0c;效率高&#xff0c;存储空间大…

高忆管理:六连板捷荣技术或难扛“华为概念股”大旗

在本钱商场上名不见经传的捷荣技术&#xff08;002855.SZ&#xff09;正扛起“华为概念股”大旗。 9月6日&#xff0c;捷荣技术已拿下第六个连续涨停板&#xff0c;短短七个生意日&#xff0c;股价累积涨幅逾越90%。公司已连发两份股票生意异动公告。 是炒作&#xff0c;还是…

Linux命令200例:mkfs用于创建文件系统

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

Pytest系列-fixture的详细使用和结合conftest.py的详细使用(3)

介绍 前面一篇讲了setup、teardown可以实现在执行用例前或结束后加入一些操作&#xff0c;但这种都是针对整个脚本全局生效的。 Fixture是pytest的非常核心功能之一&#xff0c;在不改变被装饰函数的前提下对函数进行功能增强&#xff0c;经常用于自定义测试用例前置和后置工作…

恭贺弘博创新2023下半年软考(中/高级)认证课程顺利举行

为迎接2023年下半年软考考试&#xff0c;弘博创新于2023年9月2日举行了精品的软考中/高级认证课程&#xff0c;线下线上学员都积极参与学习。 在课程开始之前&#xff0c;弘博创新的老师为学员们提供了详细的学习资料和准备建议&#xff0c;以确保学员们在课程中能够跟上老师的…

【实践篇】Redis最强Java客户端(三)之Redisson 7种分布式锁使用指南

文章目录 0. 前言1. Redisson 7种分布式锁使用指南1.1 简单锁&#xff1a;1.2 公平锁&#xff1a;1.3 可重入锁&#xff1a;1.4 红锁&#xff1a;1.5 读写锁&#xff1a;1.6 信号量&#xff1a;1.7 闭锁&#xff1a; 2. Spring boot 集成Redisson 验证分布式锁3. 参考资料4. 源…

LeetCode 49题: 字母异位词分组

题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&qu…

Linux中的软件管家——yum

目录 ​编辑 一&#xff0c;软件安装的方式 二&#xff0c;对yum的介绍 1.yum的作用 2&#xff0c;yum的库 三&#xff0c;yum下载软件的操作 1.yumlist 2.yuminstall 3.yumremove 四&#xff0c;yum源的转换 一&#xff0c;软件安装的方式 软件安装的方式大概分为三种…

【韩顺平】Linux基础

目录 1.网络连接三种方式 1.1 桥接模式&#xff1a;虚拟系统可以和外部系统通讯&#xff0c;但是容易造成IP冲突【1-225】 1.2 NAT模式&#xff1a;网络地址转换模式。虚拟系统可以和外部系统通讯&#xff0c;不造成IP冲突。 1.3 主机模式&#xff1a;独立的系统。 2.虚拟机…

C# PSO 粒子群优化算法 遗传算法 随机算法 求解复杂方程的最大、最小值

复杂方程可以自己定义&#xff0c;以下是看别人的题目&#xff0c;然后自己来做 以下是计算结果 private void GetMinResult(out double resultX1, out double min){double x1, result;Random random1 new Random(DateTime.Now.Millisecond* DateTime.Now.Second);min 99999…

C语言柔性数组详解:让你的程序更灵活

柔性数组 一、前言二、柔性数组的用法三、柔性数组的内存分布四、柔性数组的优势五、总结 一、前言 仔细观察下面的代码&#xff0c;有没有看出哪里不对劲&#xff1f; struct S {int i;double d;char c;int arr[]; };还有另外一种写法&#xff1a; struct S {int i;double …

软件与系统安全复习

软件与系统安全复习 课程复习内容 其中 软件与系统安全基础 威胁模型 对于影响系统安全的所有信息的结构化表示 本质上&#xff0c;是从安全的视角解读系统与其环境 用于理解攻击者 什么可信、什么不可信攻击者的动机、资源、能力&#xff1b;攻击造成的影响 具体场景…

了解被测系统(二)接入链路--包括域名解析和Nginx代理

目录 一、接入链路示例 二、域名解析过程 1、相关概念 1.1、域的结构 1.2、DNS是什么&#xff1f; 1.3、DNS根域名服务器 1.4、顶级域名服务器 1.5、权威域名服务器 2、域名解析过程 2.1、检查Hosts文件 2.2、检查本地DNS缓存 2.3、DNS解析--本地DNS服务器 2.4、D…

后端SpringBoot+前端Vue前后端分离的项目(二)

前言&#xff1a;完成一个列表&#xff0c;实现表头的切换&#xff0c;字段的筛选&#xff0c;排序&#xff0c;分页功能。 目录 一、数据库表的设计 ​编辑二、后端实现 环境配置 model层 mapper层 service层 service层单元测试 controller层 三、前端实现 interface接…

合宙Air724UG LuatOS-Air LVGL API控件-滑动条 (Slider)

滑动条 (Slider) 滑动条看起来和进度条是有些是有些像&#xff0c;但不同的是滑动条可以进行数值选择。 示例代码 -- 回调函数 slider_event_cb function(obj, event)if event lvgl.EVENT_VALUE_CHANGED then local val (lvgl.slider_get_value(obj) or "0")..&…

在PHP8中遍历数组-PHP8知识详解

所谓遍历数组就是把数组中的变量值读取出来。遍历数组中的所有元素对程序员来说是经常使用的操作&#xff0c;通过遍历数组可以完成数组元素的查询工作。 这好比你去商场买东西一样&#xff0c;要买什么东西&#xff0c;就去该区域浏览一遍&#xff0c;以便找出适合自己的产品…

【JavaEE】_CSS常用属性值

目录 1. 字体属性 1.1 设置字体家族 font-family 1.2 设置字体大小 font-size 1.3 设置字体粗细 font-weight 1.4 设置字体倾斜 font-style 2. 文本属性 2.1 设置文本颜色 color 2.2 文本对齐 text-align 2.3 文本装饰 text-decoration 2.4 文本缩进 text-indent 2.…

合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)

图片 (Image) 图片IMG是用于显示图像的基本对象类型&#xff0c;图像来源可以是文件&#xff0c;或者定义的符号。 示例代码 -- 创建图片控件 img lvgl.img_create(lvgl.scr_act(), nil) -- 设置图片显示的图像 lvgl.img_set_src(img, "/lua/luatos.png") -- 图片…

【Linux】进程概念I --操作系统概念与冯诺依曼体系结构

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 1. 冯诺依曼体系结构为什么这样设计? 2. 操作系统概念为什么我们需要操作系统呢?操作系统怎么进行管理? 计算机是由两部分组…

性能监控-grafana+prometheus+node_exporter

Prometheus是一个开源的系统监控和报警工具。它由SoundCloud开发并于2012年发布&#xff0c;后来成为了一个独立的开源项目&#xff0c;并得到了广泛的应用和支持。 Prometheus的主要功能包括采集和存储各种系统和应用程序的监控数据&#xff0c;并提供强大的查询语言PromQL来…