【设计模式】代理模式(Proxy Pattern)详解

代理模式(Proxy Pattern)详解

一、代理模式的概念

代理模式(Proxy Pattern)是一种结构型设计模式,它通过一个代理对象来控制对另一个对象的访问。

核心思想

  • 代理对象和被代理对象实现相同的接口。
  • 代理对象在调用目标对象前后增加额外的功能(如日志、权限控制、缓存、延迟加载等)。
  • 客户端只和代理对象交互,不直接访问目标对象,从而降低耦合,提高扩展性

二、代理模式的作用

1. 控制访问权限

  • 例如,用户未登录时拦截请求,避免访问敏感资源。

2. 记录日志

  • 例如,记录用户的 API 调用信息,便于追踪。

3. 提供缓存

  • 例如,避免重复请求数据库,提高性能

4. 远程代理

  • 例如,前端调用后端 API,代理请求数据

5. 延迟初始化(懒加载):

  • 例如,对象创建成本高时,先用代理对象占位,等需要时再创建

三、代理模式的分类

代理模式主要分为以下几种类型:

类型 特点 示例
远程代理(Remote Proxy) 代理远程对象 前端调用后端 API,如 axios 代理请求
虚拟代理(Virtual Proxy) 延迟加载,按需创建 Vue 懒加载图片
保护代理(Protection Proxy) 控制访问权限 用户权限控制,未登录时拦截请求
缓存代理(Cache Proxy) 缓存数据,避免重复计算 Redis 数据缓存
智能引用代理(Smart Reference Proxy) 统计对象引用次数,自动释放 Vue3 Proxy 监听对象变化

四、代理模式的代码实现

1. JavaScript 经典示例

直接访问 vs 代理访问

class RealSubject {
    request() {
        console.log("RealSubject: Handling request.");
    }
}

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

    request() {
        console.log("Proxy: Checking access before forwarding the request.");
        this.realSubject.request();
        console.log("Proxy: Logging the request after execution.");
    }
}

// 使用代理
const realSubject = new RealSubject();
const proxy = new Proxy(realSubject);

proxy.request();

输出

Proxy: Checking access before forwarding the request.
RealSubject: Handling request.
Proxy: Logging the request after execution.

解释

  • Proxy 代理 RealSubject,在调用 request() 方法前后添加额外的逻辑(如权限检查和日志记录)。
  • 客户端只和代理交互,不直接访问真实对象

2. 远程代理(API 请求代理)

场景:
  • 代理前端 API 请求,自动添加 Authorization 头,避免手动传递 token
class APIProxy {
    constructor(baseURL) {
        this.baseURL = baseURL;
    }

    async request(endpoint, options = {}) {
        // 自动添加身份认证 Token
        options.headers = {
            ...options.headers,
            Authorization: `Bearer ${localStorage.getItem("token")}`
        };

        console.log(`Requesting: ${this.baseURL}${endpoint}`);
        const response = await fetch(`${this.baseURL}${endpoint}`, options);
        return response.json();
    }
}

// 使用代理请求 API
const api = new APIProxy("https://api.example.com");

api.request("/users").then(data => console.log(data));

代理的作用

  • 拦截 API 请求,自动添加 Authorization
  • 减少重复代码,开发者无需手动添加 token

3. 虚拟代理(懒加载图片)

场景:
  • 图片未加载时先显示占位符,等图片加载完成后再替换
class ImageProxy {
    constructor(realImageURL) {
        this.realImageURL = realImageURL;
        this.imgElement = document.createElement("img");
        this.imgElement.src = "placeholder.jpg"; // 先显示占位图

        // 模拟网络请求加载真实图片
        setTimeout(() => {
            this.imgElement.src = this.realImageURL;
        }, 2000);
    }

    getImageElement() {
        return this.imgElement;
    }
}

// 使用代理
const proxyImage = new ImageProxy("real-image.jpg");
document.body.appendChild(proxyImage.getImageElement());

代理的作用

  • 图片未加载时先显示占位符,等加载完成后自动替换。
  • 减少页面加载阻塞,提高用户体验

4. 保护代理(权限控制)

场景:
  • 用户未登录时,拦截敏感操作
class User {
    constructor(name, role) {
        this.name = name;
        this.role = role;
    }
}

class AdminAccessProxy {
    constructor(user) {
        this.user = user;
    }

    deleteData() {
        if (this.user.role !== "admin") {
            console.log("Access Denied: Only admin can delete data.");
            return;
        }
        console.log("Data deleted successfully.");
    }
}

// 创建用户
const normalUser = new User("John", "guest");
const adminUser = new User("Alice", "admin");

// 代理对象
const proxy1 = new AdminAccessProxy(normalUser);
proxy1.deleteData(); // 拒绝访问

const proxy2 = new AdminAccessProxy(adminUser);
proxy2.deleteData(); // 成功删除

代理的作用

  • 控制权限:只有 admin 用户才能执行删除操作。
  • 安全性提升,防止未授权用户访问敏感功能。

五、代理模式 vs 装饰器模式

对比项 代理模式(Proxy) 装饰器模式(Decorator)
核心作用 控制访问,拦截请求 动态增强对象功能
是否继承原对象 通常实现相同接口 直接增强已有对象
典型应用 API 请求代理、权限控制、缓存 Vue3 reactive()、日志增强
对象的创建 代理对象可以创建或管理真实对象 直接包装对象,增强功能

六、代理模式的优缺点

✅ 优点

解耦客户端和目标对象,增强扩展性。
权限控制(如 API 访问权限)。
延迟初始化,提高性能(如图片懒加载)。
日志、缓存、监控,增强功能。

❌ 缺点

增加系统复杂度,需要额外的代理类。
可能带来性能开销(如远程代理涉及网络通信)。


七、总结

  1. 代理模式通过一个代理对象控制对目标对象的访问,可以在访问前后添加额外逻辑
  2. 代理模式适用于
    • API 请求代理(自动添加 token)。
    • 懒加载(图片、数据)。
    • 权限控制(用户角色判断)。
    • 缓存代理(避免重复计算)。
  3. 常见的代理模式
    • 远程代理(API 请求代理)。
    • 虚拟代理(懒加载)。
    • 保护代理(权限控制)。

代理模式是前端、后端、运维等多个领域的重要设计模式,合理使用可提高代码质量!

你可能感兴趣的:(面试考题专栏(前后端),设计模式,代理模式)