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

个人简介

个人主页: 前端杂货铺
‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
个人状态: 研发工程师,现效力于中国工业软件事业
人生格言: 积跬步至千里,积小流成江海
推荐学习:前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.jsThree.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', '大盘鸡');

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式_第1张图片


二、桥接模式

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

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

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

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

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

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式_第2张图片

// 奥迪轿车(车型一)
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();

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式_第3张图片


三、组合模式

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

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

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式_第4张图片

// 文件夹
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();

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式_第5张图片


本篇小结

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

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

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

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

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


参考资料:

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

在这里插入图片描述


你可能感兴趣的:(设计模式,javascript,设计模式,桥接模式,组合模式)