At my org we extensively use @Value.Immutable
annotation from the Immutables library to generate Immutable
classes (usually with builder
s) for our internal business objects (BOs). In our codebase I've seen both interface
s and abstract class
es being used for such BO definitions.
For example for a DeviceData
BO we could have an interface as follows
@Value.Immutable
@JsonDeserialize(as = ImmutableDeviceData.class)
public interface DeviceData {
@Value.Parameter
DeviceIdentifier deviceIdentifier();
@Value.Parameter
DeviceType deviceType(); // enum
}
or equivalently we could have abstract class with identical body as above interface
public
abstract class
DeviceData {
Either ways, we instantiate the BO as follows
final var myDeviceData = ImmutableDeviceData.builder()
.deviceIdentifier(ImmutableDeviceIdentifier.of("xxxx-xxxx")
.deviceType(DeviceType.Tablet)
.build();
At times we also add certain precondition checks using @Value.Check
annotations such as following, which again work identically with both interface
and abstract class
es
@Value.Immutable(builder = false)
public abstract class DeviceIdentifier {
@Value.Parameter
public String value();
@Value.Check
default void validate() {
Validate.notBlank(value(), "DeviceIdentifier cannot be blank");
}
}
Additionally there are situations where we have to declare static fields such as regex Pattern
in case of EmailAddress
BO; here again Java17 makes it possible in both abstract class and interfaces alike.
Considering this specific use case of Immutable business objects, are there any pros or cons of preferring abstract class
over interface
or vice-versa?