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

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

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 请求拦截、组件增强还是函数扩展方面,装饰器模式都提供了优雅的解决方案。

推荐文章

Hypothesis是一个强大的Python测试库
2024-11-19 04:31:30 +0800 CST
PHP 微信红包算法
2024-11-17 22:45:34 +0800 CST
PHP 允许跨域的终极解决办法
2024-11-19 08:12:52 +0800 CST
2025年,小程序开发到底多少钱?
2025-01-20 10:59:05 +0800 CST
如何在Vue 3中使用Ref访问DOM元素
2024-11-17 04:22:38 +0800 CST
Golang 中你应该知道的 noCopy 策略
2024-11-19 05:40:53 +0800 CST
JavaScript 异步编程入门
2024-11-19 07:07:43 +0800 CST
MySQL数据库的36条军规
2024-11-18 16:46:25 +0800 CST
一些实用的前端开发工具网站
2024-11-18 14:30:55 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
MySQL 优化利剑 EXPLAIN
2024-11-19 00:43:21 +0800 CST
java MySQL如何获取唯一订单编号?
2024-11-18 18:51:44 +0800 CST
浅谈CSRF攻击
2024-11-18 09:45:14 +0800 CST
对多个数组或多维数组进行排序
2024-11-17 05:10:28 +0800 CST
Vue 3 是如何实现更好的性能的?
2024-11-19 09:06:25 +0800 CST
程序员茄子在线接单