大话JS面向对象之扩展篇 面向对象与面向过程之间的博弈论(OO Vs 过程)------(一个简单的实例引发的沉思)
一,总体概要
1,笔者浅谈
我是从学习Java编程开始接触OOP(面向对象编程),刚开始使用Java编写程序的时候感觉很别扭(面向对象式编程因为引入了类、对象、实例等概念,非常贴合人类对于世间万物的认知方式和思考方式。对于复杂的事物,人类是如何去认识、归纳、总结的?面向对象式编程就是在努力回答这个问题,而答案的核心就是两个字:抽象。所以面向对象式编程特别适合处理业务逻辑,因此被广泛应用于目前的软件开发当中。因为我们开发软件就是为了解决问题,面向对象式编程符合人类对于“问题”的认知方式),因为我早以习惯用C来编写程序(),很欣赏C的简洁性和高效性,喜欢C简练而表达能力丰富的风格,特别忍受不了Java运行起来慢吞吞的速度,相对冗长的代码,而且一个很简单的事情,要写好多类,一个类调用一个类,心里的抵触情绪很强。我对Java的面向对象的特性研究很久,自认为有所领悟,也开始有意识的运用OOP风格来写程序,然而还是经常会觉得不知道应该怎样提炼类,面对一个具体的问题的时候,会觉得脑子里千头万绪的,不知道怎么下手,一不小心,又会回到原来的思路上去。 这里以一个登录,注册的完整例子贯穿全文来说明面向对象与面向过程的方式来循序渐进的进行分析和不断重构来达到我们预期的效果。
2,简单小结
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向对象是将实物高度抽象化。
面向过程是一种自顶向下的编程。
二,案例引入
(1)需求分析
a,只有注册了的用户才可以登录系统。登录系统很简单,只需要提供登录的用户名和密码即可登录系统。
b,未注册的用户可以注册一个用户名,并提供密码和简单的个人信息,比如E-mail地址,即可注册成功。需要注意的是,用户名不能够重复。注册成功的用户即可按照刚才注册的用户名和密码登录系统。
c,注册功能的输入数据项包括用户名、密码、E-mail。
(2)实例讲解,循序渐进
这里以登录的例子作为参考,最初我会这样实现:
1 function login(userName,userPass){ 2 if(!userName || !userPass){ 3 throw new Error("用户名或者密码不能为空!") ; 4 } 5 $.ajax({ 6 url : "/login.json" , 7 type : "post" , 8 data:{ 9 userName : userName , 10 userPass : userPass 11 } , 12 dataType: "json" 13 }).done(function(data){ 14 console.log("登录成功!") ; 15 }) ; 16 } ;
不难看出这是一种面向过程的实现方式,但是里面依然存在设计阶段错误的思维,login它的职能就是登录的作用,可是里面掺加了用户信息的验证工作,显然要分离职责,继续看代码
1 function login(userName,userPass){ 2 if(validate(userName,userPass)){ 3 $.ajax({ 4 url : "/login.json" , 5 type : "post" , 6 data:{ 7 userName : userName , 8 userPass : userPass 9 } , 10 dataType: "json" 11 }).done(function(data){ 12 console.log("登录成功!") ; 13 }) ; 14 } 15 else{ 16 throw new Error("用户名或者密码不能为空!") ; 17 } 18 } ; 19 function validate(userName,userPass){ 20 return (!userName || !userPass) ? false : true ; 21 } ;
这样看上去好多了,最起码设计上是没问题的,但如果再进一步抽象就更好了,看最终的代码
1 function login(userName,userPass){ 2 if(validate(userName,userPass)){ 3 loginService({ 4 userName : userName , 5 userPass : userPass 6 },function(data){ 7 console.log("登录成功!") ; 8 }) ; 9 } 10 else{ 11 throw new Error("用户名或者密码不能为空!") ; 12 } 13 } ; 14 function loginService(params,callback){ 15 $.ajax({ 16 url : "/login.json" , 17 type : "post" , 18 data:{ 19 userName : params.userName , 20 userPass : params.userPass 21 } , 22 dataType: "json" 23 }).done(function(data){ 24 callback(data) ; 25 }) ; 26 } ; 27 function validate(userName,userPass){ 28 return (!userName || !userPass) ? false : true ; 29 } ;
逐步的重构发现比最初的好多了,但依旧是过程化的思维,从机器的角度到现实世界的角度来分析问题的。因此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的出发点来达到满足现实世界的软件需求的目标。 这样的分析方法其实是不适用于Java这样面向对象的编程语言,因为,如果改用C语言,封装两个C函数,都会比Java实现起来轻松的多,逻辑上也清楚的多。 我觉得面向对象的精髓在于考虑问题的思路是从现实世界的人类思维习惯出发的,只要领会了这一点,就领会了面向对象的思维方法。
好的咱们现在用OO的方式去实现那个登录的例子
1,建立User实体模型类
1 function User(userName,userPass,rePass,userMail){ 2 this.userName = userName ; 3 this.userPass = userPass ; 4 this.rePass = rePass ; 5 this.userMail = userMail ; 6 } ; 7 User.prototype = { 8 // set get 9 } ;
2,建立User实体模型中的操作api
1 function User(userName,userPass,rePass,userMail){ 2 this.userName = userName ; 3 this.userPass = userPass ; 4 this.rePass = rePass ; 5 this.userMail = userMail ; 6 } ; 7 User.prototype = { 8 // set get 9 } ; 10 User.getUserByNameAndPwd = function(params){ 11 return $.ajax({ 12 url : "/login.json" , 13 type : "post" , 14 data:{ 15 userName : params.userName , 16 userPass : params.userPass 17 } , 18 dataType: "json" 19 }) ; 20 } ;
3,建立UserManager类
1 function UserManager(user){ 2 this.user = user ; 3 } ; 4 UserManager.prototype = { 5 login : function(){ 6 if(this.validate()){ 7 this.user.getUserByNameAndPwd({ 8 userName : this.user.userName , 9 userPass : this.user.userPass 10 },function(data){ 11 console.log("登录成功!") ; 12 }) ; 13 } 14 else{ 15 throw new Error("用户名或者密码不能为空!") ; 16 } 17 } , 18 validate : function(){ 19 return (!this.user.userName || !this.user.userPass) ? false : true ; 20 } 21 } ;
4,建立客户端测试方法
1 function LoginClient(){ 2 var userMgr = new UserManager(new User("bb","123456")) ; 3 userMgr.login() ; 4 } ;
5,基本这就是OO的完整重构版本了,以下作个小结
通过上面的例子的设计说明,使用面向对象的思维方法,其实是一个把业务逻辑从具体的编程技术当中抽象出来的过程,而这个抽象的过程是自上而下的,非常符合人类的思维习惯,也就是先不考虑问题解决的细节,把问题的最主要的方面抽象成为一个简单的框架,集中精力思考如何解决主要矛盾,然后在解决问题的过程中,再把问题的细节分割成一个一个小问题,再专门去解决细节问题。
因而一旦牢牢的抓住了这一点,你就会发现在软件设计和开发过程中,你自己总是会不知不觉的运用面向对象的思维方法来设计和编写程序,并且程序的设计和开发也变得不再那么枯燥,而一个合理运用面向对象技术进行设计和架构的软件,更是具备了思维的艺术美感。
最后,愿面向对象的思维方法也能给您的程序设计之路带来创作的乐趣。
三,最后的总结一下
1.类的职责不能多,职责多需要分解
2.抽象实体模型
3.理解oo的特质封装,继承,多态
哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步(*^__^*) 嘻嘻……