2016-08-25 64 views
10

我有一個方法將處理作爲參數傳入的Collection<Nodes>。這Collection將被修改,因此我認爲這將是很好的第一個複製它。如何命名參數和局部變量,例如nodes在下面的例子中?如何命名作爲參數副本的變量?

List<Nodes> process(Collection<Nodes> nodes) { 
    List<Nodes> nodes2 = new ArrayList<>(nodes); 
    ... 
} 

作爲另一個實例,考慮下面的其中變量是從String參數解析的int

public void processUser(final String userId) { 
    final int userId2 = Integer.parseInt(userId); 
    ... 
+2

前綴怎麼樣? node2除了nodeCpy之外沒有其他說法,例如。你還需要這個副本嗎?如果你真的需要它,只需複製收藏。否則,它是未使用的代碼。 – sascha10000

+1

我很確定沒有參數副本的命名約定。我也會使用'nodeCpy'作爲@sascha10000建議。 – ArcticLord

+2

基於意見的完美純度。但是,由於代碼的讀者可能會主要關注方法體,所以我會選擇邏輯名來理解* copy *中的代碼。假設像我的汽車列表這樣的概念,我會去參數名稱,如myCarsIn,myCarsParm,myCarsImmutable,並命名複製myCars。 (並且BTW:名稱「節點」對讀者沒有幫助 - 是否沒有這些節點共享的邏輯概念?) – mtj

回答

5

名稱變量問題的一個好方法是使用名稱來表示變量的實際含義。在你的例子中,你使用的名稱沒有說方法功能或變量的含義,這就是爲什麼很難選擇一個名稱。

在很多情況下,例如JDK中的你, Arrays#copyOf

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { 
    @SuppressWarnings("unchecked") 
    T[] copy = ((Object)newType == (Object)Object[].class) 
     ? (T[]) new Object[newLength] 
     : (T[]) Array.newInstance(newType.getComponentType(), newLength); 
    System.arraycopy(original, 0, copy, 0, 
        Math.min(original.length, newLength)); 
    return copy; 
} 

在這種情況下,他們稱之爲參數original和局部變量copy其完美表達了返回的值是參數的副本。確切地說,複製是這種方法的作用,並且相應地命名。

使用同樣的道理對於你的情況(考慮重構提供更多有意義的名稱,以你的方法和變量),我會說出當地的nodes東西拷貝像processedNodes,表示該變量是什麼,要與你的方法的一致名稱。

編輯:

你在編輯中添加不提供有關它做什麼要麼提示新方法的名稱。我會假設它修改了id通過參數傳遞的用戶的某些屬性(可能在數據庫中)。

如果是這種情況(或類似情況),我認爲您可以應用的適當方法是每種方法都應該承擔一項責任。根據你方法的名稱,它應該處理用戶,因爲你需要一個int userId。解析String userId的責任應該超出此方法的範圍。

使用所提出的方法有(其中包括)以下優點:如果你有額外的驗證添加到您的輸入

  • 你的類將不會改變。

  • 您的課程將不負責處理NumberFormatException,這是必須承擔的應用責任。

  • 如果您必須處理不同類型的輸入(例如float userId),則您的processUser方法不會更改。

1

可以肯定這取決於實際的上下文。我不會使用其他編程語言的方法,例如_這很適合命名bash腳本,IMO my也不是一個好的選擇 - 它看起來像是從教程中複製的一段代碼(至少在Java中)。

最簡單的辦法就是名字的方法參數nodesParamnodesBackup,然後你可以簡單地用nodes去作爲副本或者更具體一些,你可以叫它nodesCopy

無論如何,你的方法process有一些任務要做,也許它不是複製節點列表的最佳位置。你可以在你調用方法的地方複製,那麼你可以簡單地使用nodes作爲對象的名稱:

List<Nodes> process(Collection<Nodes> nodes) { 
    // do amazing things here 
    // ... 
} 

// ... 
process(new ArrayList<>(nodes)) 
// ... 

只是我的猜測,你有一個集合,你想保持原來的版本和修改副本,也許真正的解決方案是使用java.util.stream.Stream

+0

「您可以在調用方法的地方複製副本,然後您可以簡單地使用節點作爲你的對象的名字:「我認爲這是一個可怕的想法。每個調用者必須知道他需要製作一份副本。不好的做法。 – Roland

+1

@Roland這就是爲什麼我把它放在「無論如何」部分;)我認爲你的解決方案是函數式編程,然後你從輸入數組開始,經過幾次操作後,你最終得到你想要的和你的原始數組不變。 – ruhungry

2

這取決於你要用局部變量做什麼。

例如在第一個例子中,似乎變量nodes2實際上可能是最後返回的值。那麼我的建議就是簡單地稱之爲resultoutput

在第二個例子中...不太清楚你想達到什麼......我想userIdAsInt應該適用於本地。然而,如果在這裏總是要求int,並且您仍然希望將該參數保留爲字符串(也許您希望將該驗證推出該方法),我認爲將局部變量userId和參數userIdAsStringuserIdString這暗示String雖然在這裏被接受,但不是用戶ID的典型代表,其是int

3

我曾經給過名字,反映並強調了主要的東西。因此,一個潛在的讀者(包括幾個月後的我自己)可以立即得到,只是通過簽名來完成該方法。

在討論該API接收輸入,做一些處理並返回輸出。這是這裏的三大主要事情。

如果不是重要的,什麼樣的處理做的,什麼是輸入的類型,最通用的是這種形式:

List<Nodes> process(Collection<Nodes> input) { 
    List<Nodes> output = new ArrayList<>(input); 
    ... 
} 

public void process(final String input) { 
    final int output = Integer.parseInt(input); 
    ... 

如果是重要的是提供有關處理和輸入類型的更多信息,名稱如:processCollection,inputCollectionprocessUserinputUserId是比較合適的,但局部變量仍然是輸出 - 它是明確的,自我解釋名稱:

List<Nodes> processCollection(Collection<Nodes> inputCollection) { 
    List<Nodes> output = new ArrayList<>(inputCollection); 
    ... 
} 

public void processUser(final String inputUserId) { 
    final int output = Integer.parseInt(inputUserId); 
    ... 

這取決於使用的情況下,有時它是更加合適的詳細說明處理,這是做:asArrayasFilteredArray etc,而不是processCollection

有人可能更喜歡源目的地術語的輸入輸出 - 我看不出它們之間的主要區別。如果這能夠用它的標題告訴方法故事,那就夠好了。

5

它最終歸結爲你想與未來的程序員溝通。電腦顯然不在乎;這是其他人在跟你說話。所以,最大的因素將是什麼樣的人需要知道:

  • 什麼是邏輯(抽象的概念)意味着這個變量的
  • 這個變量如何使用可能會讓程序員感到困惑?
  • 這個變量最重要的是什麼?

看看你的第一個例子,很難理解你的程序真正選擇一個好名字。該方法被稱爲process;但是一般來說,方法實現了計算過程,所以這個名字根本不會告訴我什麼。你在處理什麼?過程是什麼?你是誰處理它,爲什麼?知道該方法的作用以及它所在的類將有助於通知變量名稱。

讓我們添加一些假設。假設您正在構建一個在建築物中定位Wi-Fi接入點的應用程序。所討論的Node是無線節點,其子類爲Repeater,AccessPointClient。我們還要說這是一個在線處理的數據集,因此,爲了響應後臺線程接收當前可見節點的更新,給定節點的集合可能隨時發生更改。您在該方法的頭部複製集合的原因是在本地處理期間將自己與這些更改分開。最後,讓我們假設你的方法是通過ping時間排序節點(解釋爲什麼該方法採用通用的Collection,但返回更具體的List類型)。

現在我們更好地瞭解您的系統,讓我們使用這種理解來選擇一些名進行通信的系統的邏輯意向未來開發商:

class NetworkScanner { 
    List<Node> sortByPingTime(Collection<Node> networkNodes) { 
     final ArrayList<Node> unsortedSnapshot; 

     synchronized(networkNodes) { 
      unsortedSnapshot = new ArrayList<>(networkNodes); 
     } 

     return Utils.sort(unsortedSnapshot, (x,y) -> x.ping < y.ping); 
    } 
} 

所以這種方法是sortByPingTime定義是什麼做;參數是networkNodes來描述我們正在查看的節點類型。而變量稱爲unsortedSnapshot僅僅通過閱讀代碼來表達一下兩件事情是不可見的:

  • 它的東西快照(暗示原來是某種揮發性);和
  • 它沒有對我們很重要的命令(暗示它可能有,當我們完成它)。

我們可以把nodes放在那裏,但是立即可以從輸入參數中看到。我們也可以稱之爲snapshotToSort,但這一點在我們將其交給下面的例程sort的事實中很明顯。

這個例子仍然有點人爲。該方法對於變量名稱來說太短暫了。在現實生活中,我可能會把它稱爲out,因爲選擇一個好名字所需的時間比任何人都會花費更長的時間來弄清楚這種方法的工作原理。

其他相關說明:

  • 命名本質上是一個有點主觀的。我的名字永遠不會適用於所有人,特別是在考慮多種人類語言的情況下。
  • 我發現最好的名字根本就沒有名字。如果我可以避開匿名的東西,我會 - 這會最大限度地減少變量被重用的風險,並減少IDE「查找」框中的符號。通常這也促使我寫更緊密,更實用的代碼,我認爲這是一件好事。
  • 有些人喜歡在名稱中包含變量的類型;我總是發現有點奇怪,因爲這種類型通常很明顯,而且編譯器通常會抓住我,如果我弄錯了。
  • 「保持簡單」在這裏是完全有效的,無處不在。大多數時候你的變量名不會幫助某人避免未來的工作。我的經驗法則是,將它命名爲愚蠢的東西,如果我最終會撓撓頭腦的東西,請選擇該場合來命名它。
1

簡單地說,命名變量時,我考慮一些事情。

  1. 如何複製產生的? (是否從一種類型轉換爲另一種類型?)
  2. 我該怎麼處理變量?
  3. 名稱簡短但有意義嗎?

考慮你在問題中提供的同樣的例子,我將命名變量是這樣的:

List<Nodes> process(Collection<Nodes> nodes) { 
    List<Nodes> nodesCopy = new ArrayList<>(nodes); 
    ... 
} 

這可能僅僅是一個集合的副本,故名nodesCopy。有意義而且短小。如果您使用nodesList,那可能意味着它不僅僅是一個Collection;還有一個List(更具體)。

public void processUser(final String userId) { 
    final int userIdInt = Integer.parseInt(userId); 
    ... 

StringuserId被解析,結果是一個整數(int)!這不僅僅是一個副本。爲了強調這一點,我將其命名爲userIdInt

這是更好的不是使用下劃線_,因爲它通常指示實例變量。而my前綴:沒有太大的意義在那裏,它是noobylocal會做的更好)。

1

當涉及到方法參數命名慣例,如果一個方法參數表示將不會受到任何其他變量來表示的東西,使用方法參數名,使得它非常清楚該方法的參數是在方法的上下文身體。例如,primaryTelephoneNumber可能是JavaBean setter方法中可接受的方法參數名稱。

如果有一種方法方面的東西多表示(包括方法參數和局部變量),使用的名稱,使人們清楚人類是什麼東西,以及它如何被使用。例如,providedPrimaryTelephoneNumber,requestedPrimaryTelephoneNumber,dirtyPrimaryTelephoneNumber可能用於方法參數名稱,而parsedPrimaryTelephoneNumber,cleanPrimaryTelephoneNumber,massagedPrimaryTelephoneNumber可能用於保留用戶提供的主要電話號碼的方法中的局部變量名稱。

主要目的是利用該名講清楚人類閱讀源代碼,今天和明天,以東西是什麼。避免像var1名,var2ab等;這些名稱在閱讀和理解源代碼時增加了額外的努力和複雜性。

沒有得到在使用長法參數名或局部變量名太趕上了;源代碼是爲了人類的可讀性,當類被編譯時,方法參數名稱和局部變量名稱與機器無關。

相關問題