首页 > 其他分享 >设计模式 - 代理模式

设计模式 - 代理模式

时间:2024-04-07 13:34:08浏览次数:16  
标签:obj log 代理 value prop personProxy 模式 console 设计模式

使用代理对象,我们可以对与某些对象的交互进行更多的控制。代理对象可以在我们与对象进行交互时确定其行为,例如,当我们获取值或设置值时。

一般来说,代理是指代替他人的人。你不是直接和那个人说话,而是和代表你试图联系的人说话的代理。在JavaScript中也是如此:我们不是直接与目标对象交互,而是与Proxy对象交互。

让我们创建一个代表约翰·多伊的人物对象。

const person = {
  name: "John Doe",
  age: 42,
  nationality: "American",
};

我们不想直接与这个对象交互,而是想与代理对象交互。在 JavaScript 中,我们可以通过创建一个新的Proxy实例来轻松创建新的代理。

const person = {
  name: "John Doe",
  age: 42,
  nationality: "American",
};

const personProxy = new Proxy(person, {});

Proxy 的第二个参数是表示处理程序的对象。在处理程序对象中,我们可以根据交互的类型定义特定的行为。尽管有许多方法可以添加到代理处理程序中,但最常见的两种方法是 get 和 set

get:尝试访问属性时调用

set:尝试修改属性时调用

实际上,最终将发生以下情况:

我们将与 personProxy 交互,而不是直接与 person 对象交互。

让我们将处理程序添加到 personProxy 代理。当尝试修改属性时,从而在Proxy上调用 set 方法,我们希望代理记录属性的先前值和新值。当尝试访问属性时,从而在Proxy上调用 get 方法,我们希望代理记录一个更具可读性的句子,其中包含属性的键和值。

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    console.log(`The value of ${prop} is ${obj[prop]}`);
  },
  set: (obj, prop, value) => {
    console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
    obj[prop] = value;
  },
});

让我们看看当我们尝试修改或检索属性时会发生什么。

const person = {
  name: "John Doe",
  age: 42,
  nationality: "American"
};

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    console.log(`The value of ${prop} is ${obj[prop]}`);
  },
  set: (obj, prop, value) => {
    console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
    obj[prop] = value;
    return true;
  }
});

personProxy.name;
personProxy.age = 43;

访问 name 属性时,代理返回了一个听起来更好的句子:The value of name is John Doe

修改 age 属性时,代理返回此属性的上一个值和新值:Changed age from 42 to 43

代理可用于添加验证。用户不应能够将person的年龄更改为字符串值,或为其指定空名称。或者,如果用户试图访问对象上不存在的属性,我们应该让用户知道。

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    if (!obj[prop]) {
      console.log(
        `Hmm.. this property doesn't seem to exist on the target object`
      );
    } else {
      console.log(`The value of ${prop} is ${obj[prop]}`);
    }
  },
  set: (obj, prop, value) => {
    if (prop === "age" && typeof value !== "number") {
      console.log(`Sorry, you can only pass numeric values for age.`);
    } else if (prop === "name" && value.length < 2) {
      console.log(`You need to provide a valid name.`);
    } else {
      console.log(`Changed ${prop} from ${obj[prop]} to ${value}.`);
      obj[prop] = value;
    }
  },
});

让我们看看当我们尝试传递错误值时会发生什么!

const person = {
  name: "John Doe",
  age: 42,
  nationality: "American"
};

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    if (!obj[prop]) {
      console.log(`Hmm.. this property doesn't seem to exist`);
    } else {
      console.log(`The value of ${prop} is ${obj[prop]}`);
    }
  },
  set: (obj, prop, value) => {
    if (prop === "age" && typeof value !== "number") {
      console.log(`Sorry, you can only pass numeric values for age.`);
    } else if (prop === "name" && value.length < 2) {
      console.log(`You need to provide a valid name.`);
    } else {
      console.log(`Changed ${prop} from ${obj[prop]} to ${value}.`);
      obj[prop] = value;
    }
    return true;
  }
});

personProxy.nonExistentProperty;
personProxy.age = "44";
personProxy.name = "";

代理确保我们没有使用错误的值修改 person 对象,这有助于我们保持数据纯净!

Reflect

JavaScript 提供了一个名为 Reflect 的内置对象,这使我们在使用代理时更容易操作目标对象。

以前,我们尝试通过直接获取或设置带有括号表示法的值来修改和访问代理中目标对象的属性。相反,我们可以使用 Reflect 对象。Reflect 对象上的方法与handler对象上的方法同名。

我们可以通过 Reflect.get() 和 Reflect.set() 访问或修改目标对象上的属性,而不是通过 obj[prop] 访问属性或通过 obj[prop] = value 设置属性。这些方法接收与处理程序对象上的方法相同的参数。

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    console.log(`The value of ${prop} is ${Reflect.get(obj, prop)}`);
  },
  set: (obj, prop, value) => {
    console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
    Reflect.set(obj, prop, value);
  },
});

我们可以使用 Reflect 对象轻松访问和修改目标对象的属性。

const person = {
  name: "John Doe",
  age: 42,
  nationality: "American"
};

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    console.log(`The value of ${prop} is ${Reflect.get(obj, prop)}`);
  },
  set: (obj, prop, value) => {
    console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
    return Reflect.set(obj, prop, value);
  }
});

personProxy.name;
personProxy.age = 43;
personProxy.name = "Jane Doe";

权衡

代理是添加对对象行为的控制的强大方法。代理可以有各种用例:它可以帮助验证、格式化、通知或调试。

过度使用 Proxy 对象或对每个handler方法调用执行繁重操作很容易对应用程序的性能产生负面影响。最好不要对性能关键代码使用代理。

标签:obj,log,代理,value,prop,personProxy,模式,console,设计模式
From: https://blog.csdn.net/liangshanbo1215/article/details/137219424

相关文章

  • C++设计模式:TemplateMethod模式(一)
    1、概念定义定义一个操作中的算法的骨架结构(稳定),而将一些步骤延迟(变化)到子类中。TemplateMethod使得子类可以不改变(复用)一个算法的骨架结构即可重定义(override重写)该算法的某些特定步骤在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很......
  • 折腾PXE网络启动 pxe 双引导bios&uefi模式 WDS windows deployment server
    简介:这才是最终章。折腾这么多,其实还是为了WDS。折腾TFTPD引导bios,是为了确认引导文件可以引导maxdos。折腾TFTPD引导uefi,也是为了确认可以引导grub。折腾OPENWRT双引导bios和UEFI,是为了确认DHCPoption93。现在我们有了可以双引导的TFTP-ROOT目录,虽然只有4个文件,这足够我......
  • 毅四捕Go设计模式笔记——桥接模式
    桥接模式(BridgePattern)桥接模式是一种结构型设计模式,它的主要目的是将抽象部分与它的实现部分解耦,使它们都可以独立的变化。通过使用组合而非继承的方式,桥接模式结合了两个独立的维度,让它们可以独立扩展而不是在两者之间建立静态的继承关系。为了解决什么问题?桥接模式解......
  • 折腾PXE网络启动 pxe 双引导bios&uefi模式 OPENWRT
    简介:前两篇已经折腾了pxe引导bios和uefi,甭管启动的是啥,已经可以网络引导了。但是同时面对这两种系统的时候怎么办?需要通过dhcp的参数来控制谁启动什么。核心内容RFC4578:DynamicHostConfigurationProtocol(DHCP)OptionsfortheIntelPrebooteXecutionEnvironment(......
  • nginx同一端口配置代理不同路径下的文件
    需求如下:CMS系统后台通过freemarker模板生成静态html文件,主站点和子站点的html文件保存在不同文件夹下。根据站点ID分别保存到不同文件夹,结构如下:  其中,75为主站点,111为子站点b。通过nginx配置,在同一域名下根据不同路径访问不同站点html。  实现访问www.xxx.com访问......
  • 适配器模式
     1.介绍适配器模式将某个类的接口转换成客户端期望的另一个接口,用户调用适配器转换出来的目标接口方法,适配器再调用被适配者的相关接口方法; 2.实现方式(1)类适配器模式/***@Description:被适配类*@date:2024/4/615:56*/publicclassVoltage220V{......
  • 观察者模式与发布-订阅模式的对决
    ......
  • nginx反向代理实现不同域名映射到同一台服务器的相同端口
    在实际应用中,我们经常会遇到多个域名需要映射到同一台服务器的相同端口的情况,这时可以使用nginx反向代理来实现。以实现将www.example.com和www.test.com都映射到127.0.0.1的80端口为例,具体步骤如下:修改hosts文件在本地hosts文件中添加以下两行:127.0.0.1www.example.com12......
  • Photoshop混合模式的底层原理
        Photoshop虽然不是什么高手,但平时工作中难免会用到,处理部分需求还是可以胜任的。接触PS这么多年,对PS中图层的混合模式(BlendMode)一直就处于懵懂状态,即使是看了教材及视频后,有了一点感性认识,但在实际操作中仍旧无法运用起来。直至某一天,我在B站看到韩世麟的《把PS......
  • 常用软件架构模式优缺点及应用场景
     1、分层架构模式最常见的架构模式就是分层架构或者称为n层架构。大部分软件架构师、设计师和开发者都对这个架构模式非常熟悉。尽管对于层的数量和类型没有具体限制,但大部分分层架构主要由四层组成:展现层、业务层、持久层和数据库层,如下图所示。一个很流行的n层架构示......