日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 嵌入式微處理器
[導(dǎo)讀] 膾炙人口的詩"春有百花秋有月,夏有涼風(fēng)冬有雪",意境唯美,簡明易懂。好的代碼也是讓人陶醉的,那么如何寫出好的代碼?

信息來源:《編寫可讀代碼的藝術(shù)》,參考:J_Knight、蔡勇等


膾炙人口的詩"春有百花秋有月,夏有涼風(fēng)冬有雪",意境唯美,簡明易懂。好的代碼也是讓人陶醉的,那么如何寫出好的代碼?

高質(zhì)量代碼有三要素:可讀性、可維護(hù)性、可變更性。我們的代碼要一個都不能少地達(dá)到了這三要素的要求才能算高質(zhì)量的代碼。


代碼可讀性的重要性


一提到可讀性似乎有一些老生常談的味道,雖然大家一而再,再而三地強(qiáng)調(diào)可讀性,但我們的代碼在可讀性方面依然做得非常糟糕。由于工作的需要,常常需要去閱讀他人的代碼,維護(hù)他人設(shè)計(jì)的模塊。

很多同行在編寫代碼的時(shí)候往往只關(guān)注一些宏觀上的主題:架構(gòu),設(shè)計(jì)模式,數(shù)據(jù)結(jié)構(gòu)等等,卻忽視了一些更細(xì)節(jié)上的點(diǎn):比如變量如何命名與使用,控制流的設(shè)計(jì),以及注釋的寫法等等。以上這些細(xì)節(jié)上的東西可以用代碼的可讀性來概括。每當(dāng)看到大段大段、密密麻麻的代碼,而且還沒有任何的注釋時(shí)常常感慨不已,深深體會到了這項(xiàng)工作的重要。

由于分工的需要,我們寫的代碼難免需要別人去閱讀和維護(hù)的。而對于許多程序員來說,閱讀和維護(hù)別人的代碼常有的事,而往往在平常很少關(guān)注代碼的可讀性,也對如何提高代碼的可讀性缺乏切身體會。有時(shí)即使為代碼編寫了注釋,也常常是注釋語言晦澀難懂形同天書,令閱讀者反復(fù)斟酌依然不明其意。


對于一個整體的軟件系統(tǒng)而言,既需要宏觀上的架構(gòu)決策,設(shè)計(jì)與指導(dǎo)原則,也必須重視微觀上的代碼細(xì)節(jié)。在過往中,有許多影響深遠(yuǎn)的重大失敗,其根源往往是編碼細(xì)節(jié)出現(xiàn)了疏漏。


不同于宏觀上的架構(gòu),設(shè)計(jì)模式等需要好幾個類,好幾個模塊才能看出來:代碼的可讀性是能夠立刻從微觀上的,一個變量的命名,函數(shù)的邏輯劃分,注釋的信息質(zhì)量里面看出來的。


宏觀層面上的東西固然重要,但是代碼的可讀性也屬于評價(jià)代碼質(zhì)量的一個無法讓人忽視的指標(biāo):它影響了閱讀代碼的成本(畢竟代碼是給人看的),甚至?xí)绊懘a出錯的概率!


對于一個整體的軟件系統(tǒng)而言,既需要宏觀上的架構(gòu)決策,設(shè)計(jì)與指導(dǎo)原則,也必須重視微觀上的代碼細(xì)節(jié)。在軟件歷史中,有許多影響深遠(yuǎn)的重大失敗,其根源往往是編碼細(xì)節(jié)出現(xiàn)了疏漏。所以代碼的可讀性可以作為考量一名程序員專業(yè)程度的指標(biāo)。


怎么理解代碼可讀性


或許已經(jīng)有很多同行也正在努力提高自己代碼的可讀性。然而這里有一個很典型的錯覺是:越少的代碼越容易讓人理解。


但是事實(shí)上,并不是代碼越精簡就越容易讓人理解。相對于追求最小化代碼行數(shù),一個更好的提高可讀性方法是最小化人們理解代碼所需要的時(shí)間。


這就引出了這本中的一個核心定理:


可讀性基本定理:代碼的寫法應(yīng)當(dāng)使別人理解它所需要的時(shí)間最小化。


相對于追求最小化代碼行數(shù),更好的提高可讀性方法是:最小化人們理解代碼所需要的時(shí)間。具體如何讓代碼易于理解?主要體現(xiàn)在下面三個層次:


  • 表層上的改進(jìn):在命名方法(變量名,方法名),變量聲明,代碼格式,注釋等方面的改進(jìn)。

  • 控制流和邏輯的改進(jìn):在控制流,邏輯表達(dá)式上讓代碼變得更容易理解。

  • 結(jié)構(gòu)上的改進(jìn):善于抽取邏輯,借助自然語言的描述來改善代碼。



表層的改進(jìn)


首先來講最簡單的一層如何改進(jìn),涉及到以下幾點(diǎn):


1.如何命名

我們在命名變量、函數(shù)、屬性、類以及包的時(shí)候,應(yīng)當(dāng)仔細(xì)想想,使名稱更加符合相應(yīng)的功能。我們常常在說,設(shè)計(jì)一個系統(tǒng)時(shí)應(yīng)當(dāng)有一個或多個系統(tǒng)分析師對整個系統(tǒng)的包、類以及相關(guān)的函數(shù)和屬性進(jìn)行規(guī)劃,但在通常的項(xiàng)目中這都非常難于做到。對它們的命名更多的還是程序員來完成。但是,在一個項(xiàng)目開始的時(shí)候,應(yīng)當(dāng)對項(xiàng)目的命名出臺一個規(guī)范。譬如,在我的項(xiàng)目中規(guī)定,新增記錄用new或add開頭,更新記錄用edit或mod開頭,刪除用del開頭,查詢用find或query開頭。使用最亂的就是get,因此get開頭的函數(shù)僅僅用于獲取類屬性。


關(guān)鍵思想:把盡可能多的信息裝入名字中。


1.選擇專業(yè)的詞匯,避免泛泛的名字
2.給名字附帶更多信息
3.決定名字最適合的長度
4.名字不能引起歧義


選擇專業(yè)的詞匯,避免泛泛的名字

比如get、query等詞最好是用來做輕量級地取方法的開頭,嚴(yán)禁使用拼音和英文混合的方式,更不允許直接使用中文的方式。


舉個例子:


getPage(url)


通過這個方法名很難判斷出這個方法是從緩存中獲取頁面數(shù)據(jù)還是從網(wǎng)頁中獲取。如果是從網(wǎng)頁中獲取,更專業(yè)的詞應(yīng)該是fetchPage(url)或者downloadPage(url)。


還有一個比較常見的反例:returnValue和retval。這兩者都是“返回值”的意思,他們被濫用在各個有返回值的函數(shù)里面。其實(shí)這兩個次除了攜帶他們本來的意思返回值以外并不具備任何其他的信息,是典型的泛泛的名字。


那么如何選擇一個專業(yè)的詞匯呢?答案是在非常貼近你自己的意圖的基礎(chǔ)上,選擇一個富有表現(xiàn)力的詞匯。


舉幾個例子:


  • 相對于make,選擇create,generate,build等詞匯會更有表現(xiàn)力,更加專業(yè)。

  • 相對于find,選擇search,extract,recover等詞匯會更有表現(xiàn)力,更加專業(yè)。

  • 相對于retval,選擇一個能充分描述這個返回值的性質(zhì)的名字,例如:




var euclidean_norm = function (v){

? ? var retval = 0.0;

? ? for (var i = 0; i < v.length; i += 1;)

? ? ? ?retval += v[i] * v[i];

? ? return Match.sqrt(retval);

}


這里的retval表示的是“平方的和”,因此sum_squares這個詞更加貼切你的意圖,更加專業(yè)。


但是,有些情況下,泛泛的名字也是有意義的,例如一個交換變量的情景:


if (right < left){

? ? tmp = right;

? ? right = left;

? ? left = tmp;

}


像上面這種tmp只是作為一個臨時(shí)存儲的情況下,tmp表達(dá)的意思就比較貼切了。因此,像tmp這個名字,只適用于短期存在而且特性為臨時(shí)性的變量。


給名字附帶更多信息

除了選擇一個專業(yè),貼切意圖的詞匯,我們也可以通過添加一些前后綴來給這個詞附帶更多的信息。這里所指的更多的信息有三種:變量的單位、變量的屬性、變量的格式。


為變量添加單位


有些變量是有單位的,在變量名的后面添加其單位可以讓這個變量名攜帶更多信息:


  • 一個表達(dá)時(shí)間間隔的變量,它的單位是秒:相對于duraction,ducation_secs攜帶了更多的信息

  • 一個表達(dá)內(nèi)存大小的變量,它的單位是mb:相對于size,cache_mb攜帶了更多的信息。


為變量添加重要屬性


有些變量是具有一些非常重要的屬性,其重要程度是不允許使用者忽略的。例如:


  • 一個UTF-8格式的html字節(jié),相對于html,html_utf8更加清楚地描述了這個變量的格式。

  • 一個純文本,需要加密的密碼字符串:相對于password,plaintext_password更清楚地描述了這個變量的特點(diǎn)。


為變量選擇適當(dāng)?shù)母袷?/strong>


對于命名,有些既定的格式需要注意:


  • 使用大駝峰命名來表示類名:HomeViewController。

  • 使用小駝峰命名來表示屬性名:userNameLabel。

  • 使用下劃線連接詞來表示變量名:product_id。

  • 使用kConstantName來表示常量:kCacheDuraction。

  • 使用MACRO_NAME來表示宏:SCREEN_WIDTH。


決定名字最適合的長度

名字越長越難記住,名字越短所持有的信息就越少,如何決定名字的長度呢?總結(jié)有幾個原則:


1.如果變量的作用域很小,可以取很短的名字

2.駝峰命名中的單元不能超過3個
3.不能使用大家不熟悉的縮寫
4.丟掉不必要的單元


如果變量的作用域很小,可以取很短的名字


如果一個變量作用域很?。簞t可以給它取一個很短的名字也無妨。


看下面這個例子:


if(debug){

? ? map <string,int>m;

? ? LookUpNamesNumbers(&m);

? ? Print(m);

}


在這里,變量的類型和使用范圍一眼可見,讀者可以了解這段代碼的所有信息,所以即使是取m這個非常簡短的名字,也不影響讀者來理解作者的意圖。


相反的,如果m是一個全局變量,當(dāng)你看到下面這段代碼就會很頭疼,因?yàn)槟悴恢浪念愋筒⒉幻鞔_:


LookUpNamesNumbers(&m);

Print(m);


駝峰命名中的單元不能超過3個


我們知道駝峰命名可以很清晰地體現(xiàn)變量的含義,但是當(dāng)駝峰命名中的單元超過了3個之后,就會很影響閱讀體驗(yàn):


userFriendsInfoModel


memoryCacheCalculateTool


是不是看上去很吃力?因?yàn)槲覀兇竽X同時(shí)可以記住的信息非常有限,尤其是在看代碼的時(shí)候,這種短期記憶的局限性是無法讓我們同時(shí)記住或者瞬間理解幾個具有3~4個單元的變量名的。所以我們需要在變量名里面去除一些不必要的單元:


丟掉不必要的單元


有些單元在變量里面是可以去掉的,例如:


convertToString可以省略成toString。


不能使用大家不熟悉的縮寫


有些縮寫是大家熟知的:


  • doc 可以代替document

  • str 可以代替string


但是如果你想用BEManager來代替BackEndManager就比較不合適了。因?yàn)椴涣私獾娜藥缀跏菬o法猜到這個名稱的意義的。


所以類似這種情況不能偷懶,該是什么就是什么,否則會起到相反的效果。因?yàn)樗雌饋矸浅D吧?,跟我們熟知的一些縮寫規(guī)則相去甚遠(yuǎn)。


名字不能引起歧義

名字要表達(dá)意思明確,不能讓人看不懂。


例如:


  • filter:過濾這個詞,可以是過濾出符合標(biāo)準(zhǔn)的,也可以是減少不符合標(biāo)準(zhǔn)的:是兩種完全相反的結(jié)果,所以不推薦使用。

  • clip:類似的,到底是在原來的基礎(chǔ)上截掉某一段還是另外截出來某一段呢?同樣也不推薦使用。

  • 布爾值:read_password:是表達(dá)需要讀取密碼,還是已經(jīng)讀了密碼呢?所以最好使用need_password或者is_authenticated來代替比較好。通常來說,給布爾值的變量加上is,has,can,should這樣的詞可以使布爾值表達(dá)的意思更加明確


2.如何聲明與使用變量


開發(fā)過程中我們會聲明很多變量(成員變量,臨時(shí)變量),而我們要知道變量的聲明與使用策略是會對代碼的可讀性造成影響的:

1.變量越多,越難跟蹤它們的動向。
2.變量的作用域越大,就需要跟蹤它們的動向越久。

3.變量改變的越頻繁,就越難跟蹤它的當(dāng)前值。

相對的,對于變量的聲明與使用,我們可以從這四個角度來提高代碼的可讀性:


1.減少變量的個數(shù)

2.縮小變量的作用域
3. 縮短變量聲明與使用其代碼的距離
4. 變量最好只寫一次


沒有價(jià)值的臨時(shí)變量


有些變量的聲明完全是多此一舉,它們的存在反而加大了閱讀代碼的成本:


let now = datetime.datatime.now()

root_message.last_view_time = now? ?


上面這個now變量的存在是毫無意義的,因?yàn)椋?/span>


  • 沒有拆分任何復(fù)雜的表達(dá)式

  • datetime.datatime.now已經(jīng)很清楚地表達(dá)了意思

  • 只使用了一次,因此而沒有壓縮任何冗余的代碼


所以完全不用這個變量也是完全可以的:


root_message.last_view_time = datetime.datatime.now()


表示中間結(jié)果的變量


有的時(shí)候?yàn)榱诉_(dá)成一個目標(biāo),把一件事情分成了兩件事情來做,這兩件事情中間需要一個變量來傳遞結(jié)果。但往往這件事情不需要分成兩件事情來做,這個“中間結(jié)果”也就不需要了:


看一個比較常見的需求,一個把數(shù)組中的某個值移除的例子:


var remove_value = function (array, value_to_remove){

? ? var index_to_remove = null;

? ? for (var i = 0; i < array.length; i+=1){

? ? ? ? if (array[i] === value_to_remove){

? ? ? ? ? ? index_to_remove = i;

? ? ? ? ? ? break;

? ? ? ? }

? ? }

? ? if (index_to_remove !== null){

? ? ? ? array.splice(index_to_remove,1);

? ? }

}?


這里面把這個事情分成了兩件事情來做:


  1. 找出要刪除的元素的序號,保存在變量index_to_remove里面。

  2. 拿到index_to_remove以后使用splice方法刪除它。(這段代碼是JavaScript代碼)


這個例子對于變量的命名還是比較合格的,但實(shí)際上這里所使用的中間結(jié)果變量是完全不需要的,整個過程也不需要分兩個步驟進(jìn)行。來看一下如何一步實(shí)現(xiàn)這個需求:


var remove_value = function (array, value_to_remove){

? ? for (var i = 0; i < array.length; i+=1){

? ? ? ? if (array[i] === value_to_remove){

? ? ? ? ? ? array.splice(i,1);

? ? ? ? ? ? return;

? ? ? ? }

? ? }

}?


上面的方法里面,當(dāng)知道應(yīng)該刪除的元素的序號i的時(shí)候,就直接用它來刪除了應(yīng)該刪除的元素并立即返回。


除了減輕了內(nèi)存和處理器的負(fù)擔(dān)(因?yàn)椴恍枰_辟新的內(nèi)容來存儲結(jié)果變量以及可能不用完全走遍整個的for語句),閱讀代碼的人也會很快領(lǐng)會代碼的意圖。


所以在寫代碼的時(shí)候,如果可以“速戰(zhàn)速決”,就盡量使用最快,最簡潔的方式來實(shí)現(xiàn)目的。


縮小變量的作用域


變量的作用域越廣,就越難追蹤它,值也越難控制,所以我們應(yīng)該讓你的變量對盡量少的代碼可見。


比如類的成員變量就相當(dāng)于一個“小型局部變量”。如果這個類比較龐大,我們就會很難追蹤它,因?yàn)樗蟹椒ǘ伎梢浴半[式”調(diào)用它。所以相反地,如果我們可以把它“降格”為局部變量,就會很容易追蹤它的行蹤:


//成員變量,比較難追蹤

class LargeCass{

? string str_;

??

? void Method1(){

? ? ?str_ = ...;

? ? ?Method2();

? }

??

? void Method2(){

? ? ?//using str_

? }

}


降格:


//局部變量,容易追蹤

class LargeCass{

??

? void Method1(){

? ? ?string str = ...;

? ? ?Method2(str);

? }

??

? void Method2(string str){

? ? ?//using str

? }

}


所以在設(shè)計(jì)類的時(shí)候如果這個數(shù)據(jù)(變量)可以通過方法參數(shù)來傳遞,就不要以成員變量來保存它。


縮短變量聲明與使用其代碼的距離


在實(shí)現(xiàn)一個函數(shù)的時(shí)候,我們可能會聲明比較多的變量,但這些變量的使用位置卻不都是在函數(shù)開頭。


有一個比較不好的習(xí)慣就是無論變量在當(dāng)前函數(shù)的哪個位置使用,都在一開始(函數(shù)的開頭)就聲明了它們。這樣可能導(dǎo)致的問題是:閱讀代碼的人讀到函數(shù)后半部分的時(shí)候就忘記了這個變量的類型和初始值;而且因?yàn)樵诤瘮?shù)的開頭就聲明了好幾個變量,也對閱讀代碼的人的大腦造成了負(fù)擔(dān),因?yàn)槿说亩唐谟洃浭怯邢薜?,特別是記一些暫時(shí)還不知道怎么用的東西。


因此,如果在函數(shù)內(nèi)部需要在不同地方使用幾個不同的變量,建議在真正使用它們之前再聲明它。


變量最好只寫一次


操作一個變量的地方越多,就越難確定它的當(dāng)前值。所以在很多語言里面有其各自的方式讓一些變量不可變(是個常量),比如C++里的const和Java中的final。


3.如何簡化表達(dá)式


有些表達(dá)式比較長,很難讓人馬上理解。這時(shí)候最好可以將其拆分成更容易的幾個小塊??梢試L試下面的幾個方法:

1.使用解釋變量

2.使用總結(jié)變量
3.使用德摩根定理

使用解釋變量

有些變量會從一個比較長的算式得出,這個表達(dá)式可能很難讓人看懂。這時(shí)候就需要用一個簡短的“解釋”變量來詮釋算式的含義。使用一個例子:



其實(shí)上面左側(cè)的表達(dá)式其實(shí)得出的是用戶名,我們可以用userName來替換它:




使用總結(jié)變量

除了以“變量”替換“算式”,還可以用“變量”來替換含有更多變量更復(fù)雜的內(nèi)容,比如條件語句,這時(shí)候該變量可以被稱為"總結(jié)變量"。使用一個例子:



上面這條判斷語句所判斷的是:“用戶id是否相等”。我們可以使用一個總結(jié)性的變量isEqual來替換它:



使用德摩根定理


當(dāng)我們條件語句里面存在外部取反的情況,就可以使用德摩根定理來做個轉(zhuǎn)換。

使用例子:


4.如何讓代碼具有美感


在讀過一些好的源碼之后我有一個感受:好的源碼往往都看上去都很漂亮,很有美感。這里說的漂亮和美感不是指代碼的邏輯清晰有條理,而是指感官上的視覺感受讓人感覺很舒服。這是從一種純粹的審美的角度來評價(jià)代碼的:富有美感的代碼讓人賞心悅目,也容易讓人讀懂。

為了讓代碼更有美感,采取以下實(shí)踐會很有幫助:


1.選擇一個有意義的順序

2.把代碼分成"段落"
3.保持風(fēng)格一致性

4.不要編寫大段的代碼


用換行和列對齊來讓代碼更加整齊


有些時(shí)候,我們可以利用換行和列對齊來讓代碼顯得更加整齊。


換行


換行比較常用在函數(shù)或方法的參數(shù)比較多的時(shí)候。


使用換行:


- (void)requestWithUrl:(NSString*)url?

? ? ? ? ? ? ? ? method:(NSString*)method?

? ? ? ? ? ? ? ? params:(NSDictionary *)params?

? ? ? ? ? ? ? ?success:(SuccessBlock)success?

? ? ? ? ? ? ? ?failure:(FailuireBlock)failure{

? ??

}


不使用換行:


- (void)requestWithUrl:(NSString*)url method:(NSString*)method params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailuireBlock)failure{

? ??

}


通過比較可以看出,如果不使用換行,就很難一眼看清楚都是用了什么參數(shù),而且代碼整體看上去整潔干凈了很多。


列對齊


在聲明一組變量的時(shí)候,由于每個變量名的長度不同,導(dǎo)致了在變量名左側(cè)對齊的情況下,等號以及右側(cè)的內(nèi)容沒有對齊:


NSString *name = userInfo[@"name"];

NSString *sex = userInfo[@"sex"];

NSString *address = userInfo[@"address"];


而如果使用了列對齊的方法,讓等號以及右側(cè)的部分對齊的方式會使代碼看上去更加整潔:


NSString *name? ? = userInfo[@"name"];

NSString *sex? ? ?= userInfo[@"sex"];

NSString *address = userInfo[@"address"];


這二者的區(qū)別在條目數(shù)比較多以及變量名稱長度相差較大的時(shí)候會更加明顯。


選擇一個有意義的順序


當(dāng)涉及到相同變量(屬性)組合的存取都存在的時(shí)候,最好以一個有意義的順序來排列它們:


  • 讓變量的順序與對應(yīng)的HTML表單中<input>字段的順序相匹配

  • 從最重要到最不重要排序

  • 按照字母排序


舉個例子:相同集合里的元素同時(shí)出現(xiàn)的時(shí)候最好保證每個元素出現(xiàn)順序是一致的。除了便于閱讀這個好處以外,也有助于能發(fā)現(xiàn)漏掉的部分,尤其當(dāng)元素很多的時(shí)候:


//給model賦值

model.name ?? = dict["name"];

model.sex ?? ?= dict["sex"];

model.address = dict["address"];


?...

??

//拿到model來繪制UI

nameLabel.text? ? = model.name;

sexLabel.text? ? ?= model.sex;

addressLabel.text = model.address;


把代碼分成"段落"


在寫文章的時(shí)候,為了能讓整個文章看起來結(jié)構(gòu)清晰,我們通常會把大段文字分成一個個小的段落,讓表達(dá)相同主旨的語言湊到一起,與其他主旨的內(nèi)容分隔開來。


而且除了讓讀者明確哪些內(nèi)容是表達(dá)同一主旨之外,把文章分為一個個段落的好處還有便于找到你的閱讀”腳印“,便于段落之間的導(dǎo)航;也可以讓你的閱讀具有一定的節(jié)奏感。


其實(shí)這些道理同樣適用于寫代碼:如果你可以把一個擁有好幾個步驟的大段函數(shù),以空行+注釋的方法將每一個步驟區(qū)分開來,那么則會對讀者理解該函數(shù)的功能有極大的幫助。這樣一來,代碼既能有一定的美感,也具備了可讀性。其實(shí)可讀性又何嘗不是來自于規(guī)則,富有美感的代碼呢?


BigFunction{

??

? ? ?//step1:*****

? ? ?....

? ? ? ?

? ? ?//step2:*****

? ? ?...

? ? ? ??

? ? ?//step3:*****

? ? ?....

??

}


保持風(fēng)格一致性


有些時(shí)候,你的某些代碼風(fēng)格可能與大眾比較容易接受的風(fēng)格不太一樣。但是如果你在你自己所寫的代碼各處能夠保持你這種獨(dú)有的風(fēng)格,也是可以對代碼的可讀性有積極的幫助的。


比如一個比較經(jīng)典的代碼風(fēng)格問題:


if(condition){


}


or:



if(condition)

{


}


對于上面的兩種寫法,每個人對條件判斷右側(cè)的大括號的位置會有不同的看法。但是無論你堅(jiān)持的是哪一個,請?jiān)谀愕拇a里做到始終如一。因?yàn)槿绻心硯讉€特例的話,是非常影響代碼的閱讀體驗(yàn)的。


我們要知道,一個邏輯清晰的代碼也可以因?yàn)榱舭椎牟灰?guī)則,格式不對齊,順序混亂而讓人很難讀懂,這是十分讓人痛心的事情。所以既然你的代碼在命名上,邏輯上已經(jīng)很優(yōu)秀了,就不妨再費(fèi)一點(diǎn)功夫把她打扮的漂漂亮亮的吧!


5.如何寫注釋


注釋是每個項(xiàng)目組都在不斷強(qiáng)調(diào)的,可是依然有許多的代碼沒有任何的注釋。為什么呢?因?yàn)槊總€項(xiàng)目在開發(fā)過程中往往時(shí)間都是非常緊的。在緊張的代碼開發(fā)過程中,注釋往往就漸漸地被忽略了。注釋的目的是盡量幫助讀者了解得和作者一樣多。

在你寫代碼的時(shí)候,在腦海中可能會留下一些代碼里面很難體現(xiàn)出來的部分:這些部分在別人讀你的代碼的時(shí)候可能很難體會到。而這些“不對稱”的信息就是需要通過以注釋的方式來告訴閱讀代碼的人。


控制流和邏輯的改進(jìn)


控制流在編碼中占據(jù)著很重要的位置,它往往代表著一些核心邏輯和算法。因此,如果我們可以讓控制流變得看上去更加“自然”,那么就會對閱讀代碼的人理解這些邏輯甚至是整個系統(tǒng)提供很大的幫助。


那么都有哪相關(guān)實(shí)踐呢?


1.使用符合人類自然語言的表達(dá)習(xí)慣
2.if/else語句塊的順序
3.使用return提前返回

4.代碼不能寫死

5.預(yù)測可能發(fā)生的變化


1.使用符合人類自然語言的表達(dá)習(xí)慣


寫代碼也是一個表達(dá)的過程,雖然表現(xiàn)形式不同,但是如果我們能夠采用符合人類自然語言習(xí)慣的表達(dá)習(xí)慣來寫代碼,對閱讀代碼的人理解我們的代碼是很有幫助的。條件語句中參數(shù)的順序:首先比較一下下面兩段代碼,哪一個更容易讀懂?



大家習(xí)慣上應(yīng)該會覺得code1容易讀懂。還有條件語句中的正負(fù)邏輯:在判斷一些正負(fù)邏輯的時(shí)候,建議使用if(result)而不是if(!result)。


2.if/else語句塊的順序


在寫if/else語句的時(shí)候,可能會有很多不同的互斥情況(好多個else if)。那么這些互斥的情況可以遵循哪些順序呢?

先處理掉簡單的情況,后處理復(fù)雜的情況:這樣有助于閱讀代碼的人循序漸進(jìn)地地理解你的邏輯,而不是一開始就吃掉一個胖子,耗費(fèi)不少精力。

先處理特殊或者可疑的情況,后處理正常的情況:這樣有助于閱讀代碼的人會馬上看到當(dāng)前邏輯的邊界條件以及需要注意的地方。


3.使用return提前返回


在一個函數(shù)或是方法里,可能有一些情況是比較特殊或者極端的,對結(jié)果的產(chǎn)生影響很大(甚至是終止繼續(xù)進(jìn)行)。如果存在這些情況,我們應(yīng)該把他們寫在前面,用return來提前返回(或者返回需要返回的返回值)。

這樣做的好處是可以減少if/else語句的嵌套,也可以明確體現(xiàn)出:“哪些情況是引起異常的”。


4.代碼不能寫死


目的就是能夠使用中提高代碼可維護(hù)性,便于日后的變更。


5.預(yù)測可能發(fā)生的變化


在開發(fā)過程中,如果將一些關(guān)鍵參數(shù)放到配置文件中,可以為軟件部署和使用帶來更多的靈活性。要做到這一點(diǎn),要求我們在軟件設(shè)計(jì)時(shí),應(yīng)當(dāng)有更多的意識,考慮到軟件應(yīng)用中可能發(fā)生的變化。就可能方便部署人員在實(shí)際部署中進(jìn)行靈活變化。然而這樣的配置,必要的注釋說明是非常必要的。軟件可維護(hù)性的另一層意思就是軟件的設(shè)計(jì)便于日后的變更。這一層意思與軟件的可變更性是重合的。所有的軟件設(shè)計(jì)理論的發(fā)展,都是從軟件的可變更性這一要求逐漸展開的,它成為了軟件設(shè)計(jì)理論的核心。


代碼組織的改進(jìn)


關(guān)于代碼組織的改進(jìn),以下三種方法:??? ? ? ? ? ? ? ? ? ? ? ? ?? ?????????????????????????


1.抽取出與程序主要目的“不相關(guān)的子邏輯”

2.重新組織代碼使它一次只做一件事情????????????????????????
3.借助自然語言描述來將想法變成代碼

一個函數(shù)里面往往包含了其主邏輯與子邏輯,我們應(yīng)該積極地發(fā)現(xiàn)并抽取出與主邏輯不相關(guān)的子邏輯。類似于工具方法的函數(shù)其實(shí)是脫離于某個具體的需求的:它可以用在其他的主函數(shù)中,也可以放在其他的項(xiàng)目里面。


結(jié)語


遵循一些簡單的規(guī)定(規(guī)范化指導(dǎo))能使代碼將更容易閱讀(從而進(jìn)一步理解、維護(hù)和擴(kuò)展)。個人認(rèn)為這一點(diǎn)是最重要的,好的程序員都是有強(qiáng)迫癥的,他們會嚴(yán)格要求自己,通過不斷的學(xué)習(xí)來提升自己的技術(shù)最終成為大神級別的程序員。如果不能以高標(biāo)準(zhǔn)來要求自己,即使看再多的如何寫出高質(zhì)量代碼,懂再多的代碼規(guī)范,也是沒有用,最終還是會寫出低質(zhì)量代碼。但是,提高自我要求是一種改變,一般來說,改變都不是一蹴而就的,需要一步一步來。所以,改變最好從小事做起,慢慢積累,最終蛻變。先從代碼規(guī)范開始,熟悉代碼規(guī)范,遵循規(guī)范寫代碼,直到成為習(xí)慣,然后再學(xué)習(xí)其它方法,最終寫出高質(zhì)量代碼,讓我們一起堅(jiān)持,且一起行動。


-END-


嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀

深圳2026年3月19日 /美通社/ -- 2026年的招聘市場,正陷入一場奇特的"算法互博":求職者用AI美化簡歷以通過篩選,企業(yè)用AI深挖細(xì)節(jié)以識別真?zhèn)?。這場博弈的背后,是簡歷日益"豐滿...

關(guān)鍵字: AI 代碼 LAB 模型

美國舊金山和中國蘇州2026年2月8日 /美通社/ -- 信達(dá)生物制藥集團(tuán)(香港聯(lián)交所股票代碼:01801),一家致力于研發(fā)、生產(chǎn)和銷售腫瘤、自身免疫、代謝、眼科等重大疾病領(lǐng)域創(chuàng)新藥物的生物制藥公司,宣布與禮來制藥達(dá)成戰(zhàn)...

關(guān)鍵字: COM 代碼 創(chuàng)始人 控制

香港2026年2月4日 /美通社/ -- 華欽科技集團(tuán)(納斯達(dá)克代碼:CLPS,以下簡稱"華欽科技"或"集團(tuán)")今日宣布其董事會已通過一項(xiàng)集團(tuán)股份回購計(jì)劃的決議。該決議聲明,當(dāng)集團(tuán)股價(jià)低于每股2美元時(shí),集團(tuán)可在公開市場上...

關(guān)鍵字: PS BSP 代碼 納斯達(dá)克

香港2025年12月11日 /美通社/ -- 諾亞控股有限公司(Noah Holdings Limited,以下簡稱"諾亞"或"公司",紐交所代碼:NOAH,港交所代碼:6686)...

關(guān)鍵字: AI 代碼 AN 操作系統(tǒng)

弗吉尼亞州阿什本2025年12月10日 /美通社/ -- 企業(yè)技術(shù)與創(chuàng)新領(lǐng)域的領(lǐng)先合作伙伴DXC Technology(紐約證券交易所代碼:DXC)今日宣布推出AdvisoryX,這是一支旨在幫助企業(yè)應(yīng)對最復(fù)雜的戰(zhàn)略、運(yùn)...

關(guān)鍵字: ADVISOR AI TECHNOLOGY 代碼

新加坡2025年12月8日 /美通社/ -- 近日,51Talk在線教育集團(tuán)("51Talk"或"公司")(紐約證券交易所美國股票代碼:COE)公布了其截至2025年9月...

關(guān)鍵字: BSP 代碼 創(chuàng)始人 新加坡

北京2025年12月2日 /美通社/ -- 亞馬遜云科技在2025 re:Invent全球大會上,宣布為Amazon Transform推出全新的Agent功能,以快速推進(jìn)代碼和應(yīng)用現(xiàn)代化,助力客戶更快消除技術(shù)債務(wù),將更...

關(guān)鍵字: 亞馬遜 代碼 TRANSFORM AGENT

蘇州2025年11月10日 /美通社/ -- 在11月8日舉行的天準(zhǔn)科技股份有限公司(股票代碼:688003)成立二十周年峰會上,一項(xiàng)承載深遠(yuǎn)意義的公益計(jì)劃——"美道基金"正式發(fā)布。香港科技大學(xué)校董會...

關(guān)鍵字: AI 人工智能 代碼 智能化

模塊化是一種將復(fù)雜系統(tǒng)分解為獨(dú)立、可管理單元的軟件開發(fā)方法。在前端開發(fā)中,模塊化指的是將JavaScript代碼、樣式、模板等資源組織成獨(dú)立的功能單元。

關(guān)鍵字: 模塊化 代碼

香港2025年10月10日 /美通社/ -- 華欽科技集團(tuán)公司(納斯達(dá)克代碼:CLPS,以下簡稱"華欽科技")今日宣布將于下周五2025年10月17日開盤前發(fā)布2025財(cái)年下半年及全年財(cái)報(bào)。 華欽科技集團(tuán)公司簡介 華...

關(guān)鍵字: PS BSP 代碼 COM
關(guān)閉