2016-11-04 70 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[]