管理具有许多字段的类

时间:2016-11-04 12:30:28

标签: java constructor

我有一个课程如下:

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

它应包含11个紧密绑定的参数A-K,它描述地球轨道中一个点的运动(一种坐标)。因此,我的意思是它们不能分为子类或其他有意义的部分,因为它们都有相同的目的和意义。所有这些参数都应该在构造函数中一起实例化,因此另一个类可以使用Foo和那11个字段进行必要的计算。 我已经对构造函数中的参数数量过多给出了评论。

是否有另一种方法可以在不使用巨型构造函数的情况下初始化Foo对象,这是一种排序图?希望我足够清楚,如果没有,我会提供更多细节。

4 个答案:

答案 0 :(得分:2)

您可以使用varargs double作为构造函数的参数,并检查其大小以确保它是预期的大小。

类似:

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);

您仍然可以将array double作为下一个提供:

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});

答案 1 :(得分:1)

如果构造函数的调用者需要如何以一致的方式设置 11紧密绑定参数,我会使用这样的构造函数,或者可能已经用Array或{ {1}}。

如果您对此11个参数的一致性有疑问或假设有问题,那么我更希望使用List创建Foo。如果这个工厂使用带有11个参数的构造函数或者11个调用set方法,则由您和您对此类设计的意愿决定。

您可以使用不同的构造函数和其他参数来代替Factory类,并具有在这些不同构造函数中设置11个参数的逻辑。

答案 2 :(得分:1)

主要的危险是该对象的一个​​用户会混淆参数,为B传递A值。<​​/ p>

答案取决于具体情况。

如果这些对象是从一些数据源(如配置文件或数据库表)初始化的一堆单例,那么您需要将一个接口传递给构造函数:

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

然后在表或配置文件上实现该接口。

如果基于立即状态动态创建对象,则按顺序组合Factory和Builder模式的某些组合。工厂模式将分解常见的值集(如果有的话)(例如A只能是1.0或0.0)。建造者让错误更难。

在第二种情况下,在工厂和构建器后面,对象仍然会有11个参数构造函数,只是对外界隐藏。

答案 3 :(得分:0)

我认为这里最大的问题是你有11个相同类型的参数,混合它们时编译器绝对没有帮助。为了解决部分问题:

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

然后,丑陋,但(可能?)有用:再复制10次,最后得到11个AValue类到KValue。

然后你可以把你的构造函数放到

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

这允许一个干净的,编译器支持的接口来构建Foo。

并不意味着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[]