深入理解JavaScript系列(31):设计模式之代理模式详解

深入理解JavaScript系列(31):设计模式之代理模式详解

概述

代理模式是一种结构型模式,其中一个对象充当另一个对象的接口,以控制对该对象的访问。 这种类型的设计模式属于结构模式,它对对象进行组合,以提供新的功能,同时使代码更易于维护。

在 JavaScript 中,代理模式允许我们在运行时动态地创建对象并控制其行为。 代理可以隔离对实际对象的访问,并对外部世界提供它自己的访问方式,以限制直接访问实际对象。

代理模式的实现

代理模式通过创建代理对象对访问对象进行控制,代理对象与实际对象具有相同的接口,开发者可以通过代理对象访问实际对象。

代理对象

代理对象的作用是隐藏实际对象,以允许开发者访问实际对象的方法或属性,并在访问之前对访问请求进行处理。

代理对象与实际对象通常实现相同的接口,以便开发者可以在无需了解实际对象的情况下,使用代理对象访问实际对象。

class RealSubject {
  someOperation() {
    console.log("RealSubject.someOperation()");
  }
}

class ProxySubject {
  constructor(realSubject) {
    this.realSubject = realSubject;
  }

  someOperation() {
    console.log("ProxySubject.someOperation()");
    //handle the privilege to real object
    this.realSubject.someOperation();
  }
}

// Client
const realSubject = new RealSubject();
const proxySubject = new ProxySubject(realSubject);
proxySubject.someOperation();

保护代理

保护代理可以控制实际对象对内部状态的访问,如果属性或者方法不应该被外部对象访问,可以使用保护代理。

下面的例子中,我们使用保护代理来防止直接访问 privateMethod 方法

class RealSubject {
  someOperation() {
    console.log("RealSubject.someOperation()");
  }

  privateMethod() {
    console.log("RealSubject.privateMethod()");
  }
}

class ProxySubject {
  constructor(realSubject) {
    this.realSubject = realSubject;
  }

  someOperation() {
    console.log("ProxySubject.someOperation()");
    //handle the privilege to real object
    this.realSubject.someOperation();
    //Cannot access to privateMethod from outside
  }
}

// Client
const realSubject = new RealSubject();
const proxySubject = new ProxySubject(realSubject);
proxySubject.someOperation();

虚拟代理

虚拟代理是一种惰性加载模式,可以通过避免初始化真正对象来减少系统资源的使用。

下面的例子中,我们使用虚拟代理来加载视频

class VideoPlayer {
  constructor(video) {
    this.video = video;
  }

  play() {
    console.log(`Playing video: ${this.video.name}`);
  }
}

class VideoPlayerProxy {
  constructor(video) {
    this.video = video;
  }

  play() {
    if (!this.videoPlayer) {
      // Initialize the video player only when the user wants to play video
      this.videoPlayer = new VideoPlayer(this.video);
    }
    this.videoPlayer.play();
  }
}

// Client
const video = { name: "Introduction to Design Patterns" };
const videoPlayerProxy = new VideoPlayerProxy(video);
videoPlayerProxy.play();

总结

代理模式提供了访问受控对象的另一种方法,可以使用代理实现额外的功能或提供额外的保护。代理模式是一种非常常见的设计模式,它可以在需要对对象进行访问控制,缓存或记录日志时非常有用。

示例 1:代理模式用于日志系统

class BitcoinPrice {
  constructor() {}

  async getBitcoinPriceByCurrencyCode(currencyCode) {
    const response = await fetch(
      `https://api.coindesk.com/v1/bpi/currentprice/${currencyCode}.json`
    );
    const data = await response.json();
    return data.bpi[currencyCode].rate_float;
  }
}

class BitcoinPriceProxy {
  constructor() {
    this.bitcoinPrice = new BitcoinPrice();
  }

  async getBitcoinPriceByCurrencyCode(currencyCode) {
    const price = await this.bitcoinPrice.getBitcoinPriceByCurrencyCode(
      currencyCode
    );
    console.log(`Bitcoin price for ${currencyCode} is $${price}`);
    return price;
  }
}

// Client
const bitcoinPriceProxy = new BitcoinPriceProxy();
bitcoinPriceProxy.getBitcoinPriceByCurrencyCode("USD");

示例 2:代理模式用于缓存系统

class SomeContent {
  constructor(contentId) {
    this.contentId = contentId;
    this.content = null;
  }

  async getContent() {
    // simulate loading content from a database
    await new Promise((resolve) => setTimeout(resolve, 3000));
    return `<html><body>Content for page ${this.contentId}</body></html>`;
  }
}

class CachedContent {
  constructor(content) {
    this.content = content;
    this.cachedContent = null;
  }

  async getCachedContent() {
    if (!this.cachedContent) {
      console.log("Cache miss, fetching content...");
      this.cachedContent = await this.content.getContent();
    }
    console.log("Cache hit, returning content from cache...");
    return this.cachedContent;
  }
}

// Client
const contentId = 3;
const content = new SomeContent(contentId);
const cachedContent = new CachedContent(content);
console.log("First fetch:");
await cachedContent.getCachedContent();
console.log("Second fetch:");
await cachedContent.getCachedContent();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解JavaScript系列(31):设计模式之代理模式详解 - Python技术站

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

相关文章

  • JavaScript 克隆数组最简单的方法

    下面是详细的“JavaScript 克隆数组最简单的方法”的攻略: 标题 JavaScript 克隆数组最简单的方法 简介 在JavaScript中,我们经常需要对数组进行操作,有时候需要创建数组的副本。本篇文章将讲述最简单的JavaScript克隆数组的方法及其示例。 代码实现 JavaScript克隆数组有以下两种方法: 1. 使用 Array.from…

    JavaScript 2023年5月27日
    00
  • Android应用开发中WebView的常用方法笔记整理

    以下是详细讲解“Android应用开发中WebView的常用方法笔记整理”的完整攻略: 简介 在Android应用开发中,WebView是常见的一个控件,它可以在应用中展示网页、HTML内容或其他的网络资源。在本篇攻略中,我们将讲解Android应用开发中WebView的常用方法和技巧。 基本用法 首先,让我们来看一下WebView的基本用法。 添加权限 在…

    JavaScript 2023年6月11日
    00
  • Javascript幻灯片播放功能实现过程解析

    下面是详细讲解“Javascript幻灯片播放功能实现过程解析”的攻略。 Javascript幻灯片播放功能实现过程解析 简介 幻灯片播放是一个很常见的功能,通常用来展示图片、文字等等。本文将介绍如何使用JavaScript实现一个简单的幻灯片播放功能。 实现 HTML结构 首先,我们需要编写HTML结构来显示幻灯片。以下是一个基本的HTML结构: <…

    JavaScript 2023年6月10日
    00
  • 在js代码拼接dom对象到页面上去的模板总结(必看)

    标题: 在JS代码拼接DOM对象到页面上的模板总结 在前端开发中,操作DOM节点是一个非常基础但又非常重要的任务。在JavaScript中,我们可以通过拼接DOM对象来实现动态渲染页面的目的,这种方式通常被称为“JS代码拼接DOM对象到页面上的模板”,本文将为您详细介绍该模板的使用方法和注意事项。 使用方法 对于JS代码拼接DOM对象到页面上,我们通常可以使…

    JavaScript 2023年6月10日
    00
  • 浅谈javascript中的加减时间

    浅谈JavaScript中的加减时间 在JavaScript中,可以通过一些内置的方法来对时间进行加减操作,本篇文章将讲解如何使用这些方法来实现时间的加减。 使用Date对象进行时间的加减 Date对象是JavaScript中表示时间的标准对象。它提供了多种方法来对时间进行加减操作。 加时间 通过调用Date对象的set方法,在原有时间的基础上添加一定的时间…

    JavaScript 2023年5月27日
    00
  • cypress中丰富的调试工具使用方法

    Cypress是一个开源的前端自动化测试框架,其提供了丰富的调试工具。本文将详细讲解Cypress中这些调试工具的使用方法。 1. 使用Chrome开发者工具 Cypress默认使用Chrome来运行测试,因此我们可以直接使用Chrome开发者工具来调试测试代码。在测试代码中添加断点,运行测试时会进入断点处,从而方便我们调试代码。 示例: describe(…

    JavaScript 2023年6月11日
    00
  • 详解JavaScript中分解数字的三种方法

    当我们需要处理数字时,有时需要将它们拆分成更细粒度的数值或进行一些计算。在JavaScript中,有多种方法可以实现数字的拆分和计算,本文将介绍其中三种方法。 方法一:将数字转换成字符串处理 数值类型也可以使用字符串上的方法,将数字转换成字符串之后即可使用字符串方法处理。 示例代码: const num = 1234567; const strNum = S…

    JavaScript 2023年5月28日
    00
  • JS创建对象的写法示例

    以下是关于JS创建对象的写法示例的完整攻略: 什么是JS对象 JS中的对象指的是一组键值对的集合。它们通过点号或中括号访问。 1.对象字面量创建对象 // 通过字面量的方式创建一个对象 const obj = { name: "Lena", age: 25, gender: "female", sayHi: funct…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部