【问题标题】:Multiple optional arguments in constructor in Java - exponential number of constructorsJava中构造函数中的多个可选参数 - 构造函数的指数数量
【发布时间】:2012-04-15 10:15:25
【问题描述】:

这是我遇到过几次但还没有找到满意答案的问题。这似乎很愚蠢,但是在谷歌上搜索了一段时间后,我想不出什么好东西。

假设我有一个包含 20 个实例变量的类,每个变量都是可选的(是否会被初始化)。

现在我希望我的构造函数处理所有情况,如果有几个实例变量很好,我可以创建具有不同签名的构造函数,但这里我有 20 个,所以我需要 2 ^20=1,048,576 构造函数来处理所有情况!这似乎......不是很理想,你不同意吗?

因此,由于使用这种蛮力方法,我基本上必须构造 2^n 个构造函数,其中 n 是实例变量的数量,我想找到一种更好的方法。

我已经看到了几个解决这个问题的方法,但我相信它们都是基于数据的假设,但在我的情况下,这些变量中的每一个都可以随机初始化或不随机初始化,我无法在初始化之前知道.

我正在寻找一些可以应用的设计模式或想法,以使我的代码更加...可维护(不用担心,我没有创建 1M+ 构造函数 :)

谢谢。

【问题讨论】:

  • 豆模式。构造函数没有参数,所有参数都通过设置器进入。
  • 这看起来很傻,我说我有 20 个实例变量,但实际上我有更多,我不想调用 20 个不同的 setter!它在执行过程中可能处于不一致的状态,这似乎是一个非常糟糕的解决方案。
  • 这也禁止我让我的类不可变。

标签: java design-patterns constructor


【解决方案1】:
【解决方案2】:

将 Bean 模式与 Builder 结合起来。 YourObject 在构建过程中不会出现不一致的状态,但仍需要 20 多次设置操作,并且您可以将 YourObject 设为不可变(如果您愿意)——但 YourObjectBuilder 不行。

public class YourObject {
    private Type field1;
    private Type field2;
    private Type field3;
    ...
    YourObject ( Type field1 , Type field2 , Type field3 ... ) { }
}

public class YourObjectBuilder {
    private Type field1;
    private Type field2;
    private Type field3;
    ...

    public YourObjectBuilder() {
    }

    public YourObject make ( ) {
         return new YourObject ( field1 , field2 , field3 ... ) ;
    }

    public void setField1(Type t) {
        field1 = t;
    }

   public void setField2(Type t) {
        field2 = t;
   }

    public void setField3(Type t) {
        field3 = t;
    }
    ...
}

【讨论】:

  • 这听起来是一个不错的解决方案,而且比 Bean 模式更好,谢谢!
【解决方案3】:
public class YourObject {
    private Type field1;
    private Type field2;
    private Type field3;
    ...

    public YourObject() {
    }

    public void setField1(Type t) {
        field1 = t;
    }

   public void setField2(Type t) {
        field2 = t;
   }

    public void setField3(Type t) {
        field3 = t;
    }
    ...
}

【讨论】:

  • 正如我在上面的评论中所说,这种或方法的问题是我的对象在其构造过程中可能处于不一致的状态!这对我来说非常危险,我真的负担不起。而且你必须让你的类可变,这是我不想要的。
  • @linker 只有在完成创建之前将对象传递给其他方法时,该对象才会在其构造过程中处于不一致状态。如果您需要担心可变性,您可以创建一个标志来确定字段是否可设置,并在您完成创建对象时切换它。
  • 我更多的是在多线程上下文中讨论。没错,我可以确保在构建完成之前不访问该对象,但这需要一些额外的努力来确保线程安全。
猜你喜欢
  • 2021-03-12
  • 2019-10-04
  • 1970-01-01
  • 2019-02-26
  • 2013-02-05
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
相关资源
最近更新 更多