掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流
編程初學者總是把大量的時間用在學習編程語言,語法,技巧和編程工具的使用上。他們認為,如果掌握了這些技術技巧,他們就能成為不錯的程序員。然而,計算機編程的目的并不是關于精通這些技術、工具的,它是關于針對特定領域里的特定問題創(chuàng)造出相應的解決方案,程序員通過相互合作來實現(xiàn)這些。所以,很重要的一點,你需要能精確的用代碼表達出你的思想,讓其他人通過代碼能明白你的意圖。

目前創(chuàng)新互聯(lián)建站已為超過千家的企業(yè)提供了網(wǎng)站建設、域名、網(wǎng)絡空間、網(wǎng)站托管、企業(yè)網(wǎng)站設計、沿灘網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
讓我們先看看編程大師Robert C. Martin的杰作《Clean Code》里的一句話:
“注釋的目的是為了彌補代碼自身在表達上的不足?!?/em>
這句話可以簡單的理解為如果你的代碼需要注釋,最有可能是你的代碼寫的很爛。同樣,如果在沒有注釋的情況下你無法用代碼完整的表達你對一個問題或一個算法的思路,那這就是一個失敗的信號。最終,這意味著你需要用注釋來闡明一部分的思想,而這部分在代碼里是看不出來的。好的代碼能夠讓任何人在不需要任何注釋的情況下看懂。好的編碼風格能將所有有助于理解這個問題的所有信息都蘊含在代碼里。
在編程理論中,有一個概念叫做“自我描述的源代碼”。對于一段代碼,一種常見的自我描述機制是遵循某種非嚴格定義的變量、方法、對象命名規(guī)則。這樣做的主要作用就是使源代碼更易讀易懂。所以,也就更容易維護和擴展。
這篇文章里,我將舉出一些例子,說明什么是“不好的代碼”,什么是“清楚的代碼”
命名要能揭示意圖
如何命名,在編程中這永遠都是個老大難問題。有些程序員喜歡簡化、縮短或加密名稱,使得只有他們自己能懂。下面讓我們看一些例子:
不好的代碼:
- int d;
- // 天數(shù)
- int ds;
- int dsm;
- int faid;
“d”可以表示任何東西。作者使用注釋來表明他的意圖,卻沒有選擇用代碼來表示。而“faid”很容易導致誤解為ID。
清楚的代碼:
- int elapsedTimeInDays;
- int daysSinceCreation;
- int daysSinceModification;
- int fileAgeInDays;
命名時避免含義引起誤解的信息
錯誤的信息比沒有信息更糟糕。有些程序員喜歡“隱藏”一些重要信息,有時候他們也會寫出一些讓人誤解的代碼。
不好的代碼:
- Customer[] customerList;
- Table theTable;
變量“customerList”其實不是個list。它是一個普通的array(或客戶集合)。除此之外,“theTable”是一個Table類型的對象(你可以用IDE容易的發(fā)現(xiàn)它的類型),“the”這個詞是個不必要的干擾。
清楚的代碼:
- Customer[] customers;
- Table customers;
命名要有合適的長度
在高級編程語言中,變量名的長度通常不太限制。變量名幾乎可以任何長度。雖然如此,這也可能使代碼變得鬧心。
不好的代碼:
- var theCustomersListWithAllCustomersIncludedWithoutFilter;
- var list;
好的名稱應該只含有必要的詞匯來表達一個概念。任何不必要的字詞都會使名稱變長、難于理解。名稱越短越好,前提是能在上下文中表達完整的意思(下訂單這個場景中,“customersInOrder” 要比 “l(fā)ist” 好)。
清楚的代碼:
- var allCustomers;
- var customersInOrder;
命名時編碼規(guī)范保持一致,讓規(guī)范幫助理解代碼
所有的編程技術(語言)都有自己的“風格”,叫做編碼規(guī)范。程序員應該在寫代碼時遵循這些習慣,因為其他的程序員也知道這些,并按這種風格編寫。下面我們看一個沒有明顯規(guī)范的不好的代碼例子。下面的這段代碼沒有遵循很好的已知的“編碼規(guī)范”(比如PascalCase, camelCase, Hungarian規(guī)范)。更糟糕的是,這有一個毫無意義的bool變量“change”。這是個動詞(用來描述動作),但這里的bool值是來描述一個狀態(tài),所以,這里應該用一個形容詞更合適。
不好的代碼:
- const int maxcount = 1
- bool change = true
- public interface Repository
- private string NAME
- public class personaddress
- void getallorders()
一段代碼,只看它的一部分,你就應該直接明白它是什么類型,只需要看它的命名方法。
例如:你看到了“_name”,你就能知道它是個私有變量。你應該在任何地方都利用這種表示方法,沒有例外情況。
清楚的代碼:
- const int MAXCOUNT = 1
- bool isChanged = true
- public interface IRepository
- private string _name
- public class PersonAddress
- void GetAllOrders()
命名時相同的概念用相同的詞表達
定義概念很難。在軟件開發(fā)過程中,很多時間都花在分析業(yè)務場景、思考正確的定義里面所有的元素。這些概念永遠都是讓程序員頭痛的事。
不好的代碼:
- //1.
- void LoadSingleData()
- void FetchDataFiltered()
- Void GetAllData()
- //2.
- void SetDataToView();
- void SetObjectValue(int value)
首先:
代碼的作者試圖表達“get the data”的概念,他使用了多個詞“l(fā)oad”,“getch”,“get”。一個概念只用一個詞表達就行了(在同一個場景中)。
第二:
“set”這個詞用在了2個概念里:第一是“data loading to view”,第二個是“setting a value of object”。這是兩個不同的概念,你應該使用不同的詞。
清楚的代碼:
- //1.
- void GetSingleData()
- void GetDataFiltered()
- Void GetAllData()
- //2.
- void LoadDataToView();
- void SetObjectValue(int value)
命名時使用跟業(yè)務領域相關的詞
程序員寫的所有代碼都是跟業(yè)務領域場景邏輯相連的。為了讓所有關系到這個問題的人都能更好的理解,程序中應該使用在領域環(huán)境中有意義的名稱。
不好的代碼:
- public class EntitiesRelation
- {
- Entity o1;
- Entity o2;
- }
當在編寫針對某個領域的代碼時,你應該始終考慮使用領域有聯(lián)系的名稱。在將來,當另外一個人(不僅是程序員,也許是測試人員)接觸你的代碼時,他能輕松的理解這個業(yè)務領域里你的代碼是什么意思(不需要業(yè)務邏輯知識)。你首先考慮的應該是業(yè)務問題,之后才是如何解決。
清楚的代碼:
- public class ProductWithCategory
- {
- Entity product;
- Entity category;
- }
命名時使用在特定環(huán)境里有意義的詞
代碼里名稱都有自己的上下文。上下文對于理解一個名稱非常重要,因為它能提供額外的信息。讓我們來看看一個典型的“地址”上下文:
不好的代碼:
- string addressCity;
- string addressHomeNumber;
- string addressPostCode;
在大多數(shù)情況中,“Post Code”通常是地址的一部分,很顯然,郵政編碼不能單獨使用(除非你是在開發(fā)一個專門處理郵編的應用)。所以,沒有必要在“PostCode”的前面加上“address”。更重要的,所以的這些信息都有一個上下文容環(huán)境,一個命名空間,一個類。
在面向對象編程中,這里應該用一個“Address”類來表達這個地址信息。
清楚的代碼:
- class Address
- {
- string city;
- string homeNumber;
- string postCode;
- }
命名方法總結
概述起來,做為一個程序員,你應該:
英文原文:Express names in code: Bad vs Clean
譯文鏈接:http://www.aqee.net/express-names-in-code-bad-vs-clean/

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流