日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
高質(zhì)量代碼的特征

回想起來(lái),我覺(jué)得我們似乎在誤讀Uncle Bob的Clean Code,至少我們錯(cuò)誤地將所謂Clean與可讀性代碼簡(jiǎn)單地劃上了等號(hào)。尤為不幸的是,在Clean Code一書(shū)中,從第二章到第五章都圍繞著可讀性代碼做文章,于是加深了這種錯(cuò)誤的印象。

專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)巴青免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

許多具有代碼潔癖的程序員將代碼可讀性視為神圣不可侵犯的真理,并奉其為高質(zhì)量代碼的最重要特征,封上了“神壇”。殊不知,Uncle Bob在Clean Code的***章就通過(guò)別人之口對(duì)所謂“Clean Code”進(jìn)行了正名:所謂整潔代碼并非僅僅是“清晰”這么簡(jiǎn)單。

按照Kent Beck的簡(jiǎn)單設(shè)計(jì)規(guī)則,排在***位的其實(shí)不是可讀性,而是“通過(guò)所有測(cè)試”。其中潛藏的含義是滿足用戶正確的需求,因?yàn)闇y(cè)試可以看做是用戶提出的需求。這個(gè)需求不僅僅是業(yè)務(wù)上的,還包括質(zhì)量屬性的需求,例如性能、安全等屬性。

消除重復(fù)和提高表達(dá)力這兩點(diǎn),有時(shí)候會(huì)互相促進(jìn),去除了冗余的代碼,會(huì)讓代碼變得更加清晰;然而,有時(shí)候卻又互相沖突,消除重復(fù)的成本可能會(huì)比較高,導(dǎo)致提取了太多細(xì)碎微小的實(shí)體,反而增加了閱讀障礙。

故而我常常將Uncle Bob提出的“函數(shù)的***規(guī)則是要短小。第二條規(guī)則是還要更短小?!笨醋鍪且环N矯枉過(guò)正的強(qiáng)迫。對(duì)于那種喜歡編寫大函數(shù)的程序員而言,確實(shí)需要時(shí)刻銘記這一原則,但切記不要將其視為***準(zhǔn)則。保證函數(shù)短小是有前提的,仔細(xì)閱讀Kent Beck的簡(jiǎn)單設(shè)計(jì)原則,依其重要順序:

  1. 能通過(guò)所有測(cè)試;
  2. 沒(méi)有重復(fù)代碼;
  3. 體現(xiàn)設(shè)計(jì)者的意圖;
  4. 若無(wú)必要,勿增實(shí)體(方法、函數(shù)、類等)。

如果程序滿足了客戶需求,沒(méi)有重復(fù)代碼,函數(shù)的表達(dá)已經(jīng)足夠清晰地體現(xiàn)設(shè)計(jì)者意圖,為何還要不斷地提取函數(shù),使得函數(shù)變得極為短小呢?真正有意義的原則是“讓函數(shù)只做一件事情”。

正因?yàn)榇?,在Clean Code書(shū)中,Uncle Bob展示的對(duì)FitNesse中HtmlUtil.java的第二次重構(gòu)并無(wú)必要。在經(jīng)過(guò)***次重構(gòu)后,代碼如下所示:

 
 
 
  1. public static String renderPageWithSetupsAndTeardowns(PageData pageData, boolean isSuite) throws Exception { 
  2.     boolean isTestPage = pageData.hasAttribute("Test"); 
  3.     if (isTestPage) { 
  4.         WikiPage testPage = pageData.getWikiPage(); 
  5.         StringBuffer newnewPageContent = new StringBuffer(); 
  6.         includeSetupPages(testPage, newPageContent, isSuite); 
  7.         newPageContent.append(pageData.getContent()); 
  8.         includeTeardownPages(testPage, newPageContent, isSuite); 
  9.         pageData.setContent(newPageContent.toString()); 
  10.     } 
  11.     return pageData.getHtml();} 

這段代碼的結(jié)構(gòu)與層次已經(jīng)非常清晰,也對(duì)實(shí)現(xiàn)細(xì)節(jié)做了足夠合理的封裝與隱藏。若要說(shuō)不足之處,或許可以將如下代碼再做一次方法提取,使其滿足SLAP原則(單一抽象層次原則):

 
 
 
  1. newPageContent.append(pageData.getContent()); 
  2.  
  3. //提取為: 
  4. includeTestContents(testPage, newPageContent) 

而Uncle Bob做的第二次重構(gòu),除了將方法變得更加短小,隱藏了太多細(xì)節(jié)從而引入更多層次之外,究竟給代碼的清晰帶來(lái)了什么呢?

 
 
 
  1. public static String renderPageWithSetupsAndTeardowns(PageData pageData, boolean isSuite) throws Exception { 
  2.     if (isTestPage(pageData)) 
  3.         includeSetupAndTeardownPages(pageData, isSuite); 
  4.     return pageData.getHtml(); 

過(guò)猶不及啊!

有時(shí)候,為了去除重復(fù),就必須要從相似代碼中尋找到一種模式或者某種抽象,進(jìn)而對(duì)其進(jìn)行提取。過(guò)分的提取反而會(huì)讓代碼變得很難閱讀,這是因?yàn)樘崛〉氖侄纬3?huì)引入“間接”。正如Martin Fowler所說(shuō):“間接性可能帶來(lái)幫助,但非必要的間接性總是讓人不舒服”。不必要的間接常常妨礙代碼的直截了當(dāng)和干凈利落。倘若去除重復(fù)帶來(lái)的唯一好處僅僅是避免一個(gè)類中少許的私有重復(fù),去除這樣的重復(fù)其實(shí)意義真的不大。

我喜歡清晰的代碼,但我認(rèn)為保持代碼的正確、健壯與高效同樣重要。

因?yàn)榇a潔癖的緣故,我曾經(jīng)將大量的非空判斷、非法檢查與異常處理視為干擾清晰代碼的洪水猛獸,但如果不做這些“臟活累活”,代碼就可能變得不健壯。在Java中,若真要避免這些判斷,可以考慮轉(zhuǎn)移職責(zé),通過(guò)定義Checked Exception,將異常處理的職責(zé)轉(zhuǎn)移給方法的調(diào)用者。然而,職責(zé)的盲目轉(zhuǎn)移始終是不負(fù)責(zé)任的。實(shí)現(xiàn)每個(gè)方法和每個(gè)類的程序員應(yīng)該保證自己的代碼是自治的。

如下代碼:

 
 
 
  1. @Override 
  2. public void run() { 
  3.    if (isFromFile) { 
  4.         if (hasQuery) { 
  5.             throw new RuntimeException("both --execute and --file specified"); 
  6.         } 
  7.         try { 
  8.             query = Files.toString(new File(clientOptions.file), UTF_8); 
  9.             hasQuery = true; 
  10.         } 
  11.         catch (IOException e) { 
  12.             throw new RuntimeException(format("Error reading from file %s: %s", clientOptions.file, e.getMessage())); 
  13.         } 
  14.     } 
  15. }     

這樣的代碼確實(shí)談不上優(yōu)雅,然而足夠充分的判斷保證了代碼的正確性與健壯性。我只能說(shuō),在滿足了這兩點(diǎn)的前提下,可以聰明地利用諸如防御式編程、Optional來(lái)規(guī)避多余的嵌套或分支,從而提高代碼的可讀性。

Effective Java總結(jié)了高質(zhì)量代碼的幾個(gè)特征:清晰、正確、可用、健壯、靈活和可維護(hù)。我認(rèn)為這一總結(jié)非常中肯。寫代碼真的不要太偏執(zhí),不分任何場(chǎng)景一味地追求代碼的可讀(清晰),一味地重申DRY,我覺(jué)得都是不負(fù)責(zé)任的態(tài)度。

或許是我老了的緣故,我變得不再理想主義;但更多的原因是因?yàn)槲铱吹教嘧非笏^“整潔代碼”的程序,不愿考慮復(fù)雜繁瑣的異外情況從而導(dǎo)致程序的不健壯;因?yàn)槿コ貜?fù)帶來(lái)的不必要間接影響了代碼的簡(jiǎn)潔與干凈,甚至影響了代碼運(yùn)行的性能。

整潔代碼是必須的,但不是衡量代碼質(zhì)量的唯一標(biāo)準(zhǔn)!

【本文為專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】


分享標(biāo)題:高質(zhì)量代碼的特征
網(wǎng)頁(yè)URL:http://www.dlmjj.cn/article/cdhpppp.html