js设计模式之代理模式及订阅发布模式实例详解

JS设计模式之代理模式及订阅发布模式实例详解

代理模式

什么是代理模式?

代理是一种结构型模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。

代理模式可以解决哪些问题?

在程序的开发过程中,我们经常会遇到需要对一个对象进行一些扩展或加强的情况。使用代理模式可以让我们更加方便地实现这一需求,同时它还可以为我们的代码提供一定的解耦和保护机制,帮助我们更好地进行模块化开发和维护。

代理模式的应用场景

代理模式常用在以下几个场景:

  1. 远程代理:隐藏一个对象存在于不同地址空间的事实。
  2. 虚拟代理:根据需要创建一个资源密集型的对象。
  3. 安全代理:用于控制真实对象的访问权限。
  4. 智能指引:在调用真实对象之前进行一些额外的处理操作。

代理模式的实现方式

下面分别介绍一些常见的代理模式实现方式。

1. 静态代理

静态代理是一个固定的代理实现,它由开发人员手动编写出一个代理类,该代理类被用于代理某个目标类,以提供对目标类的访问控制和增强。

示例代码如下:

class Subject {
  request() {
    console.log('Subject.request');
  }
}

class Proxy {
  constructor(subject) {
    this.subject = subject;
  }

  request() {
    console.log('Proxy.request');
    this.subject.request();
  }
}

const subject = new Subject();
const proxy = new Proxy(subject);
proxy.request(); // Proxy.request, Subject.request

这个示例代码中,我们创建了一个Subject类和一个Proxy类,其中Subject类是我们真正需要包装的类。在Proxy类中,我们引用了一个Subject对象,并且给出了一个request()方法,当调用该方法时,会先输出代理类的名字,然后再调用被代理对象的request()方法。

2. 动态代理

与静态代理不同的是,动态代理是在运行时动态生成的代理类,它可以执行更加复杂的代理操作。

示例代码如下:

const handler = {
  set(target, property, value) {
    console.log(`Setting ${property}=${value}`);
    target[property] = value;
  }
};

const target = {};
const proxy = new Proxy(target, handler);

proxy.name = 'Tom'; // Setting name=Tom

在这个示例代码中,我们使用ES6中的Proxy类来生成动态代理。该类接受一个被代理的目标对象和一个代理处理器,当访问和修改目标对象的属性时,会自动调用代理处理器中定义的一些函数。

订阅发布模式

什么是订阅发布模式?

订阅发布模式,也称为观察者模式,是一种行为型模式,它定义了对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖该对象的对象都会收到通知并进行相应的更新和操作。

订阅发布模式可以解决哪些问题?

订阅发布模式可以帮助代码更好地进行模块化和解耦,同时也可以大大降低代码中的重复逻辑和冗余代码。

订阅发布模式的应用场景

订阅发布模式常用在以下场景:

  1. 多个对象之间需要进行通信和数据共享。
  2. 一个对象的状态变化需要影响到其他多个对象。
  3. 需要动态地添加或删除一些操作或功能。

订阅发布模式的实现

下面给出一些订阅发布模式的实现方式。

1. 自定义事件

自定义事件是一种比较常见的实现方式,我们可以通过自定义事件来实现对象之间的通信和数据共享。

示例代码如下:

class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(eventName, listener) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(listener);
  }

  once(eventName, listener) {
    const wrapper = (...args) => {
      listener(...args);
      this.off(eventName, wrapper);
    };
    this.on(eventName, wrapper);
  }

  off(eventName, listener) {
    if (!this.events[eventName]) {
      return;
    }
    const idx = this.events[eventName].indexOf(listener);
    if (idx >= 0) {
      this.events[eventName].splice(idx, 1);
    }
  }

  emit(eventName, ...args) {
    if (!this.events[eventName]) {
      return;
    }
    for (const listener of this.events[eventName]) {
      listener(...args);
    }
  }
}

const eventEmitter = new EventEmitter();

eventEmitter.on('test', message => {
  console.log(`Received message: ${message}`);
});

eventEmitter.emit('test', 'Hello, world!'); // Received message: Hello, world!

在这个示例代码中,我们创建了一个EventEmitter类,它维护了一个包含所有事件监听器的列表,提供了on()、off()、once()、emit()四个方法。通过调用on()方法可以添加一个事件监听器,通过emit()方法可以触发指定的事件。

2. Node.js中的events模块

在Node.js中,我们可以使用events模块来方便地实现订阅发布模式。

示例代码如下:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', () => {
  console.log('an event occurred!');
});

myEmitter.emit('event'); // an event occurred!

在这个示例代码中,我们通过require()函数引入了Node.js内置的events模块,并创建了一个自定义的MyEmitter类,该类继承自EventEmitter类。通过调用其on()方法可以添加对应的事件监听器,并通过emit()方法来触发相应的事件。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js设计模式之代理模式及订阅发布模式实例详解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • nodejs npm错误Error:UNKNOWN:unknown error,mkdir ‘D:\Develop\nodejs\node_global’at Error

    当使用npm安装模块时,可能会遇到Error: UNKNOWN: unknown error, mkdir ‘D:\Develop\nodejs\node_global’的错误。这个错误通常是因为没有权限在指定的目录中创建文件夹而导致的。 以下是解决此错误的完整攻略: 确保用户具有文件夹创建权限 首先,确保当前用户具有在指定目录中创建文件夹的权限。对于D:\…

    node js 2023年6月8日
    00
  • Node.js实现下载文件的两种实用方式

    我来详细讲解“Node.js实现下载文件的两种实用方式”的完整攻略。 1. 使用Node.js自带的http、https模块进行文件下载 在Node.js中,我们可以使用原生的http、https模块来实现文件下载功能,具体步骤如下: 1.1 加载http、https模块 const http = require(‘http’); const https =…

    node js 2023年6月8日
    00
  • 四叉树有损位图压缩处理程序示例

    四叉树有损位图压缩处理程序示例攻略 简介 四叉树是一种树型数据结构,它将平面划分为四个象限,每个节点都表示一个矩形区域。通过将图像中的每个像素点添加到四叉树中,可以实现对图像的压缩和处理。本文将介绍如何使用四叉树实现有损位图压缩处理程序。 程序实现步骤 将原图像转换为灰度图像; 将灰度图像转换为二值图像; 对于二值图像,将其划分为若干个相等的矩形区域; 对每…

    node js 2023年6月8日
    00
  • 如何将Node.js中的回调转换为Promise

    将Node.js中的回调函数转换为Promise是一种常见的操作,它可以使代码更加简洁易读。下面是将Node.js中的回调函数转换为Promise的完整攻略: 步骤一:创建一个Promise 首先,我们需要创建一个Promise。Promise是一个对象,它代表异步操作的最终完成或失败,并提供了一些方法来处理操作的结果。 以下是创建一个Promise的示例代…

    node js 2023年6月8日
    00
  • 详解nodejs操作mongodb数据库封装DB类

    下面我将为你详细讲解“详解nodejs操作mongodb数据库封装DB类”的完整攻略。 1. 前言 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,使用它可以在服务端运行 JavaScript 程序。而 MongoDB 是一个基于文档模型的 NoSQL 数据库。Node.js 与 MongoDB 的结合是一种非常常见而又…

    node js 2023年6月8日
    00
  • 浅谈react前后端同构渲染

    下面是关于“浅谈React前后端同构渲染”的攻略: 一、什么是前后端同构渲染? 前后端同构渲染(server-side rendering, SSR)是指在服务端将React代码渲染成HTML字符串,并把这些字符串发送到客户端,在客户端再进行React组件的挂载和事件绑定等操作。通过同构渲染,我们可以实现更好的SEO、更快的内容呈现以及更好的用户体验。 二、…

    node js 2023年6月8日
    00
  • NodeJs的fs读写删除移动监听

    下面我会详细讲解NodeJs中fs模块的读写删除移动监听的操作: 读取文件 我们可以通过 fs 模块中的 fs.readFile() 方法读取指定的文件。该方法支持传入四个参数:文件路径、编码格式、回调函数以及可选的错误处理函数。下面是一个简单的例子: const fs = require(‘fs’); fs.readFile(‘./test.txt’, ‘…

    node js 2023年6月8日
    00
  • nodejs初始化init的示例代码

    当我们开始用Node.js编写一个新的项目时,我们需要在项目的根目录中初始化一个Node.js应用程序。Node.js应用程序初始化是使用npm命令进行的,它可以生成我们的项目所需的文件和文件夹,以及内置依赖项和配置文件。 下面是一个Node.js初始化示例: 打开命令行工具,进入项目根目录,执行以下命令: npm init 这将启动一个交互式环境,提示你输…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部