2016-02-23 35 views
1

假設我有一些類具有構造函數,其中的每一個有2個PARAMS 例如我有5種類型,其中兩個可作爲第一個參數被傳遞和三個作爲第二爪哇減少構造的數目

假設類型是A,B,C,D,E。基本上,我有這樣的事情:

public SomeClass(A,C) {} 
public SomeClass(A,D) {} 
public SomeClass(A,E) {} 

public SomeClass(B,C) {} 
public SomeClass(B,D) {} 
public SomeClass(B,E) {} 

因此,大家可以看到有這些類型的 的所有可能的組合中都沒有可選的參數,可以像標準構建模式。

我該怎麼做才能減少構造函數的數量?有一些模式可以幫助我嗎?

EDIT

因爲如果我供給A,那麼我不能提供乙 ,如果我提供的C然後我不能提供d或E我不能使用標準的助洗劑

+0

看看http://stackoverflow.com/questions/34726422/passing-properties-to-factory-method/34752184#34752184 –

+0

我不明白使用生成器模式的問題是什麼? – khelwood

+0

@Nayuki他們都是他們,但有一段時間可以有更多的,我只想找到我的問題 –

回答

2

你可以創建一個受限制的建造者模式:

class MyBuilder { 

    public MyBuilder(A) { ... } 
    public MyBuilder(B) { ... } 

    public SomeClass build(C) { ... } 
    public SomeClass build(D) { ... } 
    public SomeClass build(E) { ... } 

} 

用法示例:

new MyBuilder(A).build(C) 

如果你只有6種可能的組合,我可能會容忍在現有代碼的複雜性和重複。但是如果有更多的可能性和/或將來的代碼將被擴展,那麼我會在這裏推薦這種模式。


您可以將此模式擴展爲更多參數,但由於您需要更多中間類,因此它變得越來越醜。對於3個參數,你可能會實現這樣的:

class MyBuilder1 { 
    public MyBuilder1(A) { ... } 
    public MyBuilder1(B) { ... } 

    public MyBuilder2 build(C) { ... } 
    public MyBuilder2 build(D) { ... } 
    public MyBuilder2 build(E) { ... } 

    class MyBuilder2 { 
     public MyBuilder2(C) { ... } 
     public MyBuilder2(D) { ... } 
     public MyBuilder2(E) { ... } 

     public SomeClass build(F) { ... } 
     public SomeClass build(G) { ... } 
    } 
} 

SomeClass x = new MyBuilder1(B).build(D).build(F); 

不幸的是,中間階段需要對類型C,d,E

+0

HMM它可以是在我的情況下可以接受,但如果有3個參數等等呢? –

+0

如果你有3個參數,可以你可能想使用標準的建造者模式。除非你想嚴格執行params的順序。 – Nayuki

+0

我已添加編輯,請看它 –

0

創建2個接口,一個用於你的第一個參數,另一個用於你的第二個參數。 A和B實現第一個,C,D和E是第二個。

+1

呵,但如果某些類型不是我的自定義類型,例如其中之一是字符串 –

0

一個建議,方法和構造函數重複。將邏輯放入您的構建器等效類中。添加一個方法來檢查參數組合是否有效。

class MyBuilder { 

    int paramA; 
    bool paramAset = false; 

    long paramB 
    bool paramBset = false; 

    // etc for all parameters. 

    void setParamA(int newAval) { 
    if (checkParamA(newAval)) { 
     paramA = newVal; 
     paramAset = true; 
    } 
    } 

    void setParamB(long newBval) { 
    if (checkParamB(newBval)) { 
     paramB = newBval; 
     paramBset = true; 
    } 
    } 

    // etc. for all parameters. 

    // Parameter checker method. 
    bool checkValid() { 
    if (
     paramAset && !paramBset && /* other params */ || 
     !paramAset && paramBset && /* other params */ || 
     // other allowed parameter combinations 
     ) { 
     return true; 
    } else { 
     return false; 
    } 
    } 

} // end class MyBuilder 

每個參數都有自己的值和一個布爾值來指示它是否被設置。檢查器方法只允許有效的布爾組合。請注意,每個參數都在檢查器中設置或未設置,以捕獲所有無效組合。如果組合無效,則您的主類的構造函數需要調用檢查器方法並適當地失敗。