Reputation: 55
I am building web app with two entities :
These two classes inherit from the abstract class Book. the Book class will have common variables for both classes: id, title, releaseDate, coverID;
And I am using Pattern Builder to create Manga and Volume objects. But When I am trying to setDescription I am getting this error:
Manga manga = (Manga) new Manga.Builder().setID(id)
.setTitle(title)
.setCoverID(id)
.setDescription() //Cannot resolve method 'setDescription' in 'Builder'
.build();
Book class:
public abstract class Book<T extends Book> {
public final Long id;
public final String title;
protected Book(final Builder<T> builder) {
this.id = builder.id;
this.title = builder.title;
}
public abstract static class Builder<T> {
private Long id;
private String title;
public Builder<T> setID(Long id) {
this.id = id;
return this;
}
public Builder<T> setTitle(String title) {
this.title = title;
return this;
}
public abstract T build();
}
My Manga class:
public class Manga extends Book<Manga> {
private final String description;
protected Manga(Builder builder) {
super(builder);
this.description = builder.description;
}
public static class Builder extends Book.Builder<Manga> {
private String description;
public Builder setDescription(String description) {
this.description = description;
return this;
}
@Override
public Manga build() {
return new Manga(this);
}
}
Or is there an even better solution?
Thanks.
Upvotes: 0
Views: 456
Reputation: 1064
This here should work:
package de.dwosch;
public abstract class Book {
public final Long id;
public final String title;
protected Book(final Builder<?> builder) {
this.id = builder.id;
this.title = builder.title;
}
public abstract static class Builder<T extends Builder<T>> {
private Long id;
private String title;
public T id(Long id) {
this.id = id;
return me();
}
public T title(String title) {
this.title = title;
return me();
}
public abstract T me();
public abstract Book build();
}
}
And then
package de.dwosch;
public class Manga extends Book {
private final String description;
protected Manga(Builder builder) {
super(builder);
this.description = builder.description;
}
public static class Builder extends Book.Builder<Builder> {
private String description;
public Builder description(String description) {
this.description = description;
return this;
}
@Override
public Builder me() {
return this;
}
@Override
public Manga build() {
return new Manga(this);
}
}
}
Usage
Manga manga = new Manga.Builder().description("test")
.title("title")
.build();
I have already implemented this pattern several times. Joshua Bloch writes about it in his book Effective Java (great Book btw).
If you need further information on this let me know.
Btw: Personal preference - setter methods without set
on the builder flow. Looks 'cleaner' :)
Upvotes: 1