TypeScript | 设计模式05 - 代理模式

简介: 为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。比如,某对象需访问目标对象,但由于某种情况,不适合或不能直接访问目标对象,通过一个中介进行访问,这个中介就是代理对象。

代理模式

为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。

比如,某对象需访问目标对象,但由于某种情况,不适合或不能直接访问目标对象,通过一个中介进行访问,这个中介就是代理对象。

img

  • 抽象主题类:可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求
  • 具体主题类:被委托的类,是具体业务的执行者
  • 代理类:负责对具体主题的应用,并在具体主题处理前后都增加预处理和处理后工作

在代理创建的时期,划分为静态代理和动态代理

  • 静态代理:由由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
  • 动态代理:在程序运行时,运用反射机制动态创建而成
// 静态代理
interface Subject {
  doSave(): void;
}
​
class RealSubject implements Subject {
  doSave() {
    console.log("保存操作");
  }
}
​
class ProxyClass implements Subject {
  private realSubject?: RealSubject;
  
  doSave() {
    if (!this.realSubject) {
      this.realSubject = new RealSubject();
    }
    this.preSave();
    this.realSubject.doSave();
    this.finishSave();
  }
​
  preSave() {
    console.log("保存之前");
  }
​
  finishSave() {
    console.log("保存之后");
  }
}
​
// 动态代理类
class DynamicProxy {
  private target: any;
  constructor(target: any) {
    this.target = target;
  }
​
  getInstance(): any {
    return new Proxy(this.target, {
      get: (target, propKey) => {
       console.log('动态代理的保存之前处理...')
        return target[propKey];
      },
    });
  }
​
// ---- main 函数 ----
(() => {
  const proxy = new ProxyClass();
  proxy.doSave();
  
   console.log('-----动态代理-----');
  const instance = new DynamicProxy(new   RealSubject()).getInstance();
  instance.doSave();
})();
​
// ----输出结果----
保存之前
保存操作
保存之后
-----动态代理-----
动态代理的保存之前处理...
保存操作
​

其中动态代理可以看到使用了Proxy对象,这是typescript提供的Proxy对象

TypeScript中的Proxy

const proxy = new Proxy(target, handle);
  • target 指所要代理的对象
  • handle 也是个对象,是对 target 对象操作的拦截

再回到代码中,getInstance方法返回得到一个RealSubject类的代理,再handle里加了对目标对象的属性 get 操作的拦截,get操作中可进行一些前置操作,如输出 "console.log('动态代理的保存之前处理...')"。

Proxy中还提供其他可拦截的操作

get(target, propKey, receiver)
set(target, propKey, value, receiver)
apply(target, object, args)
defineProperty(target, propKey, propDesc)
deleteProperty(target, propKey)
has(target, propKey)
ownKeys(target)
construct(target, args)
getPrototypeOf(target)
setPrototypeOf(target, proto)
getOwnPropertyDescriptor(target, propKey)
isExtensible(target)
preventExtensions(target)

使用代理的目的是什么?

  • 保护目标对象
  • 增强目标对象(代理类增加对具体类的操作,如上的保存前后的操作)

代理使用场景:

  • 为了隐藏目标对象时使用远程代理,如
  • 当要创建的目标对象开销很大时,可以创建一个虚拟代理,如下载文件太大,创建个虚拟文件,让用户无感知服务器慢的感觉
  • 安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。
  • 延迟加载,为了提高系统性能延迟对目标的加载

参考资料:

-

\

目录
相关文章
|
6天前
|
设计模式 缓存 监控
【设计模式系列笔记】代理模式
代理模式是一种结构型设计模式,它允许一个对象(代理对象)控制另一个对象的访问。代理对象通常充当客户端和实际对象之间的中介,用于对实际对象的访问进行控制、监控或其他目的。
43 1
|
6天前
|
设计模式 C#
设计模式之代理模式(Proxy)
设计模式之代理模式(Proxy)
|
6天前
|
设计模式
设计模式-代理模式
设计模式-代理模式
|
6天前
|
设计模式 数据安全/隐私保护
设计模式之代理模式
设计模式之代理模式
|
6天前
|
设计模式 缓存 安全
小谈设计模式(8)—代理模式
小谈设计模式(8)—代理模式
|
6天前
|
设计模式 JavaScript Java
设计模式——代理模式
一文讲清楚设计模式中的代理模式
26 0
设计模式——代理模式
|
4天前
|
设计模式 Java
Java一分钟之-设计模式:装饰器模式与代理模式
【5月更文挑战第17天】本文探讨了装饰器模式和代理模式,两者都是在不改变原有对象基础上添加新功能。装饰器模式用于动态扩展对象功能,但过度使用可能导致类数量过多;代理模式用于控制对象访问,可能引入额外性能开销。文中通过 Java 代码示例展示了两种模式的实现。理解并恰当运用这些模式能提升代码的可扩展性和可维护性。
19 1
|
6天前
|
设计模式 Java 数据库连接
【重温设计模式】代理模式及其Java示例
【重温设计模式】代理模式及其Java示例
26 2
|
6天前
|
设计模式 安全 网络协议
【设计模式】代理模式例子解析
【设计模式】代理模式例子解析
11 2
|
6天前
|
设计模式 JavaScript 算法
js设计模式-策略模式与代理模式的应用
策略模式和代理模式是JavaScript常用设计模式。策略模式通过封装一系列算法,使它们可互换,让算法独立于客户端,提供灵活的选择。例如,定义不同计算策略并用Context类执行。代理模式则为对象提供代理以控制访问,常用于延迟加载或权限控制。如创建RealSubject和Proxy类,Proxy在调用RealSubject方法前可执行额外操作。这两种模式在复杂业务逻辑中发挥重要作用,根据需求选择合适模式解决问题。