一般来说,一个类的构造函数最多应该接受多少参数?我正在开发一个需要大量初始化数据的类(目前有10个参数)。然而,一个有10个参数的构造函数感觉不太对。这让我相信我应该为每个数据创建一个getter/setter。不幸的是,getter/setter模式并不能强制用户输入数据,没有它对象的特征描述是不完整的,因此无用的。您怎么看?
一般来说,一个类的构造函数最多应该接受多少参数?我正在开发一个需要大量初始化数据的类(目前有10个参数)。然而,一个有10个参数的构造函数感觉不太对。这让我相信我应该为每个数据创建一个getter/setter。不幸的是,getter/setter模式并不能强制用户输入数据,没有它对象的特征描述是不完整的,因此无用的。您怎么看?
有这么多参数,现在是考虑Builder模式的时候了。创建一个Builder类,其中包含所有那些getter和setter方法,以及一个build()方法,该方法返回您真正想要构建的类的对象。
public class ReallyComplicatedClass {
private int int1;
private int int2;
private String str1;
private String str2;
// ... and so on
// Note that the constructor is private
private ReallyComplicatedClass(Builder builder) {
// set all those variables from the builder
}
public static class Builder {
private int int1;
private int int2;
private String str1;
private String str2;
// and so on
public Builder(/* required parameters here */) {
// set required parameters
}
public Builder int1(int newInt) {
int1 = newInt;
return this;
}
// ... setters for all optional parameters, all returning 'this'
public ReallyComplicatedClass build() {
return new ReallyComplicatedClass(this);
}
}
}
而在您的客户端代码中:
ReallyComplicatedClass c = new ReallyComplicatedClass.Builder()
.int1(myInt1)
.str2(myStr2)
.build();
你可以自行决定何时足够,并使用引入参数对象来构建你的构造函数(或者任何其他方法)。
我认为你不能说一个合适的数字是“七个,不多”或“五个”。
对于构造函数而言,一个很好的经验法则是传递一个对象的标识,而不是它的状态。你传递的这些参数是对象存在所必需的,并且如果没有它们,大多数对象操作可能无法进行。
如果你确实有一个具有非常复杂的自然标识的类,因此需要许多参数,请考虑你的类的设计。
一个糟糕的构造函数的例子是:
public NightWatchman(int currentFloor, int salary, int hapiness) {...}
这里NightWatchman正在使用一些默认值进行构建,这些默认值很可能在短时间内发生变化。有趣的是,对象以一种方式告知其值,然后通过设置器以不同的方式拥有它们。
一个更好的构造函数示例:
public GateWatchman(Gate watchedGate, boolean shootOnSight) {...}
这要看情况。
如果一些参数是相同类型的,可以混合使用,我可以容忍较小的数量(比如5个)。
如果参数是不同类型的,不能混合使用,那么我可以容忍更多。但是10个就接近极限了。
构造函数传入一个参数 => 值映射对象怎么样?如果调用者省略了任何关键参数,构造函数将抛出异常。
这意味着对构造函数的错误调用只能在运行时而不是编译时捕获,这是一个缺点。但是getter/setter方法也有同样的问题,而且这种方法应该更容易使用。