类构造函数中大量参数的优雅替代方案

时间:2011-06-18 12:21:53

标签: java constructor arguments

例如,我有一个构建GUI的类,一个处理GUI所有事件的类,以及包含受GUI对象影响的所有对象(主要是滑块)和GUI实例的主类。 -class和event-class。

现在,事件类的构造函数具有GUI类和GUI所更改的每个对象作为参数。这些都是相当多的对象,所以我现在拥有的论据数量大约是8,而且还在增长。

我的问题是否有更优雅的解决方案,30个参数根本感觉不对?

ps,我宁愿不合并类,因为这三个都很大,并且会使所有内容的可读性降低。

4 个答案:

答案 0 :(得分:12)

在这种情况下,通常使用具有流利语法的构建器对象。你改变了:

new XYZEvent(a, null, null, b, null, c, d, null, null)

new XYZEventBuilder().setA(a).setB(b).setC(c).setD(d).build()

答案 1 :(得分:4)

您可以创建一个包含所有参数的默认值的配置类:

public class GUIConfig {

  private String name = "default";
  // more private declarations

  public GUIConfig() {
    // constructor, just for setting defaults
  }

  // getters and setters

}

现在您可以像这样简单地创建GUI类实例:

GUIConfig guiConfig = new GUIConfig();
guiConfig.setName("foo");
// more setters
GUI myGUI = new GUI(guiConfig);

或仅使用默认值:

GUI myGUI = new GUI(new GUIConfig());

答案 2 :(得分:3)

使用DTO(Data Transfer Object)来保存所有课程。然后可以在单个参数中传递它。

  

DTO没有任何行为   除了存储和检索   自己的数据

答案 3 :(得分:0)

您应该考虑使用Google的AutoValue库:https://github.com/google/auto/blob/master/value/userguide/index.md

@AutoValue
public abstract class Card {
    @Nullable 
    public abstract Integer localId();

    public abstract Long utcStart();

    public abstract Integer paramA();

    public abstract Integer paramB();

    @Nullable 
    public abstract Boolean paramC();

    public static Builder builder() {
        return new AutoValue_Card.Builder();
    }

    @AutoValue.Builder
    public abstract static class Builder {
        public abstract Builder setLocalId(final Integer localId);
        public abstract Builder setUtcStart(final Long utcStart);
        public abstract Builder setParamA(final Integer paramA);
        public abstract Builder setParamB(final Integer paramB);
        public abstract Builder setParamC(final Boolean paramC);
        public abstract Card build();
    }
}

所有非必填字段都可以使用@Nullable进行注释。

要创建一个不可变的Card对象,只需使用它:

Card myCard = Card.builder()
                .setLocalId(123456)  // this line can be omitted
                .setUtcStart(158632478000)
                .setParamA(5)
                .setParamB(58)
                .setParamC(true) // this line can be omitted
                .build();

“AutoValue是一个很好的工具,可以消除在Java中编写普通值类的苦差事。它将大部分建议都包含在Effective Java第2章中,让您可以专注于程序中更有趣的方面。可能会更短,更清晰,更容易出错。两个竖起大拇指。“

- Joshua Bloch,作者,Effective Java