I'm trying to make a class Box<T>. It should have two public immutable(val) properties, isContentMandatory: Boolean, content: T?. This is which combination of values I want to accept:
| isContentMandatory | content | Should allow? |
|---|---|---|
| false | null | YES |
| false | non-null | YES |
| true | null | NO |
| true | non-null | YES |
I want to make sure that the constructor(s) I provide won't allow the illegal state of an object. Also, I want multiple constructors(or use default values) so that creation of an object is straight-forward for the client. Following are examples of instantiations:
Box() // OK -> isContentMandatory = false, content = null
Box("some-content") // OK -> isContentMandatory = false, content = "some-content"
Box(false, "some-content") // OK -> isContentMandatory = false, content = "some-content"
Box(true, "some-content") // OK -> isContentMandatory = true, content = "some-content"
Box(true, null) // DON'T ALLOW
Box(true) // DON'T ALLOW
The DON'T ALLOWs from above should preferably be forbidden at compile-time(no constructor available for that combination) if it's possible. Otherwise, fail with the exception during creation.
I'm coming from Java world so all those primary/secondary constructors, default values and etc. are a bit fuzzy so please explain along with a solution. I'm also open to different class design if it supports the same business logic.
EDIT: this is how it would look in Java.
public class Box<T> {
private final boolean isContentMandatory;
private final T content;
public Box() {
this(null);
}
public Box(T content) {
this(false, content);
}
public Box(boolean isContentMandatory, T content) {
if (isContentMandatory && content == null) {
throw new IllegalArgumentException("Invalid combination of parameters");
}
this.isContentMandatory = isContentMandatory;
this.content = content;
}
...getters...
}