基于装饰器——我劝你不要在业务代码上装逼!!!(下)

简介: 基于装饰器——我劝你不要在业务代码上装逼!!!(下)

2.动态参数

  • • 在日常开发中,我们需要向后台接口发送请求来获取信息,例如传参如下。业务在后续时需要添加新参数,每个接口需要把 token 值也一并传过去, 普遍我们会去改封装的请求方法,把 token 参数添加进去。但我们直接修改封装好的请求方法不是好的行为,那我们可使用上面说过的 AOP 方式来改进。
{
    name: 'xxxx',
    password: 'xxxx',
}
  • • 如下:
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>AOP动态参数</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script src="https://unpkg.com/vue@3.2.20/dist/vue.global.js"></script>
    </head>
    <body>
        <div id="app">{{message}}</div>
    </body>
</html>
<script type="text/javascript">
    const { reactive, ref, createApp } = Vue;
    const app = createApp({
        setup() {
            const message = ref("empty params");
            Function.prototype.before = function (beforeFn) {
                var _self = this;
                return function () {
                    beforeFn.apply(this, arguments);
                    return _self.apply(this, arguments);
                };
            };
            Function.prototype.after = function (afterFn) {
                var _self = this;
                return function () {
                    var ret = _self.apply(this, arguments);
                    afterFn.apply(this, arguments);
                    return ret;
                };
            };
            function ajax(type, url, params){
                message.value = `${type} ----> ${url} -----> ${JSON.stringify(params)}`;
            }
            function getToken(){
                // do something
                return 'token';
            }
            ajax = ajax.before(function(type, url, params){
                params.token = getToken();
            })
            ajax('get', 'https://www.baidu.com/userinfo', {name: 'se', password: 'xsdsd'});
            return {
                message,
            };
        },
    });
    app.mount("#app");
</script>

3.表单校验

  • • 在日常开发中,我们经常要去做校验表单数据,通常的方式是在功能函数中进行判断处理或将判断逻辑提取为一个函数的方式。但这种方式其实是与功能性函数相混合,且校验逻辑与功能性函数有耦合关系。那我们可使用 AOP 方式来改进。
  • • 如下:
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>AOP表单验证</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script src="https://unpkg.com/vue@3.2.20/dist/vue.global.js"></script>
    </head>
    <body>
        <div id="app">
            <label>
                姓名:
                <input
                    type="text"
                    v-model="data.name"
                    placeholder="请输入姓名"
                />
            </label>
            <label>
                密码:
                <input
                    type="text"
                    v-model="data.pass"
                    placeholder="请输入密码"
                />
            </label>
            <p v-if="data.name || data.pass">{{data.name + '/' + data.pass}} ----after-----> {{data.message}}</p>
            <hr>
            <button @click="submitBtn">submit</button>
        </div>
    </body>
</html>
<script type="text/javascript">
    const { reactive, ref, createApp, watchEffect } = Vue;
    const app = createApp({
        setup() {
            const data = reactive({
                name: "",
                pass: "",
                message: "",
            });
            Function.prototype.before = function (beforeFn) {
                var _self = this;
                return function () {
                    if (beforeFn.apply(this, arguments) === false) return;
                    return _self.apply(this, arguments);
                };
            };
            function valid() {
                if (!data.name || !data.pass) {
                    alert("用户名或密码不能为空");
                    return false;
                }
            }
            function formSubmit() {
                console.log("data ------>", data);
                data.message = `${data.name} ------- ${data.pass}`;
            }
            formSubmit = formSubmit.before(valid);
            function submitBtn() {
                formSubmit();
            }
            return {
                data,
                submitBtn,
            };
        },
    });
    app.mount("#app");
</script>

装饰器模式的优缺点

  • • 优点:
  1. 1. 扩展性强:装饰器模式允许在不修改现有代码的情况下,动态地添加新功能或修改现有功能。通过使用装饰器,可以在运行时按需组合和堆叠装饰器对象,实现各种组合方式,从而实现更多的功能扩展。
  2. 2. 遵循开闭原则:装饰器模式通过添加装饰器类来扩展功能,而不是修改现有的代码。这样可以保持原有代码的稳定性,符合开闭原则,即对扩展开放,对修改关闭。
  3. 3. 分离关注点:装饰器模式将功能的扩展和核心功能分离开来,每个装饰器类只关注单一的额外功能。这样可以使代码更加清晰、可读性更高,并且容易维护和测试。
  • • 缺点:
  1. 1. 增加复杂性:使用装饰器模式会增加额外的类和对象,引入了更多的复杂性和层次结构。这可能使代码变得更加复杂,理解和调试起来可能更加困难。
  2. 2. 潜在的性能影响:由于装饰器模式涉及多个对象的组合和堆叠,可能会引入额外的运行时开销,对性能产生一定的影响。尤其是当装饰器链较长时,可能会导致性能下降。

装饰器模式的适用场景

  1. 1. 动态地扩展对象功能:当需要在运行时动态地为对象添加额外的功能或责任时,装饰器模式是一个很好的选择
  2. 2. 遵循开闭原则:如果你希望在不修改现有代码的情况下扩展功能,而且要保持代码的稳定性,装饰器模式是一个合适的解决方案。
  3. 3. 分离关注点:当你希望将不同的功能分离开来,使每个功能都有自己独立的装饰器类时,装饰器模式是有用的。每个装饰器只关注单一的额外功能,这样可以使代码更加清晰、可读性更高,并且容易维护和测试。
  4. 4. 多层次的功能组合:如果你需要实现多个功能的组合,而且每个功能都可以灵活选择是否添加,装饰器模式可以很好地满足这个需求。通过堆叠多个装饰器对象,可以按照特定的顺序组合功能,实现各种组合方式。
  5. 5. 继承关系的替代方案:当你面临类似于创建大量子类的情况时,装饰器模式可以作为继承关系的替代方案。通过使用装饰器模式,可以避免创建过多的子类,而是通过组合不同的装饰器来实现不同的功能组合。

Tip: 文章部分内容参考于曾探大佬的《JavaScript 设计模式与开发实践》。文章仅做个人学习总结和知识汇总

特殊字符描述

问题标注 Q:(question)答案标注 R:(result)注意事项标准:A:(attention matters)详情描述标注:D:(detail info)总结标注:S:(summary)分析标注:Ana:(analysis)提示标注:T:(tips)

目录
相关文章
|
11月前
如何设置Excel的快捷键?
【10月更文挑战第19天】如何设置Excel的快捷键?
1433 8
|
8月前
|
存储 搜索推荐 API
拼多多根据ID取商品详情原数据API接口的开发、运用与收益
拼多多作为中国电商市场的重要参与者,通过开放平台提供了丰富的API接口,其中根据ID取商品详情原数据的API接口尤为重要。该接口允许开发者通过编程方式获取商品的详细信息,为电商数据分析、竞品分析、价格监测、商品推荐等多个领域带来了丰富的应用场景和显著的收益。
414 10
|
5月前
|
Shell
亲测好用!解决国内短信受限的办法分享
随着国内多个平台暂停对个人用户的短信发送服务,不少人面临困扰。为此推荐一款实用工具——Spug推送平台,可满足发送短信验证码等需求。通过简单的注册、创建模板与调用接口步骤,即可快速实现短信发送功能。例如,使用bash命令调用接口:`curl https://push.spug.cc/send/xxx?code=6677&targets=151xxxx0875`。注意遵守平台规则和法律法规,确保正常使用。在短信权限受限的情况下,Spug无疑是个人用户的理想选择。
230 3
亲测好用!解决国内短信受限的办法分享
|
8月前
|
容灾 关系型数据库 分布式数据库
MyBase:打破云边界,构建云边端一体的DBaaS服务
《MyBase:打破云边界,构建云边端一体的DBaaS服务》会议聚焦DBaaS在实际场景中的应用。首先介绍DBaaS概念及其价值,随后通过两个典型场景——云下独立部署运维和跨云部署容灾,展示MyBase如何满足客户多云需求。最后分享客户案例,包括某保险公司在自有IaaS上部署企业级数据库,以及自研数据库在他云IaaS上的容灾能力。MyBase One旨在提供自主可控、主权合规、高可用的数据库服务,支持异构IaaS环境。
157 3
|
9月前
|
机器学习/深度学习 存储 人工智能
【AI系统】自定义计算图 IR
本文介绍了模型转换的方法及流程,重点讲解了计算图的自定义方法和优化技术。通过IR(Intermediate Representation)将不同AI框架的模型转换为统一格式,实现跨平台高效部署。计算图由张量和算子构成,支持多种数据类型和内存排布格式,通过算子融合等优化技术提高模型性能。文章还详细说明了如何使用FlatBuffers定义计算图结构,包括张量、算子和网络模型的定义,为自定义神经网络提供了实践指南。
252 3
【AI系统】自定义计算图 IR
|
8月前
|
小程序
产品经理面试分级汇总
《产品经理面试分级汇总》涵盖自我介绍、工作内容、团队配合、需求管理、项目流程等多方面问题,帮助候选人全面准备面试。内容包括如何划分需求优先级、参与项目开发的流程、迭代经验、复杂需求处理、版本验收标准等,旨在考察候选人的综合能力和职业规划。
|
前端开发
CSS动画效果(鼠标滑过按钮动画)
CSS动画效果(鼠标滑过按钮动画)
|
SQL Java 数据库连接
Hibernate实体类的要求是什么?
【8月更文挑战第21天】
146 0
|
人工智能 算法 ice
【2024美赛】D题(中英文):五大湖水资源问题Problem Problem D: Great Lakes Water Problem
【2024美赛】D题(中英文):五大湖水资源问题Problem Problem D: Great Lakes Water Problem
263 1
|
Web App开发 Java Python
生成github贡献者前14头像组
生成github贡献者前14头像组
166 0