当前位置: 首页> 财经> 创投人物 > 5g网络架构_网络广告的特征是()多选题_2024年8月爆发新的大流行病毒吗_抖音seo优化排名

5g网络架构_网络广告的特征是()多选题_2024年8月爆发新的大流行病毒吗_抖音seo优化排名

时间:2025/7/11 22:46:33来源:https://blog.csdn.net/a736755244/article/details/143016041 浏览次数:0次
5g网络架构_网络广告的特征是()多选题_2024年8月爆发新的大流行病毒吗_抖音seo优化排名

前言

在传统的面向对象语言中,给对象添加功能通常使用继承方式。这种方式并不灵活且存在一些问题:

随着业务复杂度增加,会创建出大量的子类,且会导致父子类之间存在强耦合性。

装饰者(decorator)模式,能够在不改变原始对象的基础上,在运行时动态地添加、删除或修改对象的功能。与继承相比,装饰者是一种更轻便灵活的做法。

当然前端也可实现装饰类,但前端中类本质上是构造函数的一种语法糖,此处不做讨论。

举个栗子

在日常项目中,我们会遇到这样的问题:有一个新需求,要在已有功能基础上增加一些内容。但老代码可能不是我们编写的,此时我们会面临如下问题

  • 不知道老代码的使用范围,随意改动容易影响之前的功能
  • 看懂老代码的逻辑再进行修改,比较耗时

我们来看一个例子:假设项目中有一个函数,在多个地方被调用,现在需要在调用这个函数前加一些逻辑。

// 原始函数
function oriFn(){console.log('执行原始函数');
}
// 找到原函数进行修改
function oriFn(){console.log('执行前置逻辑');console.log('执行原始函数');
}

当然在原函数足够简单时可以这么处理,如果原函数非常复杂,就需要考虑在不改变原函数的情况下,新增所需功能,一般做如下处理

let copyFn = oriFn;
oriFn = function(){console.log('执行前置逻辑');copyFn();
}

这种方式符合封闭开放原则,且未改动原函数。但其也存在一些问题

  • 必须新增一个临时变量,如果多次包装会产生多个非必要的变量
  • this指向问题,部分场景下需要手动处理(如document等)

AOP装饰函数

AOP(面向切面编程)。主要作用是把一些跟核心业务逻辑无关的功能抽离出来,再通过“动态织入”的方式掺入业务逻辑模块中,保证了业务逻辑模块的纯净和高内聚性。

// 前置装饰
Function.prototype.before = function(beforeFn){let _this = this;return function(){beforeFn.apply(this, arguments);return _this.apply(this, arguments);}
}
// 后置装饰
Function.prototype.after = function(afterFn){let _this = this;return function(){var ret = _this.apply(this, arguments);afterFn.apply(this, arguments);return ret;}
}

所以上面的例子可以改写为

// 定义前置函数
function beforeFn(){console.log('执行前置逻辑')
}
// 定义后置函数
function afterFn(){console.log('执行后置逻辑')
}oriFn = oriFn.before(beforeFn).after(afterFn);
oriFn();
// 输出:执行前置逻辑
// 输出:执行原始函数
// 输出:执行后置逻辑

使用场景

通常用于日记统计、安全控制、异常处理等与业务逻辑无关的场景下。

便于理解,这里举个常见的例子:在表单提交前要做必填和数据校验,通常写法如下

// 校验
function validate() {if(xxx){console.log('校验失败')return false}return true
}
// 点击提交
function submit() {// 校验if(!validate()){return}// 发送请求console.log('发送请求')fecth('http://xxx.com/xxx')
}

如果此时有如下需求

  • 需要动态决定需不需要校验

  • 需要统计按钮点击次数

  • 需要上报用户各个行为做前端监控

按照一般写法就需要找到各个业务方法入口,不停地添加判断条件,这样做就会导致各个功能模块耦合严重,所以我们可以这么处理

Function.prototype.before = function (beforefn) {let self = thisreturn function () {if (beforefn.name=='validate') {// 前置校验函数结果为false,不执行后续if(beforefn.apply(this, arguments) === false){return}}else{beforefn.apply(this, arguments)}return self.apply(this, arguments)}
}
// 统计函数
function getClickNum(){let _this = this;_this.num = 0;_this.addNum = function(){_this.num++;}
}
let clickFn = new getClickNum()
// 日志输出
function log() {console.log('用户点击了提交按钮')console.log('点击按钮次数:',clickFn.num)
}// 直接调用
submit()
// 需要校验
submit = submit.before(validate)
// 需要统计
submit = submit.before(clickFn.addNum)
// 需要统计+日志
submit = submit.before(clickFn.addNum).after(log)
// 需要校验+统计+日志
submit = submit.before(validate).before(clickFn.addNum).after(log)

这样就可以做到各功能解耦,插拔式处理业务逻辑。

优缺点

优点

  • 符合开闭原则:在不修改已有代码逻辑的情况下扩展新的功能
  • 单一职责原则:将不同的功能实现封装到不同的装饰器中,每个装饰器功能确定,便于维护,且整体代码结构清晰
  • 动态组合:可根据不同的需求场景,通过组装不同装饰器实现功能

缺点

  • 增加复杂度:装饰者模式引入了额外的类和对象,某些情况下会占用较多的内存,且在使用时需要考虑装饰器之间的关系和顺序。
  • 增大运行时开销:每个装饰器都会增加一次方法调用的开销,会产生一定的性能损失。
关键字:5g网络架构_网络广告的特征是()多选题_2024年8月爆发新的大流行病毒吗_抖音seo优化排名

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: