public abstract class EField extends EMessageObject implements Serializable
EField. This allows instances of
the application class to be serialized to a
ByteBuffer. The application class must also
define public static Builder builder() and the
Builder inner class. See
Note: EField subclasses are limited
to 31 fields. This is due to eBus binary serialization format.
EMessageObject shows how EMessage and
EField need to define a builder inner class used to
construct a subclass. But the example assumed that the
subclass was final. This example shows how to define
builders for a non-final EField class. The example
also applies to EMessage. The following examples
show two classes: UserInfo and its subclass
Employee.
public class UserInfo
extends EField
{
public final String name;
public final int age;
private UserInfo(final Builder<?, ?> builder) {
super (builder);
this.name = builder.mName;
this.age = builder.mAge;
}
// builder code explained below.
}
public final class Employee
extends UserInfo
{
public final String department;
private Employee(final Builder builder) {
super (builder);
this.department = builder.mDepartment;
}
// builder code explained below.
}
Class UserInfo can be instantiated on its own or as
Employee superclass. Because of this UserInfo
is required to have two builder inner classes. The first is
an abstract builder which the Employee builder
extends. The second is a concrete builder used to create
UserInfo instances.
public static abstract class Builder<M extends UserInfo,
B extends Builder<M, ?>>
extends EField.Builder<M, B>
{
private String mName;
private int mAge;
// Protected constructor to allow subclass access.
protected Builder(final Class<? extends EMessageObject> targetClass) {
super (targetClass);
mAge = -1;
}
public B name(final String value)
{
if (name == null || name.isEmpty()) {
throw (new IllegalArgumentException("value is null or empty"));
}
mName = value;
return ((B) this);
}
public B age(final int value)
{
if (age < 0) {
throw (new IllegalArgumentException("value < zero"));
}
mAge = age;
return ((B) this);
}
@Override protected void validate(final List<String> problems)
{
super.validate(problems);
if (mName == null) { problems.add("name not set"); }
if (mAge < 0) { problems.add("age not set"); }
}
// Since this class is abstract do not override buildImpl method.
}
Since Builder is abstract it must use have the two
class parameters M and B which are then passed
to the superclass builder. Note that the setters use B
in the method signature so that the subclass type is returned
rather than UserInfo.Builder. Method buildImpl
is not defined since that is only done in concrete builders.
UserInfo.ConcreteBuilder extends
UserInfo.Builder and defines buildImpl. There
is nothing else for ConcreteBuilder to do since the
setters and validation methods are provided by the superclass.
public static final class ConcreteBuilder
extends Builder<UserInfo, ConcreteBuilder>
{
private ConcreteBuilder() {
super (UserInfo.class);
}
@Override protected UserInfo buildImpl()
{
return (new UserInfo(this));
}
}
UserInfo.builder method returns a
UserInfo.ConcreteBuilder instance since that class is
responsible for creating UserInfo instances. But the
return type is the abstract UserInfo.Builder.
public static Builder builder() {
return (new ConcreteBuilder());
}
Employee.Builder is as you expect: it extends
UserInfo.Builder, defines the department
setter method, validates the builder configuration, and
builds the Employee instance.
public static final class Builder
extends UserInfo.Builder<Employee, Builder>
{
private String mDepartment;
private Builder() {
super (Employee.class);
}
public Builder department(final String value) {
if (value == null || value.isEmpty()) {
throw (new IllegalArgumentException("value is null or empty"));
}
mDepartment = value;
return (this);
}
@Override protected void validate(List<String> problems) {
super.validate(problems);
if (mDepartment == null) { problems.add("department not set"); }
}
@Override protected Employee buildImpl() {
return (new Employee(this));
}
}EMessageObject,
EMessage,
Serialized Form| Modifier and Type | Class and Description |
|---|---|
static class |
EField.Builder<M extends EField,B extends EField.Builder<M,?>> |
MAX_FIELDS| Modifier | Constructor and Description |
|---|---|
|
EField()
Creates a new eBus field instance.
|
protected |
EField(EField.Builder<?,?> builder) |
public EField()
throws InvalidMessageException
MessageType requires
access.InvalidMessageException - if this field violates the eBus correct field rules.protected EField(EField.Builder<?,?> builder)
Copyright © 2019. All rights reserved.