当前位置: 首页 > ops >正文

js设计模式-装饰器模式

一.概念

装饰器模式核心价值:

  1. 非侵入式扩展:无需修改核心功能源代码
  2. 责任链模式:通过装饰器链组合复杂逻辑
  3. 避免条件判断:消除冗余的if (featureX)代码膨胀

二.使用举例

  1. 原型扩展
<html>
<button tag="login" id="button">点击打开登录浮层</button>
<script>Function.prototype.after = function (afterfn) {var __self = this;return function () {var ret = __self.apply(this, arguments);afterfn.apply(this, arguments);return ret;}};var showLogin = function () {console.log('打开登录浮层');}var log = function () {console.log('上报标签为: ' + this.getAttribute('tag'));}showLogin = showLogin.after(log); // 打开登录浮层之后上报数据document.getElementById('button').onclick = showLogin; 
</script></html>
  1. 工具函数扩展
<html><button tag="login" id="button">点击打开登录浮层</button><script>document.addEventListener('DOMContentLoaded', function() {// 工具函数:创建函数执行后的增强函数function composeAfter(original, afterFn) {return function(...args) {const result = original.apply(this, args);afterFn.apply(this, args);return result};}// 原始函数:不包含副作用const showLogin = () => {console.log('打开登录浮层');};// 副作用函数:需要访问触发元素属性const trackEvent = function() {console.log('上报标签为: ' + this.getAttribute('tag'));};// 函数组合:合并核心逻辑与监视记录const combinedFunction = composeAfter(showLogin, trackEvent);// DOM 交互封装在闭包内const button = document.getElementById('button');button.addEventListener('click', combinedFunction);});</script>
</html>

三. 应用场景

  1. 日志记录
    实现对函数调用的跟踪,不改动原函数逻辑
function logDecorator(func) {return function (...args) {console.log(`Calling ${func.name} with ${args}`);const result = func.apply(this, args);console.log(`Result: ${result}`);return result;};
}// 使用装饰器
const add = logDecorator(function(a, b) {return a + b;
});add(2, 3); // 输出调用日志
  1. 性能分析
    测量函数执行时间
function timerDecorator(func) {return function (...args) {const start = performance.now();const result = func.apply(this, args);console.log(`Time taken: ${performance.now() - start}ms`);return result;};
}// 装饰计算密集型函数
const fibonacci = timerDecorator(function(n) {return n <= 1 ? n : fibonacci(n-1) + fibonacci(n-2);
});fibonacci(30); // 输出耗时

3.参数校验
确保函数参数符合规范

function validateParams(func) {return function (...args) {args.forEach(arg => {if (typeof arg !== 'number') throw new Error('Invalid parameter type');});return func.apply(this, args);};
}const multiply = validateParams(function(a, b) {return a * b;
});multiply(2, 'three'); // 抛出参数类型错误

关键优势总结:

  1. 代码复用:将常用功能封装为装饰器库
  2. 高内聚性:避免将横切逻辑嵌入核心业务代码
  3. 可插拔性:通过装饰器叠加或替换灵活控制功能组合
  4. DRY原则:如权限验证逻辑只需维护一处

通过装饰器模式,开发者能更自然地实现"开闭原则":对扩展开放,对修改关闭。

四. 总结

通过装饰器模式,框架开发者能够:

  1. 保持核心功能的最小稳定
  2. 提供无限扩展可能性
  3. 减少因功能增加导致的维护成本指数级增长

这种将「必须功能」与「期望功能」分离的设计,在现代前端框架(如React Hooks)、中间件(如Koa)中得到了广泛采用,是构建可扩展系统的核心策略

http://www.xdnf.cn/news/19785.html

相关文章:

  • CI(持续集成)、CD(持续交付/部署)、CT(持续测试)、CICD、CICT
  • Few-Shot Prompting 实战:用5个例子让GPT-4学会复杂任务
  • (二)文件管理-基础命令-cd命令的使用
  • 中州养老:资源添加功能
  • gitlab推送失败,内存不足的处理
  • 深入浅出Spring IoC与DI:设计思想、实现方式与反射技术详解
  • Excel 电影名匹配图片路径教程:自动查找并写入系统全路径
  • PostgreSQL 中唯一索引的工作原理
  • 分布式AI算力系统番外篇-----超体的现实《星核》
  • Vue基础知识-重要的内置关系:vc实例.__proto__.__proto__ === Vue.prototype
  • 股指期货可以通过移仓长线持有吗?
  • AppInventor2 如何自定义包名?
  • 华为云云原生架构赋能:大腾智能加速业务创新步伐
  • 【深度学习新浪潮】视觉大模型在预训练方面有哪些关键进展?
  • 鸿蒙UI开发实战:解决布局错乱与响应异常
  • 企业实用——MySQL的备份详解
  • 基于机器学习的Backtrader波动性预测与管理
  • Kubernetes ConfigMap 更新完整指南:原理、方法与最佳实践
  • PyTorch实战——ResNet与DenseNet详解
  • Huggingface终于没忍住,OpenCSG坚持开源开放
  • flume拓扑结构详解:从简单串联到复杂聚合的完整指南
  • Linux 的信号 和 Qt 的信号
  • IO_HW_9_3
  • MySQL数据库恢复步骤(基于全量备份和binlog)
  • 揭秘ArrowJava核心:IndexSorter高效排序设计
  • Cookie、Session、登录
  • 一个工业小白眼中的 IT/OT 融合真相:数字化工厂的第一课
  • SQL Server核心架构深度解析
  • AlexNet:计算机视觉的革命性之作
  • PostgreSQL性能调优-优化你的数据库服务器