2012-12-07 41 views
2

我確定必須有一個標準的方法來做到這一點,但我的搜索Stackoverflow的嘗試失敗了。如何重構以避免將「特殊值」傳遞給Java方法?

我有這樣的方法:

public void processSomeWidgetsForUser(int userItemId) { 
    Iterator<Widgets> iter = allWidgets.values().iterator(); 
    while(iter.hasNext()) { 
     Widget thisWidget = iter.next(); 
     if (userItemId == -1 || thisWidget.getUsersItemId() == userItemId) {     
      widget.process(); 
     } 
    } 
} 

正如你可以看到-1是一種「特殊價值」,意思是過程中的所有。這樣做可以節省在另一個名爲processSomeWidgetsForAllUsers的方法中重複循環代碼。

但我不喜歡這樣的特殊值,因爲它們很容易誤用或誤解,這正是我現在必須解決的情況(有人認爲-1意味着別的東西)。

我只能想到兩種方法來改善這一點。

  1. 具有恆定的,包含-1稱爲像 Widget.ALLWIDGETS這至少是自記錄文件,但使用不 停止代碼-1(如果有人在整合舊代碼, 例如)
  2. 更改方法將所有用戶ID列表設置爲 進程,該進程可以爲空,但看起來不太好 性能明智(需要首先檢索所有用戶ID,然後通過 如果列表中的小部件數量在 之間變化,則會發生什麼情況:retreiving the id和

有沒有更好的方法?我確定我錯過了一些明顯的東西。

上面的代碼已經稍微改變了,所以可能無法編譯,但你應該明白了。

回答

4

雖然有些多餘,一個相當整齊的自我記錄的做法可能是有3種方法,而不是一個;

使您的原始方法private,並作出一個小的變化,將添加您的static final int EXECUTE_ALL = -1並在您的原始方法中使用,然後添加兩個新的方法;

public void processWidget(int wID) throws IllegalArgumentException { 
    if(wID == EXECUTE_ALL) throw new IllegalArgumentException(); 
    originalMethod(wID); 
} 

public void processAllWidgets() { 
    originalMethod(EXECUTE_ALL); 
} 

它使你的課堂更加混亂一點,但就暴露的方法而言,它更清晰,希望萬無一失。你可以改變它,不要拋出異常,只是忽略任何無效的ID,這取決於你的情況。

當然這種方法,它改變了類如何出現的其他類,打破了目前使用的,現在私人,originalMethod一切()的主要缺點。

+2

我喜歡這種方法,因爲它更清晰(無幻數),但我會簡單地拋出任何已知無效ID一個IllegalArgumentException。沒有檢查異常是必需的(但javadoc輸入限制)。 – Robin

+0

你說得很對,我會修改答案! – lynks

+0

謝謝 - 它很好地處理了錯誤的調用,並且很清楚。 –

1

數字1會很好地工作。一定要記錄變量是什麼,所以未來的編碼器(可能是你自己)知道它是什麼意思。

/**This is the explanation for the below variable*/ 
public final static int ALL_WIDGETS = -1; 
1

有一個像外部方法等等:

static boolean idRepresentsAll(int id) { 
    return id == -1; 
} 

在這種情況下,如果決定使用不同的機制來取代它,你只在你的代碼替換你的幻數一個地方。

最起碼,你會想要做這樣的事情:

public static final int ID_REPRESENTING_ALL = -1; 
1

您可以更改方法簽名接受,當你要處理他們所有的布爾。

public void processSomeWidgets(boolean doAll, int userItemId) { 
    Iterator<Widgets> iter = allWidgets.values().iterator(); 
    while(iter.hasNext()) { 
     Widget thisWidget = iter.next(); 
     if (doAll || thisWidget.getUsersItemId() == userItemId) {     
      widget.process(); 
     } 
    } 
} 

這使得它更明確,也更容易在我看來,閱讀,因爲沒有特殊的價值。