• JavaScript设计模式(四)——策略模式、代理模式、观察者模式


    个人简介

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

    设计模式

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


    ✨✨前言

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

    上一节,我们学习了单例模式、装饰器模式、适配器模式。这一节,我们学习策略模式、代理模式和观察者模式…

    一、策略模式

    策略模式定义了一系列 算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

    举个栗子:公司年终奖分为四个等级(S、A、B、C),S 级发薪水的 6 倍,A 级发薪水的 4 倍,B 级发薪水的 3倍,C 级发薪水的 2 倍。此时,即可使用策略模式对不同等级的员工进行年终奖的发放。

    let strategy = {
        "S": (salary) => {
            return salary * 6;
        },
        "A": (salary) => {
            return salary * 4;
        },
        "B": (salary) => {
            return salary * 3;
        },
        "C": (salary) => {
            return salary * 2;
        }
    }
    
    function calBonus(level, salary) {
        return strategy[level](salary);
    }
    
    let levelS = calBonus("S", 20000);
    let levelA = calBonus("A", 10000);
    let levelB = calBonus("B", 9000);
    let levelC = calBonus("C", 8000);
    
    console.log('S:', levelS, ' A:', levelA, ' B:', levelB, ' C:', levelC);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述


    二、代理模式

    代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。

    代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。

    Vue3 中的双向数据绑定原理就是基于代理模式(Proxy)的。

    举个栗子:很多明星不能自己接戏,只能通过经纪人来接,这种情景其实就可以看成代理模式。若经纪人规定出场费不能低于 10000,则低于 10000 的都会被经纪人拒绝 “价格不合适”,大于等于 10000 才会同意出演。

    class Star {
        play() {
            console.log("价格合适,可以演戏");
        }
    }
        
    class StarProxy {
        constructor() {
            this.superStar = new Star();
        }
    
        talk(price) {
            if (price >= 10000) {
                this.superStar.play();
            } else {
                throw new Error("价格不合适")
            }
        }
    }
    
    let broker = new StarProxy();
    broker.talk(10000);
    broker.talk(2000);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    在这里插入图片描述


    下面我们简单的模仿 Vue3 的双向数据绑定(其原理就是代理模式)。

    <div id="box">默认:前端杂货铺div>
    
    • 1
    let vueObj = {};
    
    let proxy = new Proxy(vueObj, {
        get(target, key) {
            return target[key];
        },
        set(target, key, value) {
            if (key === "data") {
                box.innerHTML = value;
            }
            target[key] = value;
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    在这里插入图片描述


    三、观察者模式

    观察者模式是一种 行为型设计模式,它定义了一种 一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

    我们定义一个主体类 Subject 和一个观察者类 Observer,在 Subject 中设置几个方法 => add(给主体添加观察者)、remove(给主体移出观察者)、notify(通知观察者类更新观察者),在 Observer 中设置更新观察者的方法 => update

    // 主体对象(被观察者)
    class Subject {
        constructor() {
            // 收集所有的观察者
            this.observers = [];
        }
    
        // 给主体添加观察者
        add(observer) {
            this.observers.push(observer);
        }
    
        // 移出某个/某些观察者
        remove(observer) {
            this.observers = this.observers.filter(item => item !== observer);
        }
    
        // 通知观察者类更新观察者
        notify() {
            this.observers.forEach(item => {
                item.update();
            })
        }
    }
    
    // 观察者类
    class Observer {
        constructor(name) {
            this.name = name;
        }
        // 更新观察者
        update() {
            console.log("update", this.name);
        }
    }
    
    // 主体对象
    const subject = new Subject();
    // 观察者1
    const observer1 = new Observer("CSDN");
    // 观察者2
    const observer2 = new Observer("前端杂货铺");
    
    // 给主体对象添加观察者
    subject.add(observer1);
    subject.add(observer2);
    
    // 通知观察者类 => 更新观察者
    subject.notify();
    
    console.log('分-------割-------线')
    
    // 给主体对象移出观察者1
    subject.remove(observer1);
    // 通知观察者类 => 更新观察者
    subject.notify();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    在这里插入图片描述


    🎉🎉本篇小结

    本文我们了解了策略模式、代理模式和观察者模式。

    策略模式 是一种 行为型设计模式,它定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

    代理模式 是一种 结构型设计模式,它通过一个类代表另一个类的功能。

    观察者模式 是一种 行为型设计模式。它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

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


    参考资料:

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

    在这里插入图片描述


  • 相关阅读:
    [暑假]操作系统概述笔记[学习方法篇]
    尚硅谷ES学习笔记一
    HTTP协议 学习笔记
    操作系统——进程与线程の选择题整理
    用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
    JavaDemo——关于BigDecimal类
    表单 v-decorator 相关用法
    常见网络攻击及防御方法总结(XSS、SQL注入、CSRF攻击)
    【rar密码】rar文件不知道解压密码怎么解压?
    Android开发中集合之Collection和Collections集合
  • 原文地址:https://blog.csdn.net/qq_45902692/article/details/132643485