强制类实例化规则

时间:2017-05-16 17:35:24

标签: java constructor objectinstantiation

考虑一个包含4个字段的基本bean格式类,构造函数和getter:

public class Foo {
    private final String id;
    private final Bar bar;
    private final boolean invalid;
    private final String errorMessage;

    public Foo(String id, Bar bar, boolean invalid, String errorMessage) {
        this.id = id;
        this.bar = bar;
        this.invalid = invalid;
        this.errorMessage = errorMessage;
    }
}

我想对班级用户施加一些规则。

例如:

  • id参数绝不能为null或为空
  • 当bar为非null时,invalid必须为false且errorMessage必须为null
  • 当errorMessage为非null时,bar必须为null
  • 当invalid为true时,errorMessage必须为非null非空,bar必须为null

这些规则基本上转化为4种有效的Foo对象:

(aString,false,null,null),(aString,false,aBar,null),(aString,true,null,anErrorMessage)和(aString,false,null,anErrorMessage)。

如何强制班级用户始终创建其中一个?

2 个答案:

答案 0 :(得分:1)

id的声音应该是final,也可能是其他字段。检查构造函数参数,如果它们出错则抛出运行时异常。使用assert记录不变量。像

这样的东西
public class Foo {
  private final String id;
  private final Bar bar;

  public Foo(String id, Bar bar) {
    if (id == null || bar == null) {
      throw new IllegalArgumentException("Constructor argument was null");
    }
    this.id = id;
    this.bar = bar;
    assert this.id != null && this.bar != null;
  }

  // Getters and overrides
}

看起来不需要invaliderrorMessage,它们本来就不应该是实例变量(字段)。

答案 1 :(得分:0)

  

创建Foo时,我可以强制类的用户尊重它们吗?   对象

是的,最好在构造函数中执行此操作。基本上,您可以在构造函数中执行所有验证(或调用其他方法来完成工作),并且当用户尝试实例化对象时,如果满足任何条件,那么您应该抛出一个表明原因的例外。

  

我应该使用重载的构造函数吗?

我建议在一个构造函数中执行此操作,并在需要时使用其他方法验证各个详细信息。

如果您认为某些内置异常没有描述抛出异常的原因,那么您可以使用足够的详细信息实现自己的异常,以向类的用户标识未实例化对象的原因

读数:

<强> Builder Pattern