一,總體概要
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的特質封裝,繼承,多態
哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步(*^__^*) 嘻嘻……