免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
表達:用好代碼的肢體語言

表達:用好代碼的肢體語言

Spacesoft【暗夜狂沙】

    編程從本質上說是一種表達。實際上,編程的過程就是我們使用一種語言向機器表述一個工作以及其完成的步驟,讓機器來進行的過程。也就是說:軟件開發(fā)看起來似乎應該是一件人和機器溝通的工作,就像那位穿黑衣服戴黑墨鏡的黑客尼奧干的一樣酷。

    但是,我們遇到的項目往往太龐大、太復雜,于是我們每天更多的是在試圖和人交流——寫文檔闡述我們的需求,用注釋描述我們的設計,用圖表表示系統(tǒng)的結構。也就是說:我們每天要為我們的思想維護兩套描述:代碼和文檔。而且我們還必須時時小心,保證它們一致。然而在比較大的項目里,文檔的數(shù)目有時候會多得簡直可怕,而假如這個項目的文檔管理又有點混亂的時候,文檔就變成了災難。

    當用大量文檔作為條條框框保障起來的規(guī)矩把眾人弄得苦不堪言時,革命發(fā)生了。有人喊出了口號:“源代碼就是設計”。是啊,當文檔和注釋作為必要的輔助出現(xiàn)在開發(fā)中時,它們有效的提高了設計的可讀性;而當它們開始喧賓奪主,當工程師們每天有效的工作時間更多的被消耗在不直接產生效益的附件上時,我們就有必要開始反思了。我們之所以不用我們日常的語言來編程,是因為它們有二意性,它們不精確,不易為編譯器所理解。那么我們的設計為什么在用代碼描述之后還要用模糊的自然語言再來做進一步的解釋呢?也許我們的表達方式有問題?

    這篇文章試圖總結一些用代碼來表述設計的技巧,當然我還不打算也沒辦法完全回答剛才提出的問題。這些技巧僅僅包括編碼的方式,所以我稱之為代碼的“肢體語言”,也就是僅僅采用代碼本身,來表述你的設計思路和限制。

一.起個好名字

    一個好名字能夠清晰的描述對象的含義,也可以清晰的描述操作的目的和方式。ctype.h 里面的這個函數(shù)名字就起得很好:

    int isalpha( int c );

    很明確的告知了函數(shù)的意圖。把你代碼里面的

    (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')))這樣的代碼扔掉把,一個isalpha多么清晰的描述了你要做的動作?。?/p>

    各個開發(fā)團隊的代碼規(guī)范往往對命名有比較嚴格的規(guī)定。變量的命名往往使用匈牙利規(guī)則或者與它類似。匈牙利規(guī)則很好的利用前綴,使一個簡單的變量名攜帶了更多的信息。比如 lpszFormat 這樣一個變量,熟悉對應編碼規(guī)范的人會很容易看出來這其實是一個字符數(shù)組指針。于是他就不用跑到變量的聲明處去看它的類型,也不用從上下文推敲,這個變量到底是CString 還是一個char *。遵守代碼規(guī)范也帶來同樣的好處:確實省掉了到處找變量聲明的麻煩。當男生常常起名二狗,女生常常叫做翠花的時候,我們往往可以省去想翠花是男是女的麻煩。

    當然了,起個好名字,最關鍵還是要選個好詞。好詞匯是表達中非常關鍵的東西,這對寫代碼還是寫文章都有效。由于我們開發(fā)的主流還是用的英文編程,建議變量起名還是不要用漢語拼音了。int ShiBuShiZiFu( int c ); 這樣的命名實在是別扭,還是能免則免了,我覺得比英文難懂多了:)

二、利用語言要素描述限制條件

    編程語言為了增強表達能力,往往提供了很多的限定,但是我們常常沒有很好的利用。舉個Delphi 的例子:

function MyExample (const nParamIn: Integer; var nParamOut:Integer): Integer;

這樣的參數(shù)列表就很清晰的告訴了調用者:nParamIn 是輸入用的,nParamOut里面則會返回一個數(shù)據(jù)。

    又比如,C++ 中都有這樣的規(guī)定:一個類中有純虛函數(shù)的話,這個類不能實例化,于是,你可以用這個特點來向基類的使用者表達:“你一定要Overload 這個函數(shù)”這樣的要求。

    斷言也是說明限制的一個好手段。比如我們要實現(xiàn)這樣一個函數(shù):

char *strcpy( char *strDestination, const char *strSource);

我們將把strSource緩沖區(qū)中的字符串拷貝到strDestination里面,怎樣表達“strDestination不能為空指針” 這樣一條限制呢? 

首先想到的辦法是在函數(shù)的開始加一句 if (!strDestination) return NULL; 然而這并不是一個良好的表達。它給調用者傳遞了一個含混的信息:我碰到問題了。至于具體是什么問題呢?就不告訴你?;蛘呖梢赃M一步:用一個全局變量式的方法儲存錯誤信息(就像GetLastError()做的那樣),或者用異常。然而,這也不是一個良好的表達:GetLastError 和異常更加合適的讀者是軟件的最終用戶,而不是程序員。對程序員更友好的方式是在編譯或者調試的時候就能報告出錯誤的所在。于是我們用斷言。一句assert(strDestination); 明確的告知了使用這個函數(shù)的程序員你需要的限制。

三、使用眾人都了解的表達方式

    當一種表達方式為眾人所接受和熟悉的時候,使用它往往可以省很多口舌,比如自然語言中的成語和典故,就往往被用來表述一些原本要長篇大論才能說明白的意思。

    模式(Patterns)就是這樣的一種表達方式。在我看來,一個模式就是總結出一類問題,以及這些問題的經典解決之道,最后給這樣的一套東西起個名稱。于是當這樣的思維方式為眾人所認同的時候,你可以使用模式名稱來指代一些說明起來很麻煩的問題和手段。

    舉個例子。我有一個對象CService,它為另外一個對象CClient 提供一些服務,兩個對象都在本地作通信?,F(xiàn)在需求變了,需要把CMyClient 移到其他機器上,但是我又不想改寫現(xiàn)有的兩個模塊。于是乎,我就寫了一個類來管理CClient 對CService的調用。這樣的設計思想怎么描述?洋洋灑灑寫上那么幾百字的注釋?不用!我把這個類叫做CServiceRemoteProxy 好了。熟悉remote proxy 模式的人一下子就會理解我要作什么了。當然啦,對模式不熟悉的程序員就麻煩了^_^

    所以我覺得,模式對程序員的重要性在于,模式使得程序員的交流有了更多共同語言。于是了解模式就和當初我們在小學里學成語一樣重要了。

    另外一個例子是對公有庫的態(tài)度。很多人對公有的函數(shù)庫、類庫,甚至編譯器都有不信任感,或者本來就文人相輕,覺得用別人的東西不是顯得自己沒水平?于是就自己實現(xiàn)一個自己版本的東西。倘若是為了優(yōu)化或者原來的公有東西有bug, 那也就罷了,據(jù)說有牛人自己從Framework到編譯器自己完全作了一套,有任務的時候完全在自己的環(huán)境里完成,那未免就有走火入魔之嫌了。這樣的代碼完全沒有辦法作交流,也就沒有什么表達的需要,當然不在本文的討論范疇。我覺得若有可能,還是盡量使用公有的東西,大家都熟悉,也就比較容易理解。怕就怕在自己另外作了一套東西,接口相似,偏偏又有不少東西和而不同,特性大相徑庭。這樣旁人閱讀這樣的代碼,就難免覺得郁悶,難免要你寫文檔了。

    比如,我不喜歡string.h 提供的strcpy,于是我就實現(xiàn)了一個自己的版本:

int strcpy( char *strDestination, const char *strSource );

還要給個規(guī)定strcpy 成功返回1,失敗返回-1。完了,這回沒搞頭了,想不寫注釋,這樣的代碼誰看了不糊涂???于是只好老老實實寫注釋。你說這又是何苦捏^0^?

    最后,還是要說明一下,我在這里強調代碼的表達,不是說從此就不再需要注釋和文檔了,有的時候,一小段注釋,說明的效果比什么都好,那么我們又何必吝嗇那一點注釋呢?

    其實,編程就是表達,精妙的表達可以省去很多口舌,也可以部分的把我們從文檔的海洋里解救出來。所以用好代碼的肢體語言吧:)

歡迎訪問作者的個人主頁:替換www.alloysoft.com

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
大講臺說程序員深愛的那些不良編程習慣
怎樣寫好代碼——編程獨家心法
總結了一些值得堅持的編程習慣
以后再也不用面向Google編程了
PEP 8
學編程的人不能不看的好文章(轉) - ::古埃及象形文字::
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服