由表单提交引伸的对JS设计模式的思考
2017-06-04 17:44
246 查看
表单提交
表单提交是业务当中在普通不过的场景了,以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。以上。
相关文章推荐
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
- Web开发设计模式PRG:Post/Redirect/Get,防止重复提交表单
- Session学习:防止用户重复提交表单(单态设计模式-原子设计模式+MD5技术&Base64算法)
- web 界面设计---js提交表单
- 设计模式与泡mm的关系之Composite组合模式及组合模式的再思考
- 设计模式与泡mm的关系之template method模版方法模式及再思考
- 设计模式与泡mm的关系之strategy策略模式及再思考
- 关于设计模式的几点思考
- 设计模式与泡mm的关系之flyweight享元模式及享元模式的再思考
- 设计模式与泡mm的关系之Mediator中介者模式及再思考
- 设计模式与泡mm的关系之state状态模式及再思考
- 设计模式与泡mm的关系之interpret解释器模式及解释器模式的再思考
- 设计模式与泡mm的关系之Chain of Responsibility职责链模式及再思考
- 设计模式与泡mm的关系之Facade外观模式及外观模式的再思考
- Js表单提交验证
- 设计模式与泡mm的关系之工厂模式及工厂模式的再思考
- 设计模式与泡mm的关系之singleton及singleton的再思考
- 设计模式与泡mm的关系之Proxy代理模式及代理模式的再思考
- 设计模式与泡mm的关系之iterator迭代模式及再思考
- 设计自动获取网页和提交表单组件