首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >由表单提交引伸的对JS设计模式的思考

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

作者头像
j_bleach
发布2019-07-02 11:23:21
9400
发布2019-07-02 11:23:21
举报
文章被收录于专栏:前端加油站前端加油站

版权声明:本文为博主原创文章,未经博主允许不得转载。 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。

以上。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年06月04日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 表单提交
    • 第一版登陆
      • 第二版登陆
        • 第三版登陆
          • 第四版登陆
          • 对JS设计模式的思考
            • 单一职责原则
              • 最少知识原则
                • 开放封闭原则
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档