2016-11-04 71 views
4

我有一個類,如下所示:與許多領域管理類

public class Foo { 
    private double A; 
    private double B; 
    ... 
    private double K; 
} 

它應包含11個緊密結合的參數,A-K,其描述了在地球軌道的點(一種座標的)的移動。因此,我的意思是它們不能分成小類或其他有意義的部分,因爲它們都具有相同的目的和意義。所有這些參數應該在構造函數中一起實例化,因此另一個類可以使用Foo和那11個字段進行必要的計算。 我已經給了一個關於構造函數中參數數量太多的評論。

是否有另一種方法來初始化一個Foo對象而不使用巨大的構造函數,一個排序圖?希望我已經足夠清楚,如果沒有,我會提供更多細節。

+0

你不能使用數組而不是從** AK則params的** ? –

+0

[Builder Pattern](https://en.wikipedia.org/wiki/Builder_pattern)? – bradimus

+0

考慮到你描述的情況,11參數構造函數似乎是最合適的實現。由於一般編譯器/分析警告而選擇不同的實現(如列表)會違反此警告的根本原因。 附註:空間11分?這是否是弦理論? – pathfinderelite

回答

2

您可以使用varargsdouble作爲您的構造函數的參數,並檢查其大小以確保它是預期的。

喜歡的東西:

public class Foo { 
    private double A; 
    private double B; 
    ... 
    private double K; 

    public Foo(double... coordinates) { 
     if (coordinates == null || coordinates.length != 11) { 
      throw new IllegalArgumentException("Unexpected size of coordinates"); 
     } 
     this.A = coordinates[0]; 
     this.B = coordinates[1]; 
     ... 
     this.K = coordinates[10]; 
    } 
    ... 
} 

這樣,你已經在你的構造函數只有一個參數定義,但你仍然可以爲簡單起見,在明年提供11值:

Foo foo = new Foo(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0); 

而且您仍然可以將它作爲doublearray作爲下一個提供:

Foo foo = new Foo(new double[]{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0}); 
+0

非常有用,謝謝!不幸的是,最大的問題是,如果用戶上傳一個參數順序混合的配置文件,就不會有任何方法知道哪個值對應於某個特定的參數。 – borgmater

+0

確實,我認爲你應用了公約,例如3D如果我提供'{1,2,3}'作爲座標我隱含地知道'x = 1','y = 2'和'z = 3',它可能是另一種方式,但它會完全不是標準。 –

+1

無論如何,你恐怕沒有數以百萬計的可能性,要麼你保留你所擁有的並忽略警告,要麼你選擇一個基於數組或集合的解決方案 –

1

如果構造函數的調用者需要如何設置11緊密結合參數中我會用這樣的構造函數或可能已結合的ArrayList說了一致的方式。

如果您對這11個參數的一致性有任何疑問,我寧願使用Factory創建Foo。如果這個工廠使用一個具有11個參數的構造函數或11個set方法調用,則取決於您和您對此類設計的期望。

而不是Factory類,您可以使用不同的構造函數與其他參數,並具有在這些不同的構造函數中設置11個參數的邏輯。

1

主要的危險是該對象的用戶之一會混淆參數,傳遞值爲A,其中B是。

答案取決於具體情況。

如果這些對象是一羣來自數據源的初始化單身如配置文件或數據庫表,那麼你就需要一個接口傳遞給構造函數:

interface FooData { 
    double getA(); 
    ... 
} 

然後實現該接口上的表或配置文件。

如果對象是基於即時狀態即時創建的,則Factory和Builder模式的某些組合是按順序組合的。工廠模式(如果有的話)(例如A只能是1.0或0.0)。生成器讓錯誤更難。

在第二種情況下,在工廠和構建器之後,該對象仍然具有11個參數的構造函數,這個構造函數只是隱藏在外部世界中。

0

我認爲這裏最大的問題是,你有11個相同類型的參數,並且在編譯時它們絕對沒有幫助。爲了解決一部分,怎麼樣:

public class AValue { 
    public final double val; 
    public AValue(double val) { this.val = val; } 
} 

然後,醜陋,但是(也許?)非常有用:複製10次與11班安勤達KValue結束。

然後你就可以放下你的構造函數

public Foo(AValue a, BValue b, ... and so on) { 

,允許一個乾淨,編譯器支持的接口來構建富。

這並不意味着Foo必須存儲11個對象;它可以將它們推入具有11個插槽的雙陣列中。當然,你還可以添加喜歡

AValue getA() 

您Foo類類型安全方法。

而且,除此之外,你甚至可以把薩科答案併爲此:

interface ValueType { public double getValue(); } 
class AValue implements ValueType { 
    ... 
    @Override 
    double getValue() { return value; } 

public class Foo { 

    public Foo(AValue a, BValue b, ... KValue k) { 
    this((ValueType) a, ..., (ValueType) k); 
    } 
    Foo(ValueType... values) { 
    ... push values into double[]