Subclassing with Bloch’s Builder pattern

Update: There’s a newer version of the code in this post; the newer version allows you to call the arguments in any order.


A co-worker of mine recently ran across this post by Eamonn McManus, “Using the builder pattern with subclasses,” and after due consideration, settled on what McManus calls “a shorter, smellier variant.”

Shorter because:

  1. it has only one Builder class per class

Smellier because:

  1. it uses raw types
  2. the builder’s self() method requires an unchecked cast

Frankly, I don’t find the shortness here a compelling argument for the smell, but I also think there’s more shortness to be found in McManus’ design while remaining fragrant. Thus:

class Shape
{
    private final double opacity;

    public double getOpacity()
    {
        return opacity;
    }

    public static abstract class Builder<T extends Shape> {

        private double opacity;

        public Builder<T> opacity(double opacity) {
            this.opacity = opacity;
            return this;
        }

        public abstract T build();
    }

    public static Builder<?> builder() {
        return new Builder<Shape>()
        {
            @Override
            public Shape build()
            {
                return new Shape(this);
            }
        };
    }

    protected Shape(Builder<?> builder) {
        this.opacity = builder.opacity;
    }
}

class Rectangle extends Shape {

    private final double height;
    private final double width;

    public double getHeight()
    {
        return height;
    }

    public double getWidth()
    {
        return width;
    }

    public static abstract class Builder<T extends Rectangle> extends Shape.Builder<T> {
        private double height;
        private double width;

        public Builder<T> height(double height) {
            this.height = height;
            return this;
        }

        public Builder<T> width(double width) {
            this.width = width;
            return this;
        }
    }

    public static Builder<?> builder() {
        return new Builder<Rectangle>()
        {
            @Override
            public Rectangle build()
            {
                return new Rectangle(this);
            }
        };
    }

    protected Rectangle(Builder<?> builder) {
        super(builder);
        this.height = builder.height;
        this.width = builder.width;
    }
}

class RotatedRectangle extends Rectangle {
    private final double theta;

    public double getTheta()
    {
        return theta;
    }

    public static abstract class Builder<T extends RotatedRectangle> extends Rectangle.Builder<T> {
        private double theta;

        public Builder<T> theta(double theta) {
            this.theta = theta;
            return this;
        }
    }

    public static Builder<?> builder() {
        return new Builder<RotatedRectangle>()
        {
            @Override
            public RotatedRectangle build()
            {
                return new RotatedRectangle(this);
            }
        };
    }

    protected RotatedRectangle(Builder<?> builder) {
        super(builder);
        this.theta = builder.theta;
    }
}

class BuilderTest {
    public static void main(String[] args) {
        RotatedRectangle rotatedRectangle = RotatedRectangle.builder()
                .theta(Math.PI / 2)
                .width(640)
                .height(400)
                .opacity(0.5d)
                .build();
        System.out.println(rotatedRectangle.getTheta());
        System.out.println(rotatedRectangle.getWidth());
        System.out.println(rotatedRectangle.getHeight());
        System.out.println(rotatedRectangle.getOpacity());
    }
}

Now, some notes:

  1. Where McManus’ generics are of the self-referential, Builder<T extends Builder<T>> variety (cf. Enum), in mine a Builder<T> builds Ts. Personally I think this will give fewer developers headaches.
  2. My Builders don’t require a self() method; they simply return this.
  3. Like McManus’ preferred design, this one requires two Builders per class, one abstract and one concrete. However, the concrete one is an anonymous inner class, so it’s less obtrusive, and there’s only one “boilerplate” method per class. A little longer than the “smelly” version in that respect, but in my opinion livable.

9 thoughts on “Subclassing with Bloch’s Builder pattern

  1. I think the main of the original design was the ability to call the methods on the builder in any order. In your approach, I cannot not write

    RotatedRectangle.builder().opacity(0.5d).theta(Math.PI / 2).width(640).height(400).build();

  2. Hi David,

    try this test.
    The .width(111) cause syntax error

    public void testBla() {
    RotatedRectangle rotatedRectangle = RotatedRectangle.builder()
    .theta(Math.PI / 2)
    .width(640)
    .height(400)
    .height(400)
    .opacity(0.5d)
    .width(111)
    .opacity(0.5d)
    .width(222)
    .height(400)
    .width(640)
    .width(640)
    .build();
    System.out.println(rotatedRectangle.getTheta());
    System.out.println(rotatedRectangle.getWidth());
    System.out.println(rotatedRectangle.getHeight());
    System.out.println(rotatedRectangle.getOpacity());
    }

  3. Pingback: Show Your Work — Subclassing with Bloch’s Builder pattern, revised

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s