1. 面向過(guò)程
面向過(guò)程是一種以事件為中心的編程思想,編程的時(shí)候把解決問(wèn)題的步驟分析出來(lái),然后用函數(shù)把這些步驟實(shí)現(xiàn),在一步一步的具體步驟中再按順序調(diào)用函數(shù)。
舉個(gè)例子,下五子棋,面向過(guò)程的設(shè)計(jì)思路是首先分析解決這個(gè)問(wèn)題的步驟:
(1)開(kāi)始游戲(2)黑子先走(3)繪制畫(huà)面(4)判斷輸贏(5)輪到白子(6)繪制畫(huà)面(7)判斷輸贏(8)返回步驟 (9)輸出最后結(jié)果。
用函數(shù)實(shí)現(xiàn)上面一個(gè)一個(gè)的步驟,然后在下五子棋的主函數(shù)里依次調(diào)用上面的函數(shù)(不同的編程語(yǔ)言有不同的調(diào)用方法,我這里寫的是直接調(diào)用):
下五子棋{開(kāi)始游戲();黑子先走();繪制畫(huà)面();判斷輸贏();輪到白子();繪制畫(huà)面();判斷輸贏();返回到 黑子先走();輸出最后結(jié)果;}
可見(jiàn),面向過(guò)程始終關(guān)注的是怎么一步一步地判斷棋局輸贏的,通過(guò)控制代碼,從而實(shí)現(xiàn)函數(shù)的順序執(zhí)行。
2. 面向?qū)ο?/h3>
在日常生活或編程中,簡(jiǎn)單的問(wèn)題可以用面向過(guò)程的思路來(lái)解決,直接有效,但是當(dāng)問(wèn)題的規(guī)模變得更大時(shí),用面向過(guò)程的思想是遠(yuǎn)遠(yuǎn)不夠的。所以慢慢就出現(xiàn)了面向?qū)ο蟮木幊趟枷?。世界上有很多人和事物,每一個(gè)都可以看做一個(gè)對(duì)象,而每個(gè)對(duì)象都有自己的屬性和行為,對(duì)象與對(duì)象之間通過(guò)方法來(lái)交互。面向?qū)ο笫且环N以“對(duì)象”為中心的編程思想,把要解決的問(wèn)題分解成各個(gè)對(duì)象,建立對(duì)象的目的不是為了完成一個(gè)步驟,而是為了描敘某個(gè)對(duì)象在整個(gè)解決問(wèn)題的步驟中的屬性和行為。
在下五子棋的例子中,用面向?qū)ο蟮姆椒▉?lái)解決的話,首先將整個(gè)五子棋游戲分為三個(gè)對(duì)象:
(1)黑白雙方,這兩方的行為是一樣的。
(2)棋盤系統(tǒng),負(fù)責(zé)繪制畫(huà)面
(3)規(guī)則系統(tǒng),負(fù)責(zé)判定犯規(guī)、輸贏等。
然后賦予每個(gè)對(duì)象一些屬性和行為:
(4)第一類對(duì)象(黑白雙方)負(fù)責(zé)接受用戶輸入,并告知第二類對(duì)象(棋盤系統(tǒng))棋子布局的變化,棋盤系統(tǒng)接收到了棋子的變化,并負(fù)責(zé)在屏幕上面顯示出這種變化,同時(shí)利用第三類對(duì)象(規(guī)則系統(tǒng))來(lái)對(duì)棋局進(jìn)行判定。
可以看出,面向?qū)ο笫且怨δ軄?lái)劃分問(wèn)題,而不是以步驟解決。比如繪制畫(huà)面這個(gè)行為,在面向過(guò)程中是分散在了多個(gè)步驟中的,可能會(huì)出現(xiàn)不同的繪制版本,所以要考慮到實(shí)際情況進(jìn)行各種各樣的簡(jiǎn)化。而面向?qū)ο蟮脑O(shè)計(jì)中,繪圖只可能在棋盤系統(tǒng)這個(gè)對(duì)象中出現(xiàn),從而保證了繪圖的統(tǒng)一。
3、面向?qū)ο蠛兔嫦蜻^(guò)程的區(qū)別
之前在博客上看到這個(gè)比喻,覺(jué)得特別恰當(dāng),挺容易讓人理解的,現(xiàn)在分享一下:
用面向過(guò)程的方法寫出來(lái)的程序是一份蛋炒飯,而用面向?qū)ο髮懗鰜?lái)的程序是一份蓋澆飯。所謂蓋澆飯,北京叫蓋飯,東北叫燴飯,廣東叫碟頭飯,就是在一碗白米飯上面澆上一份蓋菜,你喜歡什么菜,你就澆上什么菜。我覺(jué)得這個(gè)比喻還是比較貼切的。
蛋炒飯制作的細(xì)節(jié),我不太清楚,因?yàn)槲覜](méi)當(dāng)過(guò)廚師,也不會(huì)做飯,但最后的一道工序肯定是把米飯和雞蛋混在一起炒勻。蓋澆飯呢,則是把米飯和蓋菜分別做好,你如果要一份紅燒肉蓋飯呢,就給你澆一份紅燒肉;如果要一份青椒土豆蓋澆飯,就給澆一份青椒土豆絲。
蛋炒飯的好處就是入味均勻,吃起來(lái)香。如果恰巧你不愛(ài)吃雞蛋,只愛(ài)吃青菜的話,那么唯一的辦法就是全部倒掉,重新做一份青菜炒飯了。蓋澆飯就沒(méi)這么多麻煩,你只需要把上面的蓋菜撥掉,更換一份蓋菜就可以了。蓋澆飯的缺點(diǎn)是入味不均,可能沒(méi)有蛋炒飯那么香。
到底是蛋炒飯好還是蓋澆飯好呢?其實(shí)這類問(wèn)題都很難回答,非要比個(gè)上下高低的話,就必須設(shè)定一個(gè)場(chǎng)景,否則只能說(shuō)是各有所長(zhǎng)。如果大家都不是美食家,沒(méi)那么多講究,那么從飯館角度來(lái)講的話,做蓋澆飯顯然比蛋炒飯更有優(yōu)勢(shì),他可以組合出來(lái)任意多的組合,而且不會(huì)浪費(fèi)。
蓋澆飯的好處就是”菜”“飯”分離,從而提高了制作蓋澆飯的靈活性。飯不滿意就換飯,菜不滿意換菜。用軟件工程的專業(yè)術(shù)語(yǔ)就是”可維護(hù)性“比較好,”飯” 和”菜”的耦合度比較低。蛋炒飯將”蛋”“飯”攪和在一起,想換”蛋”“飯”中任何一種都很困難,耦合度很高,以至于”可維護(hù)性”比較差。軟件工程追求的目標(biāo)之一就是可維護(hù)性,可維護(hù)性主要表現(xiàn)在3個(gè)方面:可理解性、可測(cè)試性和可修改性。面向?qū)ο蟮暮锰幹痪褪秋@著的改善了軟件系統(tǒng)的可維護(hù)性。
四、總結(jié)
面向過(guò)程:
優(yōu)點(diǎn):性能比面向?qū)ο蟾?,因?yàn)轭愓{(diào)用時(shí)需要實(shí)例化,開(kāi)銷比較大,比較消耗資源;比如單片機(jī)、嵌入式開(kāi)發(fā)、 Linux/Unix等一般采用面向過(guò)程開(kāi)發(fā),性能是最重要的因素。
缺點(diǎn):沒(méi)有面向?qū)ο笠拙S護(hù)、易復(fù)用、易擴(kuò)展
面向?qū)ο螅?/p>
優(yōu)點(diǎn):易維護(hù)、易復(fù)用、易擴(kuò)展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計(jì)出低耦合的系統(tǒng),使系統(tǒng) 更加靈活、更加易于維護(hù)
缺點(diǎn):性能比面向過(guò)程低