我有一个课程如下:
public class Foo {
private double A;
private double B;
...
private double K;
}
它应包含11个紧密绑定的参数A-K,它描述地球轨道中一个点的运动(一种坐标)。因此,我的意思是它们不能分为子类或其他有意义的部分,因为它们都有相同的目的和意义。所有这些参数都应该在构造函数中一起实例化,因此另一个类可以使用Foo
和那11个字段进行必要的计算。
我已经对构造函数中的参数数量过多给出了评论。
是否有另一种方法可以在不使用巨型构造函数的情况下初始化Foo
对象,这是一种排序图?希望我足够清楚,如果没有,我会提供更多细节。
答案 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[]