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

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

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)

相关文章
|
4月前
|
前端开发
十分钟封装一个好用的axios,省时又省力他不香吗
十分钟封装一个好用的axios,省时又省力他不香吗
|
26天前
|
数据采集 数据可视化 数据库连接
谁说无代码搞不定MES系统,我看smardaten能行!
我国工业制造数字化渗透率较低,为提升效率,某企业尝试使用无代码开发平台smardaten进行制造执行系统(MES)的开发,成功满足了超过80%的项目需求。smardaten以其全域数据资产管理、业务流程组装及智能分析可视化等特性,支持快速开发。平台可轻松实现数据对接、应用模块搭建、大屏展示、移动APP开发及OA门户集成等功能,大幅缩短开发周期并降低技术门槛。此外,smardaten提供SaaS试用版,便于更多企业探索无代码开发的可能性。
|
1月前
信不信?工作这么多年,还有很多网工不知道光模块光衰的正常范围?
信不信?工作这么多年,还有很多网工不知道光模块光衰的正常范围?
|
4月前
|
存储 Web App开发 运维
发布、部署,傻傻分不清楚?从概念到实际场景,再到工具应用,一篇文章让你彻底搞清楚
部署和发布是软件工程中经常互换使用的两个术语,甚至感觉是等价的。然而,它们是不同的! • 部署是将软件从一个受控环境转移到另一个受控环境,它的目的是将软件从开发状态转化为生产状态,使得软件可以为用户提供服务。 • 发布是将软件推向用户的过程,应用程序需要多次更新、安全补丁和代码更改,跨平台和环境部署需要对版本进行适当的管理,有一定的计划性和管控因素。
828 1
|
4月前
|
前端开发 JavaScript
意想不到的前端三个小妙招
意想不到的前端三个小妙招
|
JavaScript 前端开发
基于装饰器——我劝你不要在业务代码上装逼!!!(上)
基于装饰器——我劝你不要在业务代码上装逼!!!(上)
|
设计模式 SQL Java
有点狠有点猛,我用责任链模式重构了业务代码
文章开篇,抛出一个老生常谈的问题,学习设计模式有什么作用? 设计模式主要是为了应对代码的复杂性,让其满足开闭原则,提高代码的扩展性 另外,学习的设计模式 一定要在业务代码中落实,只有理论没有真正实施,是无法真正掌握并且灵活运用设计模式的 这篇文章主要说 责任链设计模式,认识此模式是在读 Mybatis 源码时, Interceptor 拦截器主要使用的就是责任链,当时读过后就留下了很深的印象(内心 OS:还能这样玩)
|
数据安全/隐私保护
分享五款没什么名气却意外好用的软件
噔噔噔噔,作为一个黑科技软件爱好者,电脑里肯定是不会缺少这方面的东西,今天的5款优质软件闪亮登场了。
155 0
分享五款没什么名气却意外好用的软件
|
消息中间件 Kubernetes Cloud Native
记一次内部分享——瞎扯淡
记一次内部分享——瞎扯淡
记一次内部分享——瞎扯淡
|
JSON Java 测试技术
如何写出让人抓狂的代码?
如何写出让人抓狂的代码?
如何写出让人抓狂的代码?