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);

在这里插入图片描述


二、代理模式

代理模式(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);

在这里插入图片描述

在这里插入图片描述


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

<div id="box">默认:前端杂货铺</div>
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

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

在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【golang】派生数据类型---指针 标识符、关键字等

1、指针 对比C/C中的指针&#xff0c;go语言中的指针显得极为简洁&#xff0c;只是简单的获取某个空间的地址 或者 根据指针变量中的内容 获取对应存储空间的内容等操作。 具体示例如下&#xff1a; go中使用指针需要注意的点&#xff1a; 可以通过指针改变它所指向的内存空…

LeetCode——回溯篇(一)

刷题顺序及思路来源于代码随想录&#xff0c;网站地址&#xff1a;https://programmercarl.com 目录 77. 组合 216. 组合总和 III 17. 电话号码的字母组合 39. 组合总和 40. 组合总和 II 77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的…

RK3568 USB支持接口类型

一.简介 RK356x 总共支持 4 个 USB 外设接口&#xff0c;包括 1 个OTG 接口&#xff0c;1 个 USB 3.0 Host 接口&#xff0c;以及 2 个 USB 2.0 Host 接口。 二.常用接口类型介绍 Type-C 接口类型&#xff1a; Type-A 接口类型&#xff1a; Type-A USB 3.1 接口&#xff1a;…

【云原生进阶之PaaS中间件】第一章Redis-1.3Redis配置

1 Redis配置概述 Redis支持采用其内置默认配置的方式来进行启动&#xff0c;而不需要提前配置任何文件&#xff0c;但是这种启动方式只推荐在测试和开发环境中使用&#xff0c;但更好的方式是通过提供一个Redis的配置文件来对Redis进行配置&#xff0c; 这个配置文件一般命名为…

Ansible学习笔记4

file模块&#xff1a; file模块用于对文件相关的操作&#xff08;创建、删除、属性修改、软链接等&#xff09;touch是创建。 [rootlocalhost ~]# ansible group1 -m file -a "path/tmp/111 statetouch" 192.168.17.105 | CHANGED > {"ansible_facts"…

字节前端实习的两道算法题,看看强度如何

最长严格递增子序列 题目描述 给你一个整数数组nums&#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7…

《TCP/IP网络编程》阅读笔记--Socket类型及协议设置

目录 1--协议的定义 2--Socket的创建 2-1--协议族&#xff08;Protocol Family&#xff09; 2-2--Socket类型&#xff08;Type&#xff09; 3--Linux下实现TCP Socket 3-1--服务器端 3-2--客户端 3-3--编译运行 4--Windows下实现 TCP Socket 4-1--TCP服务端 4-2--TC…

Windows下将nginx等可执行文件添加为服务

Windows下将nginx等可执行文件添加为服务 为什么将可执行文件添加为服务&#xff1f;将可执行文件添加为服务的步骤步骤 1&#xff1a;下载和安装 Nginx步骤 2&#xff1a;添加为服务方法一&#xff1a;使用 Windows 自带的 sc 命令方法二&#xff1a;使用 NSSM&#xff08;Non…

新版Mongodb(6.0以上)找不到mongo.exe

安装目录下/bin目录中&#xff0c;没有mongo.exe文件&#xff0c;只有mongod和mongos&#xff0c;以及一个powershell命令脚本。 原因在于&#xff0c;mongodb6.0以后做出了重大改变&#xff0c;mongodb已经不再默认为你安装shell工具&#xff0c;因此需要安装一个额外的shell…

python venv 打包,更换路径后,仍然读取到旧路径 ,最好别换路径,采用docker封装起来

机械盘路径 /home/yeqiang/code/xxx 移动到 /opt/xxx 编辑/opt/xxx/venv/bin/activate VIRTUAL_ENV"/home/yeqiang/code/xxx/venv" 改为 VIRTUAL_ENV"/opt/xxx/venv" 下面还有这么多&#xff0c;参考&#xff1a; (venv) yeqiangyeqiang-MS-7B23:/…

Android修改默认gradle路径

Android Studio每次新建项目&#xff0c;都会默认在C盘生成并下载gradle相关文件&#xff0c;由于C盘空间有限&#xff0c;没多久C盘就飘红了&#xff0c;于是就需要把gradle相关文件转移到其他盘 1、到C盘找到gradle文件 具体路径一般是&#xff1a;C:\Users\用户\ .gradle …

WPF实战项目十四(API篇):登录注册接口

1、新建UserDto.cs public class UserDto : BaseDto{private string userName;/// <summary>/// 用户名/// </summary>public string UserName{get { return userName; }set { userName value;OnPropertyChanged(); }}private string account;/// <summary>…

Mysql锁及行锁机制探索

先讲一下mysql存储方式(innodb) 分为&#xff0c;聚簇索引和非聚簇索引。 聚簇索引&#xff0c;就是b树的所有真实数据。 聚簇索引不是一种索引类型&#xff0c;而是一种数据存储方式。innoDB的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行。当表有聚簇索引时&…

Ubuntu20.04下安装搜狗输入法Linux版

Ubuntu20.04下安装搜狗输入法Linux版 参考搜狗输入法的官网安装指南&#xff1b; 第一步&#xff1a;打开搜狗输入法官网&#xff1b; https://shurufa.sogou.com/ 点击X86_64后将会自动跳转到搜狗输入法的安装指南中&#xff1b; 安装指南 Ubuntu搜狗输入法安装指南 搜狗…

javaee之黑马乐优商城1

问题1&#xff1a;整体的项目架构与技术选型 技术选型 开发环境 域名测试 如何把项目起来&#xff0c;以及每一个目录结构大概是什么样子 通过webpack去启动了有个项目&#xff0c;这里还是热部署&#xff0c;文件改动&#xff0c;内容就会改动 Dev这个命令会生成一个本地循环…

Leetcode54螺旋矩阵

思路&#xff1a;用set记录走过的地方&#xff0c;记下走的方向&#xff0c;根据方向碰壁变换 class Solution:def spiralOrder(self, matrix: list[list[int]]) -> list[int]:max_rows len(matrix)max_cols len(matrix[0])block_nums max_cols * max_rowscount 1i 0j…

Spring: HiddenHttpMethodFilter的用法及原理

作用&#xff1a;将html表单提交的post请求转换为put请求或delete请求发给接口。 html不支持put和delete. 一、web.xml中配置过滤器 <filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenH…

【大模型AIGC系列课程 3-3】低成本的领域私域大模型训练方法

重磅推荐专栏: 《大模型AIGC》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经验分享,旨在帮助读者更好地…

【JS】—闭包—双例对比法学习总结

一、选定知识点&#xff1a;闭包 二、指令学习 1. 闭包MDN的定义 闭包&#xff08;closure&#xff09;是一个函数以及其捆绑的周边环境状态&#xff08;lexical environment&#xff0c;词法环境&#xff09;的引用的组合。换而言之&#xff0c;闭包让开发者可以从内部函数…

从零开始搭建AI网站(6):如何使用响应式编程

响应式编程&#xff08;Reactive Programming&#xff09;是一种编程范式&#xff0c;旨在处理异步数据流和事件流。它通过使用观察者模式和函数式编程的概念&#xff0c;将数据流和事件流抽象为可观察的序列&#xff0c;然后通过操作这些序列来实现各种功能。 在响应式编程中…