编程 JavaScript设计模式:装饰器模式

2024-11-19 06:05:51 +0800 CST views 694

JavaScript设计模式:装饰器模式

模式概念

如何在不改变对象本身功能的基础上为其增加额外的新功能?装饰器模式(Decorator Pattern)就是为此设计的一种结构型设计模式,它允许在不修改原有对象的前提下,动态地为其增加新的功能。这种模式通过创建一个包装对象来包裹实际对象,从而在不修改其代码的情况下实现功能的扩展。

装饰器模式是继承的替代技术,它通过对象组合来取代继承,实现动态扩展对象功能。

模式结构

装饰器模式的核心组件包括:

  • Component(抽象组件):定义了一个对象接口,可以动态地为这些对象添加职责。
  • ConcreteComponent(具体组件):定义了抽象组件的具体实现,即被装饰的具体对象。
  • Decorator(抽象装饰者):持有一个 Component 对象的引用,定义与 Component 一致的接口。
  • ConcreteDecorator(具体装饰者):实现 Decorator 的接口,并为对象增加新的功能。

代码实现

// 抽象组件
class Component {
  operate() {
    throw new Error('This method must be implemented by subclasses');
  }
}

// 具体组件
class ConcreteComponent extends Component {
  operate() {
    return 'ConcreteComponent';
  }
}

// 抽象装饰者
class Decorator extends Component {
  constructor(component) {
    super();
    this._component = component;
  }

  operate() {
    return this._component.operate();
  }
}

// 具体装饰者A
class ConcreteDecoratorA extends Decorator {
  operate() {
    const result = this._component.operate();
    return `${result} + ConcreteDecoratorA`;
  }
}

// 具体装饰者B
class ConcreteDecoratorB extends Decorator {
  operate() {
    const result = this._component.operate();
    return `${result} + ConcreteDecoratorB`;
  }
}

// 使用示例
const component = new ConcreteComponent();
console.log(component.operate());  // 输出: ConcreteComponent

const decoratedComponentA = new ConcreteDecoratorA(component);
console.log(decoratedComponentA.operate());  // 输出: ConcreteComponent + ConcreteDecoratorA

const decoratedComponentAB = new ConcreteDecoratorB(decoratedComponentA);
console.log(decoratedComponentAB.operate());  // 输出: ConcreteComponent + ConcreteDecoratorA + ConcreteDecoratorB

使用函数的装饰器:

// 为函数添加前置函数
Function.prototype.before = function(beforeFn) {
  const _this = this;
  return function() {
    beforeFn.apply(this, arguments);
    return _this.apply(this, arguments);
  };
};

// 为函数添加后置函数
Function.prototype.after = function(afterFn) {
  const _this = this;
  return function() {
    const result = _this.apply(this, arguments);
    afterFn.apply(this, arguments);
    return result;
  };
};

// 创建一个函数
function test() {
  console.log("111111");
}

// 使用装饰器增加前置和后置函数
const testAll = test
  .before(() => { console.log("000000"); })
  .after(() => { console.log("222222"); });

testAll(); 
// 输出:
// 000000
// 111111
// 222222

模式效果

优点:

  • 动态扩展:不修改原有对象的代码即可动态地添加新功能。
  • 透明性:装饰者和实际对象对客户端透明。
  • 灵活性:可以叠加多个装饰者,灵活增加不同的功能。

缺点:

  • 复杂性增加:使用多个装饰者可能会增加系统的复杂性。
  • 难以管理:多个装饰者叠加时,追踪装饰的类变得困难。

模式应用

1. Axios 拦截器

Axios 的拦截器是装饰器模式的一个典型应用。它允许在请求或响应前后对其进行拦截,修改或添加额外的处理逻辑。

// 创建 Axios 实例
const axios = axios.create({ baseURL: 'http://aaa.com' });

// 请求拦截器
axios.interceptors.request.use(
  config => {
    config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  error => Promise.reject(error)
);

// 响应拦截器
axios.interceptors.response.use(
  response => response,
  error => Promise.reject(error)
);

axios.get('/user')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

2. React 高阶组件(HOC)

高阶组件(Higher-Order Component, HOC)是 React 中的一种常见模式,它接受一个组件作为输入,返回一个增强了该组件的新组件。

class Home extends React.PureComponent {
  render() {
    return <div>{this.props.name}</div>;
  }
}

// 定义高阶组件
function enhanceComponent(WrappedComponent) {
  return class NewComponent extends React.PureComponent {
    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
}

const EnhancedHome = enhanceComponent(Home);

3. TypeScript 装饰器

TypeScript 提供了装饰器来增强类和类成员的功能。装饰器可以用于类、方法、属性和参数。

function methodWatcher(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log(`Calling ${propertyKey} with arguments:`, args);
    return originalMethod.apply(this, args);
  };
}

class MyClass {
  @methodWatcher
  myMethod(arg1: string, arg2: number) {
    console.log('Original method logic');
  }
}

const obj = new MyClass();
obj.myMethod('hello', 42);

4. Nest.js 中的装饰器

Nest.js 是一个基于 Node.js 的服务器框架,它通过装饰器实现依赖注入、路由处理等功能,是装饰器模式的优秀应用。


总结

装饰器模式是一种强大且灵活的设计模式,它允许动态地为对象添加功能,而不会影响对象本身的结构。无论是在 HTTP 请求拦截、组件增强还是函数扩展方面,装饰器模式都提供了优雅的解决方案。

推荐文章

Linux查看系统配置常用命令
2024-11-17 18:20:42 +0800 CST
PHP设计模式:单例模式
2024-11-18 18:31:43 +0800 CST
Vue3的虚拟DOM是如何提高性能的?
2024-11-18 22:12:20 +0800 CST
Go 接口:从入门到精通
2024-11-18 07:10:00 +0800 CST
用 Rust 玩转 Google Sheets API
2024-11-19 02:36:20 +0800 CST
SQL常用优化的技巧
2024-11-18 15:56:06 +0800 CST
MySQL 优化利剑 EXPLAIN
2024-11-19 00:43:21 +0800 CST
Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
Vue3中如何处理跨域请求?
2024-11-19 08:43:14 +0800 CST
PHP 命令行模式后台执行指南
2025-05-14 10:05:31 +0800 CST
如何开发易支付插件功能
2024-11-19 08:36:25 +0800 CST
OpenCV 检测与跟踪移动物体
2024-11-18 15:27:01 +0800 CST
php常用的正则表达式
2024-11-19 03:48:35 +0800 CST
Golang 中你应该知道的 noCopy 策略
2024-11-19 05:40:53 +0800 CST
Vue3 实现页面上下滑动方案
2025-06-28 17:07:57 +0800 CST
Go语言中实现RSA加密与解密
2024-11-18 01:49:30 +0800 CST
JavaScript数组 splice
2024-11-18 20:46:19 +0800 CST
程序员茄子在线接单