日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【整洁之道】如何写出更整洁的代码(上)

發(fā)布時間:2025/3/14 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【整洁之道】如何写出更整洁的代码(上) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

如何寫出更整潔的代碼

?

?

  代碼整潔之道不是銀彈,不會立竿見影的帶來收益。

  沒有任何犀利的武功招式,只有一些我個人異常推崇的代碼整潔之道的內(nèi)功心法。它不會直接有效的提高你寫代碼的能力與速度,但是對于程序員的整個職業(yè)生涯必然會帶來意想不到的好處。

  如果你還是一個在校學(xué)生,或者是剛工作沒多久的“菜鳥”,那么很有必要接觸一些這方面的知識的。很顯然,它會幫助你更快的適應(yīng)企業(yè)級開發(fā)的要求。

?

1. 為什么需要代碼更整潔?

  在考慮代碼整潔的時候,我們需要明確的一個前提是,這里不討論代碼的對錯。

  關(guān)于什么是整潔的代碼,可能千人千面,但是關(guān)于為什么要寫出整潔的代碼是要達(dá)成共識的。

  如果今天需要出去約會,不管是男生女生一定會將自己梳妝打扮一番吧。如果是周末自己一個人宅在家里呢?可能很多人都是不修邊幅的。這體現(xiàn)了人際交往中很重要的一點(diǎn):當(dāng)需要與別人接觸時,會注重自己的儀容。不管咱們的顏值高低,怎么都還是得捯飭一番不是?對于代碼而言,我們應(yīng)該抱有一樣的要求。如果只是自己寫的好玩的“用后即丟“的代碼,讓它邋遢點(diǎn)其實(shí)也沒什么影響。但是如果是在公司與其他人一起開發(fā)維護(hù)的代碼庫呢?別人會看我們寫的代碼,我們也需要看別人寫的代碼。這樣咱們是不是應(yīng)該也要把自己的代碼好好打扮一下,畢竟代碼就是咱么的面子啊!

?

  想必,對于每一個看過幾本編程方面書籍的人,都看過這么兩個說法:

  1) 代碼是寫給人看的。

  2) 開發(fā)的大部分時間都是在看代碼。

?

  我們可能在看別人的代碼的時候,會在心里情不自禁的飆幾句WTF,以宣泄自己對別人難以理解的代碼的煩躁之情。但與此同時,別人也可能在心里F著咱們的代碼。有感于此,是不是覺得自己應(yīng)該寫出更整潔、更易讀的代碼?讓別人對自己的代碼”無F可說“。

?

  我們需要追求整潔的代碼,但是代碼需要整潔的什么程度呢?抱歉,好像這是一個現(xiàn)階段還沒有被量化的問題。在我看來,是需要找到一個平衡點(diǎn)。對于那些之后再也不會用到的代碼,當(dāng)然就不用花費(fèi)大力氣去追求極致的整潔。而對于那些日常中需要用到的代碼,我想讓它們再怎么整潔也不為過。

?

2. 怎么寫出整潔的代碼?

  以下將是來自于《代碼整潔之道》的方法論。

?

2.1 命名

  需要被命名的有:變量、函數(shù)、參數(shù)、類、包等。

  • 名副其實(shí)。選擇體現(xiàn)本意的名稱能讓人更容易理解和修改代碼。都知道類名用名詞性的詞,函數(shù)名用動詞性的詞。除了這個最基本的要求之外,名字應(yīng)該能體現(xiàn)領(lǐng)域概念。使用表意更準(zhǔn)確的詞匯,而不要用模棱兩可的詞匯增加代碼模糊度。
  • 避免誤導(dǎo)。應(yīng)避免使用與本意相悖的詞。
  • 不要使用不同之處較小的名稱。如?InformationToSet, InformationToSend?,這樣會增加區(qū)分它們的時間成本。此外,在使用IDE的快捷補(bǔ)全功能時,可能會使用相似但錯誤的變量名。如果有兩個類型為?String?的變量,一個為?XYZControlllerForEffcientHandlingOfStrings?另一個為?XYZControllerForEffectientStorageOfStrings?,在使用補(bǔ)全功能時,一不小心就可能使用錯誤的變量名而導(dǎo)致錯誤。
  • 以同樣的方式拼寫同樣的概念。也就是說,同一個概念如果前后使用不一樣的名字,就會產(chǎn)生誤導(dǎo)的反效果。
  • 最應(yīng)該避免的是使用小寫字母l和大寫字母O作為變量名,它們與數(shù)字1和0極難區(qū)分。
  • 做有意義的區(qū)分。
  • 不要使用數(shù)字系列的命名來區(qū)分。對于如下方法簽名 /*該方法簽名需要注釋的幫助來能理解參數(shù) a1, a2 分別表示什么意思*/public static void copyChars(char[] a1, char[] a2);/*方法簽名“自說明”參數(shù)的含義*/public static void copyChars(char[] source, char[] destination);

    說明一個好的名字,對整個方法可讀性的提供。

  • 只要體現(xiàn)有意義的區(qū)分,廢話都是冗余的。對于?getActiveAccount();getActiveAccounts();?這兩個函數(shù)很難通過名字就明白它們之間的區(qū)別。
  • 使用讀得出來的名字。受制于“poor”的英文詞匯,一般很少涉及這點(diǎn)。但毫無疑問,如果在與別人交流代碼的時候,能夠順暢的讀出每個變量、函數(shù)名,無疑會使得整個交流更加的高效集中。
  • 使用可搜索的名字。使用單字母名稱和數(shù)字常量的問題在于,當(dāng)需要全局搜索某個名字的時候,會出現(xiàn)很多的重復(fù)。就好像,如果你在一個文件中全局搜索字母"e",一般會出現(xiàn)很多結(jié)果(某個單詞中間包含的字母也會被搜索到),這樣會模糊我們的搜索結(jié)果。
  • 長名稱勝于短名稱。單字母名稱用于短方法中的本地變量。
  • 名稱長短應(yīng)該與其作用域大小相對應(yīng)。
  • 避免使用編碼。不要把類型或作用域信息編碼進(jìn)名稱里。
  • 每個概念對應(yīng)一個詞。避免將多個單詞用于同一個目的。給每個抽象概念選擇一個詞,并從一而終。例如,在DAO層中查詢數(shù)據(jù)庫時,很多時候會出現(xiàn)?get, query?等表示查詢的詞,對于這種情況項(xiàng)目組內(nèi)應(yīng)該要保持統(tǒng)一。
  • 別用雙關(guān)語。避免將同一個單詞用于不同的目的。代碼作者應(yīng)該盡力寫出易于理解的代碼。
  • 使用解決方案領(lǐng)域名稱。使用在編程領(lǐng)域里大家都認(rèn)同并接受的概念。比如,當(dāng)使用訪問者模式時,在名稱中加上?Visitor?會給熟悉設(shè)計模式的更多的信息。
  • 使用問題領(lǐng)域的名稱。也就是在名字中使用業(yè)務(wù)領(lǐng)域的概念來命名。這些概念都是從你的項(xiàng)目正在解決的問題中提煉出來的。在你的日常開發(fā)交流中會使用到的概念。
  • 添加有意義的語境,不要添加沒有意義的語境。
  •   取名字最難的地方在于需要良好的描技巧和共有的文化背景。一般而言,很難一下就給所有的變量、函數(shù)取一個簡單直接、表意準(zhǔn)確的名字,所以更應(yīng)該的是不斷的重構(gòu)改善它們。隨著對業(yè)務(wù)知識理解的不斷加深,我們會發(fā)現(xiàn)以前起的名字不那么貼切,這個時候應(yīng)該果斷的對其進(jìn)行修改。

    ?

      大概就是像給自己家小孩起名字一樣的態(tài)度對待每個出現(xiàn)在代碼中的名字。

    ?

    2.2 函數(shù)

    ?

      函數(shù)是業(yè)務(wù)邏輯的載體。大部分時候,我們都是在函數(shù)中進(jìn)進(jìn)出出、上上下下、左左右右。這里涉及到了函數(shù)之間的跳轉(zhuǎn)、函數(shù)內(nèi)的導(dǎo)航。對于函數(shù)的編寫,同樣有著一些應(yīng)該遵守的最佳實(shí)踐。

    ?

  • 短小。函數(shù)的第一個規(guī)則就是要短小。短小才精悍,濃縮的都是精華。函數(shù)短小的好處:
  • 對于大部分大腦不是特別發(fā)達(dá)的人,10個10行的函數(shù)可能比一個100行的函數(shù)理解起來更容易。如果給每個“小函數(shù)”能起一個具有說明性的名字,那么整個流程讀下來會更清晰,而且可以增加代碼自解釋的作用。我曾經(jīng)重構(gòu)過一個接近1000行的函數(shù),那絕對是噩夢。
  • 短小的函數(shù)便于在電腦屏中完整的顯示出來,不需要上下去滾動屏幕。
  • 只做一件事。函數(shù)應(yīng)該做好一件事,做好這件事,只做這件事。這個原則(單一職責(zé)原則)表述起來很簡單,但實(shí)際執(zhí)行過程中卻困難重重。難點(diǎn)就在于怎么去區(qū)分“事”。你覺得“吃飯”是一件事嗎?是的,它可以只是一件事。但是如果你要在更低的層次去細(xì)分,你還可以將“吃飯”拆分成“拿碗 -> 打飯 -> 吃飯 -> 洗碗”這些過程。當(dāng)然,這個例子比較牽強(qiáng),但還是可以說明問題的。按不同的粒度可以劃分出不同的結(jié)果。那到底應(yīng)該將一件事“細(xì)分到多細(xì)”呢?需要找到一個平衡。當(dāng)我們將一件事劃分的越細(xì)、粒度越小,那么它的靈活性就越高,復(fù)雜度也越高。反之,則靈活性降低、易用性提高。比如,“棉花”就有較高的靈活性,我們可以用它來制作“棉被、被套、布匹”等,相應(yīng)的它的復(fù)雜度也較高,大部分非專業(yè)技能人士應(yīng)該都不可能將一堆“棉花”加工成一塊“布匹”。與“棉花”相比,“布匹”的層次高一些,高層次也導(dǎo)致了它靈活性的降低,“棉花”可以加工成“棉被”,而“布匹”則不應(yīng)加工成“棉被”了,也就說“布匹”的可能性相比“棉花”更少。此外,從“布匹”加工成一件“衣服”的復(fù)雜度比起從“棉花”到一件“衣服”的復(fù)雜度有了極大的降低。
  • 每個函數(shù)一個抽象層級。讓代碼擁有自頂向下的閱讀順序,讓每個函數(shù)后面跟著位于下一抽象層級的函數(shù)。也就是說,將類中的函數(shù)按照抽象層次的順序放置在文件中,這樣的好處在于可以順暢的從上到下的閱讀整個類。函數(shù)的順序應(yīng)該像小說一樣被精心安排。
  • 函數(shù)中混雜不同抽象層級,往往讓人迷惑。
  • 如果和一群你的“領(lǐng)導(dǎo)”(抽象層級高)的人一起吃飯,你會“不自在”。
  • 如果和一群你的“下屬”(抽象層級低)的人一起吃飯,你會咋樣呢?哪個領(lǐng)導(dǎo)來表達(dá)一下此種情況的心情::-)
  • switch語句。有需要的時候可以利用多態(tài)來優(yōu)化?switch?語句。
  • 使用描述性的名稱。與之前在命名中介紹的一樣,我們需要使用具有描述性的名字。不要害怕長名稱。
  • 使用描述性的名稱能幫助理清模塊的設(shè)計思路,并幫助改進(jìn)它。
  • 命名的方式要保持一致。
  • 函數(shù)越短小、功能越集中,就越便于取名字。在函數(shù)名字中存在 ?and ?時一般體現(xiàn)來了該函數(shù)的職責(zé)不單一。
  • 函數(shù)參數(shù)。
  • 函數(shù)參數(shù)越少越好。
  • 從測試角度來看,參數(shù)越多,就越難寫出能確保各種參數(shù)組合正常運(yùn)行的測試用例。
  • 輸出參數(shù)比輸入?yún)?shù)難以理解。習(xí)慣認(rèn)為信息通過輸入?yún)?shù)傳入函數(shù),通過返回值從函數(shù)中輸出。不太希望信息通過輸入?yún)?shù)傳出。輸出參數(shù),就是將一個對象通過參數(shù)形式傳入一個函數(shù),然后在函數(shù)中對該對象的值進(jìn)行處理,在該函數(shù)外部可以通過該對象的引用使用函數(shù)處理后的值,達(dá)到函數(shù)輸出的效果。
  • 標(biāo)識參數(shù)丑陋不堪。不要向函數(shù)中傳入布爾值。
  • 無副作用。
  • 分割指令與詢問。函數(shù)要么做什么事,要么回答什么事。
  • 函數(shù)應(yīng)該修改某對象的狀態(tài)(指令),或是返回該對象有關(guān)的信息(詢問),兩者都干常會導(dǎo)致混亂。
  • 使用異常替代返回錯誤碼。使用Java的異常系統(tǒng)來處理錯誤,而不是通過自定義的錯誤碼來處理各種異常的情況。
  • ??try / catch?代碼塊搞亂了代碼結(jié)構(gòu),把錯誤流程和正常流程混為一談。最好把 ?try??和 ?catch??代碼塊的主體部分抽離出來,形成函數(shù)。
  • 使用錯誤碼容易形成依賴磁鐵 dependency magnet,依賴磁鐵類會被很多類導(dǎo)入和使用。當(dāng)這個類修改時,所有其他依賴它的類都需要重新編譯和部署。
  • 別重復(fù)自己DRY。
  • 重復(fù)是軟件中一切邪惡的根源。許多原則與實(shí)踐都是為了控制與消除重復(fù)。
  • 存在不同層次的消除重復(fù)。可以將一段語句塊提取為一個函數(shù)來消除重復(fù),可以將一些函數(shù)提取到父類來消除重復(fù),可以將一個模塊提取為公共服務(wù)來消除重復(fù),就像開源屆流行的說法:不要重復(fù)制造車輪。
  • ?

      借助于高級開發(fā)工具的幫助,我們可以方便的在函數(shù)、類之間跳轉(zhuǎn),可以方便在函數(shù)中添加任意的參數(shù),但是如果拋開工具的輔助,那么曾經(jīng)沒有在意的“細(xì)節(jié)”就會形成難以清除的“污垢”,讓人難受。當(dāng)然,我們完全沒有必要拋棄高級的開發(fā)工具,但是如果能在日常工作中就注意并保持代碼中的每一個細(xì)微之處的整潔,難道不是一件很有“工匠精神”的事情嗎?

      大師級程序員把系統(tǒng)當(dāng)作故事來講,而不是當(dāng)作程序來寫。

    ?

    2.3 注釋

    ?

      注釋就是函數(shù)、類的一種輔助說明,就是怕別人不懂自己寫的代碼的意圖,就加上一段說明性的文字。我經(jīng)歷過兩個極端:一個是完全不寫注釋,另一個是每個函數(shù)、類都需要寫上注釋。

      我個人更認(rèn)同的觀點(diǎn)是:如果我們擅長于用語言來表達(dá)意圖,那么就不需要注釋。

      關(guān)于注釋特別要注意的一點(diǎn)是:當(dāng)代碼在變動的時候,注釋并不總是跟著變動的。這樣會導(dǎo)致注釋常常會與它所描述的代碼不同步,并越來越不準(zhǔn)確,甚至可能會起誤導(dǎo)的作用。

    ?

  • 注釋不能美化糟糕的代碼。少量而準(zhǔn)確是注釋比大量而毫無意義的注釋更有用。大量無用的注釋會打亂閱讀代碼時的思路,也會增加滾動屏幕的成本。
  • 用代碼來闡述。盡量使用代碼來闡述它的意圖。這需要給函數(shù)、參數(shù)起恰當(dāng)?shù)拿?#xff0c;函數(shù)層次清晰、邏輯明確。
  • 好注釋。
  • 法律信息。根據(jù)公司要求而定。
  • 提供信息的注釋。
  • 對意圖的解釋。注釋可以提供某個決定背后的故事。
  • 闡釋。注釋可以解釋某些難懂的參數(shù)或返回值的意義。
  • 警示。
  • TODO注釋。TODO大多都是程序員的自我安慰、自欺欺人。
  • 放大。可以用來放大某種不合理之物的重要性。
  • 公共API中的Javadoc
  • 壞注釋。大多數(shù)注釋都屬于此列。
  • 喃喃自語。如果決定寫注釋,那就花點(diǎn)時間確保寫出最好的注釋。
  • 多余的注釋。典型的就是對Bean類中的每個參數(shù)都寫上注釋,比如?name, length?等可以通過名字就判斷意義的字段。
  • 誤導(dǎo)性的注釋。這個最可怕。
  • 循規(guī)蹈矩式的注釋。很多IDE都會自動生成函數(shù)的注釋,其中可能會包含?@param, @return?等信息的說明,大多數(shù)時候可能就是放了一個IDE生成的模板在那里,并沒有任何實(shí)質(zhì)性的內(nèi)容。
  • 日志式注釋。在每次修改時,在模塊開始處添加一條注釋,注明此次的修改變動。這個工作應(yīng)該是Git等版本控制系統(tǒng)該做的事。
  • 廢話注釋。毫無意義的注釋。
  • 能用函數(shù)或變量時就別用注釋。體現(xiàn)了要使名稱更具表達(dá)性,能表達(dá)它自身的意圖。
  • 位置標(biāo)記。#######################################之類的。
  • 括號后面的注釋。通過注釋來表明這個括號與哪個括號是一對的。
  • 歸屬與署名。同樣應(yīng)該是代碼控制系統(tǒng)應(yīng)該做的事。
  • 注釋掉的代碼。
  • 非本地信息。
  • 信息過多。
  • 不明確的聯(lián)系。
  • ?

      注釋應(yīng)該起著輔助的作用,而不應(yīng)該“喧賓奪主”。好的注釋在于提供有用信息、或者方便程序員獲取有用信息。而壞的信息在于冗余,甚至是錯誤,一般它們對提高對系統(tǒng)的認(rèn)識不會提供任何幫助,反而會分散注意力。

    ?

    2.4 格式

    ?

      好的團(tuán)隊(duì),應(yīng)該有一份屬于團(tuán)隊(duì)的編碼規(guī)范。這里面需要定義代碼的格式問題,目的是為了保證團(tuán)隊(duì)的人輸出的代碼就像是一個人寫的。這樣的好處,1)在于減少團(tuán)隊(duì)間相互適應(yīng)不同格式的成本,2)在于提高團(tuán)隊(duì)對外輸出的影響力。

      代碼的格式關(guān)乎溝通。下面是一些格式的最佳實(shí)踐:

  • 垂直格式。
  • 向報紙學(xué)習(xí)。源文件的頂部應(yīng)該給出高層次概念和算法,細(xì)節(jié)應(yīng)該往下逐次展開。
  • 概念間垂直方向上的區(qū)隔。每個空白行都應(yīng)該是一條線索,標(biāo)識出新的獨(dú)立概念。
  • 垂直方向上的靠近。相互靠近的代碼應(yīng)該是緊密相關(guān)的代碼。
  • 垂直距離。
  • 變量聲明。應(yīng)該盡可能的靠近其使用的位置。
  • 實(shí)體變量。應(yīng)該在類的頂部聲明。
  • 相關(guān)函數(shù)。調(diào)用者應(yīng)該盡可能的放在被調(diào)用者的上面。
  • 概念相關(guān)。概念間的相關(guān)性越強(qiáng),彼此之間的距離就應(yīng)該越短。
  • 水平格式。
  • 水平方向上的區(qū)隔與靠近。
  • 在操作符周圍加上空格字符,可以達(dá)到強(qiáng)調(diào)的目的。
  • 不在函數(shù)名和左圓括號之間家空格。
  • 函數(shù)參數(shù)之間用空格隔開。
  • 縮進(jìn)。縮進(jìn)有助于理清代碼的層次結(jié)構(gòu)。  
  • // 風(fēng)格1 if (condition) {statement;}// 風(fēng)格2if (condition){statement;}

      關(guān)于下面的兩個?if?語句塊,你是哪種風(fēng)格?我是風(fēng)格1,曾經(jīng)被人當(dāng)面說風(fēng)格1怎么怎么不好,應(yīng)該使用風(fēng)格2,什么什么的!氣氛一度十分尷尬。
      其實(shí),這也沒什么大驚小怪的,每個程序員都會有自己喜歡的風(fēng)格。但是,在團(tuán)隊(duì)中,那就應(yīng)該形成一致的團(tuán)隊(duì)風(fēng)格。

    3. 總結(jié)

      

      上面介紹了關(guān)于命名、函數(shù)、注釋、格式相關(guān)的一些概念性知識點(diǎn),代碼整潔之道不是銀彈,它只是幫助我們做好代碼層面的小事。如果能夠堅(jiān)持下去,那今天的付出可能就是一只蝴蝶開始扇動了翅膀,可能在未來的某一天帶來意想不到的巨大收貨。拋開這些功利主義的想法,純粹的想要成為一個有著“工匠精神”的程序員也是一件很牛逼的事吧!

    轉(zhuǎn)載于:https://www.cnblogs.com/liujiong/p/7471515.html

    總結(jié)

    以上是生活随笔為你收集整理的【整洁之道】如何写出更整洁的代码(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。