{%hackmd BJzAwtWvp %}

[Clean Code]有意義的命名

讓名稱代表意圖-使之名副其實

  • 變數、函示與類別的名稱,要能解答大部分的問題。他需要告訴你,他為什麼在這出現、他要做甚麼、要怎麼使用他。如果一個名稱還需要註解的輔助,那麼這個名稱就不具備展現意圖的能力。

    以下的範例就看不出這個變數的命名意義為何,還需要一個註解幫他解釋。

    int d; //消逝的天數
    int daysSinceCreatio   int daysSinceCreatio數值4n;
    int daysSinceModification;
  • 我們以一段程式碼作為範例來點出我們需要哪些資訊

    public List<int[]> getThem(){
        List<int[]> list1 = new ArrayList<int[]>();
        for(int[] x : theList){
            if(x[0] == 4){
                list1.add(x);
            }
        }
        return list1;
    }
    1. theList裡存著甚麼東西?
    2. theList裡索引0的項目,代表的意義是甚麼?
    3. 數值4是甚麼意思?
    4. 我該如何使用回傳的列表?

    這些問題都沒有在程式碼中透漏,但它們應該要辦到這件事情。

    我們假設這段程式碼是在編寫踩地雷的遊戲,並把他改寫為如下

    public List<int[]> getFlaggedCells(){
        List<int[]> flaggedCells = new ArrayList<int[]>();
        for(int[] cell : gameBoard){
            if(cell[STATUS_VALUE] == FLAGGED){
                flaggedCells.add(cell);
            }
        }
        return flaggedCells;
    }

    如此一來,此段程式碼的意圖就非常明確。 另外我們還可以透過簡單的類別宣告取代int[],使之更為明確。

    public List<Cell> getFlaggedCells(){
        List<Cell> flaggedCells = new ArrayList<cell>();
        for(Cell cell : gameBoard){
            if(cell.isFlagged){
                flaggedCells.add(cell);
            }
        }
        return flaggedCells;
    }

避免誤導

產生有意義的差別

  • 如 a 及 the
    private String aBook;
    private String theBook;
    這樣的命名方式無法看出兩者的不同。

使用能唸出來的名稱

  • 這裡提供一個範例,以下這個function是做甚麼的,你能看的出來嗎?
    public String genymdhms();
    這個方法是拿來產生年月日時分秒的,但是由這樣的命名方式看起來非常地不直觀。

使用可被搜尋的名字

  • 這樣在debug及察看是否有相同命名的狀況時,可以加快尋找及解決的速度。

不要使用編碼當作命名

  • 編碼已經很多了啦!!不要再出來亂了!!
  • 這樣的命名方式,必須確保所有的觀看成員都能理解這種編碼,但實際上這樣是不可能的。

成員的自首

  • 盡量避免在變數的前面加上如下這種幫助理解的自首
    private object m_info;
    而是利用建立物件或是周全周遭的命名來提升它的可讀性。
    private Member info;

避免思維轉換

類別的命名

  • 類別和物件的命名應該使用名詞或名詞片語來命名,不應該使用動詞

方法的命名

  • 應該使用動詞或動詞片語作為開頭,並盡量依照javaBean的標準(get、set、is)。
  • 當建構子被多載時 這樣寫
    Complex fulcurmPoint = Complex.FromRealNumber(23.0);
    會比這樣寫來的好
    Complex fulcurmPoint = new Complex(23.0);
    因為這樣也可以明確的了解是由甚麼樣的情境下產生這個物件。 也建議可考慮強制將對應的建構子都這為私有的private。

不要裝可愛

private void deleteAccount(String accountId);    X
private coid holyHandGrenade(String accountId);  √

使用同一種字詞

  • 如取得資料時,使用了三種不同的"取得"動詞作為開頭,一方面無法確定功能是否相同,一方面在搜尋時也無法搜出確切需要的資料。
    private String getName();
    private String retrieveName();
    private String fetchName();

添加有意義的上下文資訊

  • 以下這樣的命名你會不知道是甚麼的名字、甚麼的號碼
    private String name;
    private String number;
    但若改為以下這樣便能清楚了解是使用者的名字、使用者的手機號碼。
    prviate String userName;
    private String userMobileNumber
    當然,若是可以為次建立一個物件,那會是更好的解法。

  • 資料來源
    • Clean code 無瑕的程式碼