I'm trying to make a small hierarchy of classes to use the Builder pattern. There is only one abstract
class (sort of like a base class with common fields). This one has close to 15 fields/members, hence the builder approach.
This is how the abstract
class looks like:
public abstract class AbstractItem {
private Long id;
private String type;
private String status;
protected AbstractItem () { }
protected AbstractItem (final BuilderBase<?> builder) {
id = builder.id;
type = builder.type;
status = builder.status;
}
public Long getId() { return id; }
public String getType() { return type; }
public String getStatus() { return status; }
protected abstract static class BuilderBase<T extends BuilderBase<T>> {
private Long id;
private String type;
private String status;
protected abstract T self();
public T withId(final Long value) {
id = value;
return self();
}
public T withType(final String value) {
type = value;
return self();
}
public T withStatus(final String value) {
status = value;
return self();
}
// PROBLEM 1
// public abstract T build(); // Nice to have!
}
}
...and this could be one of the classes that extend from it:
public final class Item extends AbstractItem {
private String device;
public Item() { }
public Item(final BuilderBase<?> builder) {
super(builder);
device = builder.device;
}
public static BuilderBase<?> builder() { return new Builder(); }
public String getDevice() { return device; }
public static class BuilderBase<T extends BuilderBase<T>> extends AbstractItem.BuilderBase<T> {
private String device;
// PROBLEM 2
@Override
protected T self() { throw new IllegalStateException("Can't touch this!"); }
public T withDevice(final String value) {
device = value;
return self();
}
public Item build() { return new Item(this); }
}
protected static class Builder extends BuilderBase<Builder> {
@Override
protected Builder self() { return this; }
}
}
As it stands right now, it works:
return Item.builder()
.withId(1_100L)
.withType("ITEM_01")
.withStatus("CREATED")
.withDevice("MAGIC_SWORD")
.build();
But I have two problems here:
- Is there a way to implement correctly
protected T self()
for inherited classes? — so far I can only returnnull
from those or throw an exception. - Is there a way to declare
public abstract T build()
(in theabstract
BuilderBase
class) in such a way that classes that inherit from it must have to provide their own implementation?
Aucun commentaire:
Enregistrer un commentaire