专栏首页前端加油站由表单提交引伸的对JS设计模式的思考

由表单提交引伸的对JS设计模式的思考

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/j_bleach/article/details/72860322

表单提交

表单提交是业务当中在普通不过的场景了,以QQ登陆页面为例,在注册一个qq账号的话,如果不能填写必填字段,是不会发起http请求的,于是乎我们有了这样一段JS代码。

第一版登陆

class loginCtrl {
    constructor(http, $state) {
        [this.http, this.state, this.name] = [http, $state, 'login'];
        this.islogin = true;
    }

    login() {
        if (!this.param.name)  return alert('用户名不能为空')
        if (!this.param.psw)  return alert('密码不能为空')

        this.http(this.param, url, function () {
            console.log('登陆成功')
        })
    }
}

可以看到,在这段代码中存在一个问题,即在login这个函数当中,存在两个功能,一个是校验是否填写了用户名,密码等信息,另一个是发送http请求,请求登陆。这样做存在明显的弊端,在编写代码中,一个函数对象最好是纯净的,专一的,简单来讲就是一个函数只做一件事。 于是乎,我们把这段验证代码抽离出去。

第二版登陆

class loginCtrl {
    constructor(http, $state) {
        [this.http, this.state, this.name] = [http, $state, 'login'];
        this.param = {};
    }

    validate() {
        if (!this.param.name) {
            alert('用户名不能为空');
            return false
        }

        if (!this.param.psw) {
            alert('密码不能为空');
            return false
        }
        return true
    }

    login() {
        if (!this.validate()) return false
        this.http(this.param, url, function () {
            console.log('登陆成功')
        })
    }
}

于是在第一版的基础上,我们很容易的将验证这段代码抽离出去,进步的地方是,在修改验证函数时,不会直接修改login,但这样依旧没有改掉第一版的诟病,login函数当中依旧引入了验证的函数,本质上是没有变化的,验证与发送http请求依旧耦合着,可能需要多加一段函数将他彻底分离出去。

第三版登陆

class loginCtrl {
    constructor(http, $state) {
        [this.http, this.state, this.name] = [http, $state, 'login'];
        this.param = {};
        this.login = this.preHand(this.login, this.validate);
    }

    preHand(fn, beforeFn) {
        return function () {
            if (!beforeFn.apply(this, arguments)) {
                return false;
            }
            return fn.apply(this,arguments)
        }
    }

    validate() {
        if (!this.param.name) {
            alert('用户名不能为空');
            return false
        }

        if (!this.param.psw) {
            alert('密码不能为空');
            return false
        }
        return true
    }

    login() {
        this.http(this.param, 1, function () {
            console.log('登陆成功')
        })
    }
}

在这一版当中,我们加入了preHand这个函数,这个函数帮助我们分离了验证与发送http请求这两个函数,在进入loginCtrl这个类之后,首先就是重新定义login这个函数,使得login函数运行之前,首先去跑validate这个函数,通过后,再去跑login本身的函数,这样的做法,使得login函数本身不再引用依赖validate函数。但这样的做法还是不够完善,因为登陆这个操作,本身比较简单,如果换成注册呢。

可以看到,此时,需要验证的项目多了很多,而之前的validate函数明显不够用了,所以,为了使得代码能够复用,还要修改。

第四版登陆

这里将validate函数改为

 validate() {
        this.arr = [
            {key: '名字', value: this.param.name},
            {key: '密码', value: this.param.psw}
        ]
        for (let a of this.arr) {
            if (!a.value) {
                alert(`${a.key}不能为空`)
                return false;
            }
        }
        return true;
    }

对JS设计模式的思考

通过这次表达提交,总结一下,在JS设计当中,需要遵循的几个原则。

单一职责原则

单一职责原则,英文名叫做SRP.即,Single responsibility principle 。在js中,函数永远是一等公民,一个函数仅完成一个功能,最后编织我们的js程序。在本例中,一个简单的登陆,可以拆分为校验表单和发送请求。

最少知识原则

最少知识原则要求我们在设计程序时,应当减少对象之间的交互。如果两个对象之间不必彼此直接通信,那么这两个对象就不要发生直接的相互联系。 常见的做法是引入一个第三者对象,来承担这些对象之间的通信作用。在本例中,preHand函数担任了校验与发送请求的中介者。

开放封闭原则

设计的时候,时刻要考虑,尽量让这个函数足够好,写好了就不要去修改了,如果新需求来,我们增加一个函数就完事了,原来的代码能不动则不动。在本例中,如果还有新的需求,进尽量去写新的函数,然后想法设法让他们之间联系起来,而不是直接去修改login或者validate。

以上。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JS设计模式之基于组合模式的code review

    版权声明:本文为博主原创文章,未经博主允许不得转载。 ...

    j_bleach
  • 百度地图自定义marker(图标),layer(覆盖层)

    本文只要涉及的内容有,web中动态引入百度地图,基于百度地图的本地搜索(公交,地铁,停车场),自定义marker,layer,接入微信内置地图(微信中使用第三方...

    j_bleach
  • 基于react的录音及音频曲线绘制的组件开发

    版权声明:本文为博主原创文章,未经博主允许不得转载。 ...

    j_bleach
  • 寿司快卖:实现游戏主流程--制作寿司和客户显示动画特效

    上一节我们搭建了游戏的基本框架。游戏界面被分为若干个板块,其中一个板块显示了各种制作寿司的材料,它的目的是用于玩家根据信息组装各种寿司,本节我们进入游戏的主流程...

    望月从良
  • 分享HTML5-CANVAS相交线动画代码实例

    今天全百科网分享的是HTML5-CANVAS相交线动画代码实例,史基于html、css、js三个方面制作而成,可用于网页背景,效果很是不错。

    于飞云计算
  • Cobalt Strike折腾踩坑填坑记录

    最近在做渗透测试相关的工作,因工作需要准备用Cobalt Strike,老早都知道这款神器,早几年也看过官方的视频教程,但英文水平太渣当时很多都没听懂,出于各种...

    FB客服
  • 聊聊rocketmq的registerProducer与unregisterProducer

    本文主要研究一下rocketmq的registerProducer与unregisterProducer

    codecraft
  • 聊聊rocketmq的registerConsumer与unregisterConsumer

    本文主要研究一下rocketmq的registerConsumer与unregisterConsumer

    codecraft
  • 分享一个微信公众号开发封装类

    仙士可
  • 开发 | 傻瓜式操作带你初始化「跳一跳」游戏场景

    在上一篇教程里,知晓程序为大家详细讲解了如何创建小游戏「跳一跳」的游戏场景。通过介绍,大家一定对于小游戏的开发有了更进一步的认识。

    知晓君

扫码关注云+社区

领取腾讯云代金券