除构造函数重载java之外的最佳实践/设计模式

除构造函数重载java之外的最佳实践/设计模式,java,design-patterns,builder-pattern,constructor-overloading,architectural-patterns,Java,Design Patterns,Builder Pattern,Constructor Overloading,Architectural Patterns,我有一个类,它有多个构造函数。每个代表不同的用例 public class ABC { public ABC(int x) { ... } public ABC(ArrayList<String> Stringarray) { ... } ..many more constructors.. } 公共类ABC{ 公共ABC(int x){ ... } 公共ABC(ArrayList Stringarray){ ... } …更多的施工人员。。 } 构造

我有一个类,它有多个构造函数。每个代表不同的用例

public class ABC {
  public ABC(int x) {
  ...
  }
  public ABC(ArrayList<String> Stringarray) {
  ...
  }
  ..many more constructors..
}
公共类ABC{
公共ABC(int x){
...
}
公共ABC(ArrayList Stringarray){
...
}
…更多的施工人员。。
}
构造函数重载是迄今为止最干净的解决方案,直到我在java编译器中遇到同样的擦除问题。例如,我想添加另一个最终具有相同擦除的构造函数,因此我只选择了包含一个默认参数,以解决目前的问题,如下所示:

public ABC(ArrayList<String> stringArray) {
  …
}
public ABC(ArrayList<Integer> integerArray, boolean… sameErasureFlag) {
  …
}
公共ABC(ArrayList stringArray){
…
}
公共ABC(ArrayList integerArray、boolean…sameErasureFlag){
…
}

但是我有一种强烈的感觉,对于这个用例来说,拥有这么多的构造函数并不是一种好的设计模式。。也许有一个更好的解决方案或最佳实践设计模式用于这种场景。我正在查看生成器模式,但不确定该模式是否正确/更好。有什么建议吗?

这取决于类对参数的具体操作,我们没有确切的细节,但是对于泛型类型,您可以做的一件简单的事情是使您自己的类成为泛型(在这种情况下,可能不需要应用奇特的设计模式):

公共类ABC{
公共ABC(ArrayList stringArray){
…
}
…
}
ArrayList intList=流(1,2,3)
.collect(收集器.toCollection(ArrayList::new));
ArrayList stringList=流(“a”、“b”、“c”)
.collect(收集器.toCollection(ArrayList::new));
ABC abc1=新的ABC(intList);
ABC abc2=新的ABC(字符串列表);
我有一个类,它有多个构造函数。每个代表不同的用例

public class ABC {
  public ABC(int x) {
  ...
  }
  public ABC(ArrayList<String> Stringarray) {
  ...
  }
  ..many more constructors..
}
那么简单的答案是:将每个用例转换成它自己独特的类

一个类中有多个不相关的字段,而每个“用例”只使用其中的一部分,这一想法清楚地表明类做了太多的事情


任何类或方法都应该只做“一件事”。所以,如前所述:答案就到此为止,而不是在一个类中添加更多的东西:问问自己如何有意义地将其拆分。

是的,有许多构建者可以指出,类违反了单一责任原则。 我同意-信息不足以做出决定。构建器模式可以工作,甚至可以抽象工厂。 但是,请考虑使用工厂方法而不是构造函数作为建议J. Bloch:

public ABC of(ArrayList<Integer> integerArray, boolean… sameErasureFlag) {
public ABC of(ArrayList integerArray,boolean…sameErasureFlag){

}

您的类是否真的实现了不同的用例,每个用例都由另一个构造函数表示?那么

如果您只想为您的类提供不同的初始化路径,而这些路径在其他情况下执行相同的操作,那么无论用于初始化的数据的格式如何,使用多个构造函数都可能是正确的选择


但是当超过一定数量的构造函数(有些说3,其他5……一些极端主义者甚至说1),你肯定有太多的构造函数,然后你应该考虑工厂模式,如建议的那样。当您考虑引入“虚拟”参数来解决擦除问题时,无论有多少构造函数,都应该明确考虑这一点。工厂模式的优点是,工厂方法的签名不仅仅由参数列表决定,您还可以选择不同的名称(
ABC.ofitlist()
ABC.ofStringList()
,等等……。

如果类中的字段太多,我建议您的设计不好。有些人可能建议使用生成器模式。但是我认为最好对OOP表现出更多的尊重,所以我认为最好将类划分为多个类,并使用装饰器模式

我有一种强烈的感觉,可能有这么多的构造函数不是一种好的设计模式

视情况而定

有些人更喜欢构造函数,一些其他的方法,但我认为你是对的,有很多重载的构造函数可能很难阅读和维护

P>一个可供选择的方案是最近,许多作者建议使用静态工厂方法而不是构造函数

您可能希望支持他们的原因很少:

它们为您提供了更好、更清晰、更直观的可读性 你不能给构造函数起名字。构造函数名称始终与类名相同;不过,您可能会发现使用命名很有用,因为它们将提供更清晰的可读性

您可以构造并返回子类型
使用构造函数时,不能改变构造对象的类型;但是,factory方法可以返回从超类派生的对象,这意味着您可以根据输入条件决定具体构造什么。

您确实需要提供有关实际用例的更多信息,因为现在看起来你想创建一个上帝类,而不是让你的类保持简单,让他们只做一件事。您是否考虑过使用接口和适当抽象的泛型?假设您指的是Bob Martin:一个方法应该只做一件事。班级是不同的。据我所知,他从未建议班级做一件事。恰恰相反,我不同意。类的范围仍然应该是“一件事”。只是在“更大”的范围内。理想情况下,所有方法都使用“所有”字段。只要你能画出清晰的线条,x/y/z只被foo()/bar()使用,a/b/c只被horr()/ible()使用,那么这就清楚地表明你的类正在做“两件事”,应该被拆分。要清楚的是,你是否把这个观点归因于Bob Martin,或者这是你个人的观点?马丁是单一res的坚定支持者