工程實踐:如何給變量取一個好的名字

在上一篇文章中跟你們分享了關於函數命名的一些實踐心得,今天咱們繼續命名這個話題,來說一講如何對變量命名。html

  如下是本文的目錄大綱:java

  一. 變量命名風格bash

  二. 變量命名最高境界ide

  三. 變量命名最佳實踐函數

  如有不正之處請多多諒解,並歡迎批評指正。優化

  請尊重做者勞動成果,轉載請標明原文連接:this

 https://www.cnblogs.com/dolphin0520/p/10639167.htmlspa

一.變量命名風格

  變量命名風格一般會根據不一樣的變量類型來區分,以Java語言爲例,根據變量類型不一樣有兩種命名風格:代碼規範

1)類成員變量、局部變量code

  類成員變量、局部變量一般採用駝峯命名風格,以下:

String userName;
複製代碼

2)靜態成員變量、枚舉值、常量

  靜態成員變量、枚舉值、常量一般採用全部字母大寫、多個單詞以英文下劃線鏈接,如:

public static final int MAX_YEARS = 25;
​
// 建議枚舉類都以Enum結尾
enum ColorEnum {
    RED(0, "紅色"),
    YELLOW(1, "黃色"),
    GREEN(2, "綠色"),
    WHITE(3, "白色"),
    BLACK(4, "黑色");
    private int code;
    private String name;
​
    Color(int code, String name) {
        this.code = code;
        this.name = name;
    }
}複製代碼

二.變量命名最高境界

  在函數命名那篇中咱們說的函數命名最高境界是見字如面,那麼對於變量命名來講,最高境界是什麼呢? 我認爲是:自解釋,即"代碼即註釋"。

  爲何這麼說呢,由於一般來講一個函數是會有函數註釋的,即便函數名字取的很差,若是註釋寫的比較清楚,對於後續維護人員來講也是瞭解函數具體功能的一種方式。

  而變量則不一樣,在一個工程裏面,變量的數量遠遠大於函數的數量,因此不太可能對於每一個變量都去寫註釋,因此若是一個工程的變量命名很糟糕,那麼對於後續維護人員來講將是毀滅性的打擊,由於每讀到一個變量,可能就須要去猜想變量的含義,我想沒有哪一個人願意讀到這樣的代碼,永遠記住一點:"代碼是寫給人看的,不是寫給機器看的"。

  譬以下面這段代碼的命名就很是糟糕:

ppn = (cpn > 1) ? (cpn - 1) : cpn;
npn = (cpn < tpn) ? (cpn + 1) : tpn;
​
p = new Page(ppn, cpn, npn, tpn);複製代碼

  上面這段代碼估計只有原做者清楚地知道各個變量的含義是啥了,

  若是修改成下面這種寫法,可讀性會好不少,而且一目瞭然,很容易知道其大概意圖是計算分頁信息:

prePageNum = (curPageNum > 1) ? (curPageNum - 1) : curPageNum;
nextPageNum = (curPageNum < totalPageNum) ? (curPageNum + 1) : totalPageNum;
​
page = new Page(prePageNum, curPageNum, nextPageNum, totalPageNum);複製代碼

三.變量命名最佳實踐

1)採用名詞或者形容詞來命名變量

  變量通常狀況下建議使用名詞、名字組合或者形容詞,由於變量通常形容的是一種事物或者事物的屬性,因此用名詞或者名詞組合更容易讓人理解,而形容詞通常用於bool類型的變量。

2)避免使用單字母變量,儘可能細化變量含義

  在程序中,儘可能避免使用單字母變量,惟一能夠接受使用單字母變量的場景只有for循環,不過仍是不太推薦在for循環中使用單字母變量(用pos、index比for循環的i、j、k要好不少)。

  舉個例子,好比下面這行代碼:

double calConeVolume(double b, double d) {
  return Math.PI * b * b * d / 3;
}複製代碼

  咋一看這個函數參數感受挺清晰,可是一細看,b是什麼?d又是什麼?若是我要用這個函數,該怎麼傳參?估計大部人是一臉懵逼狀,只能進去看實際的函數實現才知道b是圓錐體半徑,d是圓錐體高度;

  那麼怎麼優化這段代碼命名呢?其實很簡單,稍微細化一下變量含義,讓變量名本身去表達實際意圖:

double calConeVolume(double radius, double height) {
  return Math.PI * radius * radius * height / 3;
}複製代碼

3)變量命名先後用詞需統一

  在同一個工程或者一個場景下,變量命名風格需先後統一,好比total和sum都能表示總計的意思,那麼全部須要用到"總計"含義的地方要麼所有使用total、要麼所有使用sum。

  保持先後命名風格統一是保證工程代碼良好可讀性的關鍵保證。

4)集合變量用類型或者複數s做爲後綴

  在java中,有不少集合,好比List、Map、Set等,那麼集合變量該怎麼命名呢?

  通常可採起兩種方式:

  • 使用複數s結尾

List<Student> students = new ArrayList<>();
複製代碼

  • 用集合類型做爲後綴

List<Student> studentList = new ArrayList<>();
複製代碼

  上面兩種方式都可,沒有比較明顯的偏好,根據實際場景決定。第一種方式相對更簡潔,第二種在局部做用域裏面有多種相關的集合變量時區分度更大,好比:

List<Student> studentList = new ArrayList<>();
Map<Long, Student> studentMap = Maps.newHashMap();
​
for (Student stu : studentList) {
  studentMap.put(stu.getId, stu);
}複製代碼

  個人建議是若是局部做用域只有一種類型的集合,那麼推薦使用複數形式;若是局部做用域有多個相關的集合類型,那麼推薦用類型結尾。

5)禁止使用is做爲bool類型的類成員變量前置

  在java中,禁止用is做爲bool類型的類成員變量的前綴,由於is做爲前綴會致使序列化/反序列出現問題,阿里的java代碼規範中也明確提到了這一點,因此在寫代碼的時候最好仍是遵照公認的規範,否則哪天說不定就踩坑了。

6)儘可能避免使用縮寫進行命名

  有些時候,變量名可能有點長,不利於代碼可讀性,所以不少時候在寫代碼的時候喜歡用縮寫來命名,但這個不是一個好的習慣,除非使用的縮寫是你們都會使用的約定俗稱的縮寫。

  好比下面這個命名:

int avgStudentAge;
複製代碼

  由於avg你們都知道是average的縮寫,因此這麼寫問題不大,不會引發歧義;

  可是下面這種縮寫命名:

res
tmp
cnt
dep複製代碼

  就不是好的縮寫命名,由於不一樣的人閱讀可能會有不一樣的理解:

res => response、resource、result
tmp => temporary、template
cnt => count、content、context複製代碼

  附上一些約定俗稱的縮寫:

全稱 縮寫
identification id
average avg
maximum max
minimum min
buffer buf
error err
message msg
image img
length len
library lib
password pwd
position pos
data transfer object dto
view object vo

7)拋棄掉flag變量

  國內一些早期的教材上,處處充斥着各類flag風格的變量,這種命名方式對於大型工程簡直就是噩夢,好比:

int flag = getDoctorFlag(doctorId);
if (flag == 1) {
  //....
}複製代碼

  看到這段代碼,讀者會有疑問flag變量的含義是什麼?flag值爲1的時候又表明什麼含義?是醫生的值班/在崗狀態、仍是醫生的身體狀態?估計讀者的心裏是崩潰的。

  若是優化成下面這種形式:

DutyStatus doctorDutyStatus = getDoctorDutyStatus(doctorId);
if (doctorDutyStatus == DutyStatus.ONLINE) {
  // ...
}複製代碼

  就比上面的形式清晰多了,很容易看出來判斷的是醫生的值班/在崗狀態。


博客園連接:https://www.cnblogs.com/dolphin0520/

公衆號:

相關文章
相關標籤/搜索