Java 多字段管理类
我的课程如下:Java 多字段管理类,java,constructor,Java,Constructor,我的课程如下: public class Foo { private double A; private double B; ... private double K; } 它应该包含11个紧密绑定的参数A-K,它描述了地球轨道上一个点的运动(一种坐标)。我的意思是,它们不能被划分为子类或其他有意义的部分,因为它们都有相同的目的和意义。所有这些参数都应该在构造函数中一起实例化,这样另一个类就可以使用Foo和这11个字段进行必要的计算。 我已经得到了一个关于构造函
public class Foo {
private double A;
private double B;
...
private double K;
}
它应该包含11个紧密绑定的参数A-K,它描述了地球轨道上一个点的运动(一种坐标)。我的意思是,它们不能被划分为子类或其他有意义的部分,因为它们都有相同的目的和意义。所有这些参数都应该在构造函数中一起实例化,这样另一个类就可以使用Foo
和这11个字段进行必要的计算。
我已经得到了一个关于构造函数中参数数量太多的评论
有没有另一种方法可以在不使用巨型构造函数(一种排序映射)的情况下初始化
Foo
对象?希望我足够清楚,如果不清楚,我将提供更多细节。如果构造函数的调用方需要如何以一致的方式设置11个紧密绑定的参数,我将使用这样的构造函数,或者像前面所说的那样使用数组
或列表
如果您在这11个参数的一致性方面存在问题或假设存在问题,那么我更愿意使用工厂创建Foo
s。如果这个工厂使用的构造函数有11个参数或11个set方法调用,这取决于您和您对这个类的设计意愿
您可以将不同的构造函数与其他参数一起使用,而不是使用工厂类,并且可以在这些不同的构造函数中设置11个参数。您可以使用ofdouble
作为构造函数的参数,并检查其大小以确保它是预期的参数
类似于:
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);
您仍然可以将其作为数组
的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});
主要的危险是对象的一个用户会混淆参数,传递A的值,其中B是
答案取决于具体情况
如果这些对象是从某些数据源(如配置文件或数据库表)初始化的一组单例,则需要向构造函数传递一个接口:
interface FooData {
double getA();
...
}
然后通过表或配置文件实现该接口
如果对象是基于即时状态动态创建的,则工厂模式和构建器模式的某种组合是正确的。工厂模式,以计算出通用值集(如有)(例如A只能为1.0或0.0)。建设者更容易犯错误
在第二种情况下,在factory和builder之后,对象仍然有11个参数构造函数,只是对外隐藏。我认为这里最大的问题是,您有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; }
与
难道你不能用数组代替A-K中的参数吗?鉴于你所描述的情况,11参数构造函数似乎是最合适的实现。由于通用编译器/分析警告而选择不同的实现(如列表)与此类警告的根本原因背道而驰。旁注:空间中有11点?这是弦论吗?是星历数据,地球静止轨道上的卫星位置。数组会很笨拙,因为每个参数都有自己的名称(例如正弦振荡、自变化率、cos振荡、变化率等),非常有用,谢谢!不幸的是,最大的问题是,如果用户上传的配置文件中的参数顺序混淆了,就无法知道哪个值对应于特定的参数。事实上,我假设您应用了通用约定,例如在3D中,如果我提供{1,2,3}
作为坐标,我隐式地知道x=1
,y=2
和z=3
,这可能是另一种方式,但它将完全不是标准的。我担心,无论如何,你没有数百万种可能性,要么你保留现有的并忽略警告,要么你选择一种基于数组或集合的解决方案是的,看起来是这样。我已将此作为解决方案包括在内,因此现在我只有一个参数,谢谢:)
public class Foo {
public Foo(AValue a, BValue b, ... KValue k) {
this((ValueType) a, ..., (ValueType) k);
}
Foo(ValueType... values) {
... push values into double[]