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 倍。此时,即可使用策略模式对不同等级的员工进行年终奖的发放。

javascript 复制代码
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);

二、代理模式

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

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

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

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

javascript 复制代码
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);

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

html 复制代码
<div id="box">默认:前端杂货铺</div>
javascript 复制代码
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;
    }
})

三、观察者模式

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

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

javascript 复制代码
// 主体对象(被观察者)
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. JavaScript设计模式 【作者:千锋教育】


相关推荐
WaaTong1 分钟前
《重学Java设计模式》之 单例模式
java·单例模式·设计模式
小白学大数据4 分钟前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_3901617713 分钟前
防抖函数--应用场景及示例
前端·javascript
3345543241 分钟前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test42 分钟前
js下载excel示例demo
前端·javascript·excel
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
7年老菜鸡2 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js