2010-06-28 21 views
2

例如,假設我這樣的:我應該如何設計一個允許可選操作的方法?

class Gundam00 extends Gundam implements MobileSuit { 
    ... 

    public void fight(final List<MobileSuit> mobiruSuitso, final List<Gundam> theOtherDudes, final List<Person> casualities) { 
     .... 
    } 
} 

假設theOtherDudes和傷亡參數都是可選的。我怎樣才能使這種方法儘可能乾淨?我想布爾表明它們是否爲空,然後根據需要檢查它們。

對於每個參數組合,我也可以有不同版本的方法,但是我認爲會有很多代碼重複。

有什麼建議嗎?

+0

看到這個http://stackoverflow.com/questions/965690/java-optional-parameters – 2010-06-28 00:53:21

回答

0

我想過布爾值是否爲空,然後檢查它們並做出相應的反應。

或者...你可以檢查它們是否爲空。

if(theOtherDudes == null) 
    ... 
+0

我的意思是做'最後布爾anyAllies = theOtherDudes == null'並檢查,只要我必須使用該參數。以便。我編輯了這篇文章,使其更清晰。 – 2010-06-28 00:52:24

+2

在沒有「其他傢伙」的情況下,您應該傳遞一個空集合而不是傳遞null。 – 2010-06-28 00:55:02

+0

現在你提到它,傳遞一個空集合聽起來更好。 – 2010-06-28 00:59:53

3

我發現,過去2-3個參數,有能力記住所有的函數參數都受到影響。隨着它的可理解性。

傳遞命名參數可以提供幫助。具有方便散列式文字語法的語言使得這非常簡單。以JavaScript的:

g = new Gundam00(); 
g.fight({opponent: enemy, casualties: 'numerous'}); 

您也可以利用可變長度參數特徵來解決這個(治療奇怪的論點姓名,甚至參數作爲實際參數)。

g.fight('opponent',enemy,'casualties', 'numerous'); 

某些語言實際支持命名的參數直(見:http://en.wikipedia.org/wiki/Named_parameter#Use_in_programming_languages)。

最後,您可能需要考慮添加其他方法,使用一些稱爲Fluent接口(http://en.wikipedia.org/wiki/Fluent_interface)的方法。基本上,你有方法調用它返回的對象本身,這樣你就可以調用鏈在一起:

g.opponent(enemy).casualties('numerous').fight(); 

,如果你在一個明顯/靜態類型類爲重點的語言工作,這可能是最簡單的選項。

更新

應對剎那的評論......在最後一個例子,如果你有奢侈,你可以像opponentcasualties簡單的setter方法不影響任何內部狀態或除了設置他們命名的參數之外的其他方式進行計算。他們只是簡單地設置內部屬性,然後所有的實際工作都發生在像fight這樣的動作方法中。如果你不能這麼做(或者如果你不喜歡編寫操作是次原子的方法的話),你可以用這種類似散列的字面意思放在這個想法之間的一箇中間點,並且創建自己的集合類專門用於調用命名參數:

n = new NArgs(); 
g.fight(n.arg('opponent',enemy).arg('casualties','numerous').arg('motion','slow')); 

多一點笨拙,但是它分離出來的命名參數的問題,可以讓你保持你的方法有點多個原子,並NARGS是可能是你可以實現很簡單,只是圍繞一種類型的集合(HashTable?)或另一種可用的語言包裝某些方法。

+1

最後一種方法是我首先想到的 - 裝飾者 - 但操作必須同時進行。所以我想不出添加它們的方法。我確定有,我只是不習慣這種模式。 – 2010-06-28 01:47:39

+1

你可以製造'對手'和'傷亡'基本製作者,並將實際工作留在'戰鬥'中......但是如果這對你的情況不起作用,你可以創建一個命名參數類,使用某些想法。我剛剛更新了我的答案以反映這一點。 – 2010-06-28 02:47:30

0

如果在你的類中只有一個「主要方法」,那麼你可以實現可選參數作爲getter/setter函數。例如:

public void setOtherDudes(final List<Gundam> theOtherDudes) {} // for input arguments 
public List<Person> getCasualities() {} // for output arguments 

然後,你的文檔中,提到如果呼叫者有任何可選的輸入參數,它調用fight()之前傳遞,和可選的輸出值將可在fight()被調用。

這是值得的,如果有幾十個可選參數。否則,我建議將方法重載爲最簡單的方法。

相關問題