莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          漂亮的代碼

          Posted on 2008-10-09 23:58 dennis 閱讀(3078) 評論(4)  編輯  收藏 所屬分類: 涂鴉計算機(jī)科學(xué)與基礎(chǔ)
              Ruby的創(chuàng)造者為《代碼之美》撰寫的文章標(biāo)題是《代碼如散文》。程序和散文有一些共性,首先是兩者都必須有清晰的意圖,散文內(nèi)容是什么,想表達(dá)什么,程序的功能是什么,能做什么;其次兩者在意圖的表達(dá)上(功能的實(shí)現(xiàn)上)都依賴于寫作的具體風(fēng)格,編程的隱喻之一就是寫作。你想表達(dá)的思想是好的,但是如果表達(dá)得難以理解,那么要把這個思想傳播給讀者將非常困難。代碼被讀和修改的次數(shù)是相當(dāng)多的,因此一個很重要的觀點(diǎn)就是你寫的代碼是給人讀的,你需要考慮可讀性的問題,歸結(jié)于寫出漂亮的代碼。
             判斷代碼是否漂亮似乎沒有什么國家標(biāo)準(zhǔn),更沒有國家免檢。代碼是寫給人讀的,從這個角度上看,如果一段代碼能讓人很容易地讀懂,讓人感覺心情愉快,修改起來也不費(fèi)什么力氣,這似乎就是漂亮的代碼咯。那么顯然,漂亮的代碼的真正含義是幫助程序員感到快樂和提高生產(chǎn)率。有了這個指導(dǎo)性的方向,你可以從這么幾個方面去努力寫出漂亮的代碼:簡潔性、保守性、簡單性、靈活性和平衡。
             簡潔性,文中以Ruby和Java版本的Hello World入手比較,在Ruby和其他動態(tài)語言中,你所做的就是你想表達(dá)的:打印Hello World
          print "Hello World\n"
          換成java,哦,你先要定義一個類,這個類有個入口main方法,在main方法中調(diào)用System.out對象的println方法打印:
          class Sample{
             
          public static void main(String []args){
               System.out.println(
          "Hello World");
             }
          }
          我記的我初學(xué)java的時候就特別不理解為什么要定義一個類,為什么方法要static、args,而我僅僅想要的只是打印一個字符串,可語言硬塞給了我太多的概念:類、方法、入口、參數(shù)。這些額外的東西牽扯了太多的注意力,而往往卻忘記了初衷是什么。因此在《unix編程藝術(shù)》一書中對OO的一個評價是:鼓勵具有厚重的膠合和復(fù)雜層次的體系,大大降低了代碼的簡潔性和透明性,你無法一眼看出代碼是想做什么的。OO的抽象能力很強(qiáng)大,因此在很多場景下是這種抽象能力的濫用,實(shí)現(xiàn)最簡單的功能也是一定要有類,有類才有對象,有對象才有光:)而往往這些對象卻非問題領(lǐng)域中的自然實(shí)體,而是某種膠合物,為了抽象而抽象。
             簡潔同樣意味著消除冗余。代碼的重復(fù)是萬惡之源,拷貝黏貼是滋生bug的溫床,在重構(gòu)概念如此深入人心的今天,這一點(diǎn)毋庸置疑。因此,謹(jǐn)記請DRY原則。語言級別的冗余可能是需要的,例如Ruby允許方法調(diào)用省略括號:
          task :name=>:test
          task({:name
          =>:test})

          這兩行代碼想表達(dá)的意思一樣,顯然第一種方式更簡潔,這種語言級別的冗余顯然是有利于程序員的,盡管將實(shí)現(xiàn)的難度推給了語言的設(shè)計和實(shí)現(xiàn)者。
             漂亮代碼另一個有爭議的方面就是它的熟悉性,人們對于新東西的接受程度遠(yuǎn)沒有想象中的高,大家都喜歡自己熟悉的東西而非全新的思考方式(嗯,極客例外)。這其實(shí)是Ruby一直鼓吹的最小驚奇原則的另一種表達(dá)。Ruby看來就是這么個保守的語言,他有很強(qiáng)大的OO能力,但是沒有全然照搬smalltalk,他有FP的能力但是卻沒有讓你驚掉下巴,他仍然遵循著古老的順序、循環(huán)、選擇的程序結(jié)構(gòu)。
             簡單性強(qiáng)調(diào)是減輕程序員的工作負(fù)擔(dān),語言和類庫API的優(yōu)化應(yīng)當(dāng)有利于使用者,將困難留給實(shí)現(xiàn)者。前面提到的語言的冗余性就是一例。程序的復(fù)雜性來源有這么幾個:商業(yè)上基于推銷熱點(diǎn)而非實(shí)際需求考慮出發(fā)帶來的“特性清單”、業(yè)務(wù)領(lǐng)域本身的復(fù)雜度、程序員的自傲心理,最根本在于軟件的開發(fā)的復(fù)雜性。如果能將復(fù)雜的功能,用人人理解的簡單代碼表達(dá)出來,當(dāng)然漂亮!
             簡單并不意味著簡陋,保守也不意味著死板。靈活性同樣是代碼漂亮與否的判斷標(biāo)準(zhǔn),是否隔離了變化點(diǎn),是否擁有一定的擴(kuò)展能力,是否無需借助工具的增強(qiáng)而實(shí)現(xiàn)某些巧妙的調(diào)用。同樣以Ruby為例,open class和元編程給了內(nèi)置你在語言級別的“工具”,你無需借助antlr、cglib等等類庫去做一些看似復(fù)雜的東西。你將感受到編程的快樂,而非為了工具而去做一些違背本意的事情。靈活性可能是把雙刃劍,過分的強(qiáng)調(diào)靈活性、可擴(kuò)展性也可能帶來復(fù)雜的代碼,注意你的“炫耀”心理。
             最后要強(qiáng)調(diào)的是平衡,在這些因素之間做出平衡,我覺的吧,沒有更多實(shí)踐的經(jīng)驗(yàn)想平衡這些因素是相當(dāng)困難的,如果了解了平衡的藝術(shù),也許算是透出那么點(diǎn)“編程的藝術(shù)”的味道。Matz一直強(qiáng)調(diào)的一點(diǎn)是編程的樂趣,如果沒有樂趣,我想我不會干這行,如果沒有樂趣,我想我的工作效率將極度低下,從你認(rèn)為是枯燥的工作中找樂子,存了這么個心理,你總能找出很多可以做的有趣事情,問題在于,你肯不肯做?

          ps.加張圖片,俺的blog國家免檢

            


          評論

          # re: 漂亮的代碼  回復(fù)  更多評論   

          2008-10-10 08:33 by Jack.Wang
          說的不錯!

          # re: 漂亮的代碼  回復(fù)  更多評論   

          2008-10-10 08:50 by yeshucheng
          哥們,太喜歡看你的BLOG。夠務(wù)實(shí),夠扎實(shí)!

          # re: 漂亮的代碼[未登錄]  回復(fù)  更多評論   

          2008-10-10 09:14 by Leon
          Hello world那個例子舉得太好了,深得我心啊!
          當(dāng)初剛接觸Java的時候也是被這個搞得一頭霧水,頓時覺得OO的世界如此之可怕-_-

          不過話又說回來了,在樂趣和秩序之間,究竟有沒有平衡點(diǎn)?我覺得Ruby/Rails的項(xiàng)目一旦規(guī)模上去之后,協(xié)作是個大問題,可以參見hideto的帖子:
          http://www.javaeye.com/topic/233800

          不知道Dennis怎么認(rèn)為?


          # re: 漂亮的代碼  回復(fù)  更多評論   

          2008-10-10 12:35 by dennis
          @yeshucheng
          過獎,謝謝關(guān)注
          @Leon
          盡管Ruby可以many way to do one thing,但總體上講,仍然是有一些慣用法的。我認(rèn)為可以在團(tuán)隊(duì)內(nèi)部開展這種慣用法培訓(xùn),讓大家都上去講,就幾種寫法發(fā)布看法,這不僅僅是交流的需要,也講促進(jìn)知識的共享,長期下去,我相信團(tuán)隊(duì)的代碼風(fēng)格可以趨同
          主站蜘蛛池模板: 姜堰市| 梓潼县| 浮山县| 黔东| 方正县| 平昌县| 邵武市| 河西区| 宁波市| 寿宁县| 阜新市| 南昌市| 定襄县| 怀远县| 饶平县| 钟祥市| 扶沟县| 普陀区| 图们市| 明光市| 日喀则市| 大渡口区| 龙里县| 阜阳市| 昆明市| 醴陵市| 松江区| 岳池县| 抚宁县| 水富县| 铁力市| 南溪县| 通渭县| 鹤岗市| 湘潭县| 赤壁市| 安宁市| 曲松县| 上思县| 剑川县| 锦屏县|