有没有更好的方法来制作一个构造函数来填充所有可能的变量,而不是将它们全部写出来?

Is there any better way to make a constructor that fills in for all the possible variables rather than writing them all out?

提问人:Jelatinone 提问时间:11/5/2022 更新时间:11/5/2022 访问量:191

问:

有没有更省时的方法来创建一个程序,该程序可以接受我所有给定的参数,而不管它们是什么,只需为这些值填写什么?例如,给定我想要填充的可选 4 个参数,我是否必须为每个可能的组合编写构造函数?

我是 Java 的新手,但我已经编写了一个我这样做的类,这花了我相当长的时间并且有点单调,我只是想知道是否有更快的方法。

Java parameters 构造函数 参数传递

评论


答:

2赞 hfontanez 11/5/2022 #1

构造函数不是构造对象的唯一方法。有一些(创建性)设计模式可以实现您应该考虑的相同目标。事实上,可以说构造函数应该被视为构建对象的最后手段。我强烈建议你对创造性设计模式做一些研究

对于这个问题,我认为您可以利用 The Builder Pattern

构建器模式解释

构建器模式允许客户端分阶段构建对象。这是可能的,因为所需对象的实例化被推迟到构建器,直到获得所有需要的属性。

考虑构建“小部件”的过程。假设这个“小部件”有两个组件,其中只需要一个。您可以 A) 在没有可选组件的情况下构建“小部件”,或者 B) 您可以将“小部件”与所需的部件组装在一起,暂停构建过程,并在可选组件可用时稍后恢复。使用传统构造函数时,这是不可能的。

Builder 模式的另一个优点是,您不需要创建具有大量不需要的参数的构造函数。而且,它消除了使用不同参数对构造函数进行多种排列的需要。事实上,有时这甚至是不可能的。例如,如果所讨论的类有 8 个 String 参数,则不能有两个构造函数,每个构造函数有 4 个 String。

在实现此模式时,正在构建的“小部件”只有一个构造函数,并且是私有的。类的构造函数仅供生成器访问。

最后,与传统的“setter”方法不同,构建器的“setter”方法返回构建器本身的实例。这允许链接方法调用设置多个(可选)参数。例如; 等。builder.setOptionalParm1(val1).setOptionalParm2(val2)...

生成器模式代码示例

public class ImmutableWidget {
    
    private final String required;
    private final String optional;
    
    private ImmutableWidget (Builder builder) {
        this.required = builder.required;
        this.optional = builder.optional;
    }
    
    @Override
    public String toString () {
        return "Required: " + required + "; Optional: " + optional;
    }
    
    public String getRequired () {
        return required;
    }
    
    public String getOptional () {
        return optional;
    }
    
    public static class Builder {
        
        private final String required;
        private String optional;
        
        public Builder (String required) {
            this.required = required;
        }
        
        public Builder setOptional (String optional) {
            this.optional = optional;
            return this;
        }
        
        public ImmutableWidget build () {
            return new ImmutableWidget (this);
        }
    }
    
    public static void main (String... strings) {
        Builder builder = new ImmutableWidget.Builder ("required");
        builder.setOptional("optional"); // This step is not required
        ImmutableWidget widget = builder.build();
        System.out.println(widget);
    }
}

其他信息:

  1. Basic Builder Pattern 主题:不可变小部件 YouTube 视频
  2. Advanced Builder Pattern 主题:将 Builder Pattern 用于类 层次 结构
1赞 flibbit31 11/5/2022 #2

维塔利·费多连科(Vitalii Fedorenko)的这篇文章解释了该怎么做:https://stackoverflow.com/a/12994104/20421925

Vitalii 的帖子有很多值得一看的地方(我自己仍在努力理解它)。如果您需要任何帮助来理解它,请告诉我。

评论

2赞 hfontanez 11/5/2022
这当然是一个很好的联系。对于这篇文章,只有构造函数适用;这就是为什么我的回答集中在构建器模式上。如果你检查一下链接,这是那里提到的唯一创造模式。此外,仅供参考,请注意仅链接的答案。他们在这里被认为是低质量的,他们被否决了很多。在答案中提供链接应该是为了支持你的答案,而不是作为答案本身。