Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use Builder pattern from the constructor in a subclass

Tags:

java

builder

I am currently using the Builder pattern, following closely the Java implementation suggested in the Wikipedia article Builder pattern http://en.wikipedia.org/wiki/Builder_pattern

This is a sample code that ilustrates my implementation

public class MyPrimitiveObject {
  private String identifier="unknown";
  public static class Builder {
    private final MyPrimitiveObject obj = new MyPrimitiveObject();
    public MyPrimitiveObject build() { return obj; }
    public Builder setidentifier (String val) {
     obj.identifier = val;
     return this;
    }
  }
  public static Builder createBuilder() { return new Builder(); }
  @Override public String toString() { return "ID: "+identifier; }
}

In some of my applications that use this class, I happen to find very similar building code , so I thought to subclass MyPrimitiveObject in MySophisticatedObject and move all my repeated code into its constructor.. and here is the problem.

How may I invoke the superclass Builder and assign its returned object as my instance?

public class MySophisticatedObject extends MyPrimitiveObject {
  private String description;
  public MySophisticatedObject (String someDescription) {
    // this should be the returned object from build() !!
    Builder().setidentifier(generateUUID()).build()
    description = someDescription;
  }     
}
like image 274
PA. Avatar asked Apr 10 '12 16:04

PA.


People also ask

When should you use the builder pattern?

Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.” It is used to construct a complex object step by step and the final step will return the object.

What does builder () build () do?

It returns the builder itself, so that the setter calls can be chained, as in the above example. In the builder: A build() method which calls the method, passing in each field. It returns the same type that the target returns.

What do you mean by subclass constructor method?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.


1 Answers

You might want to consider having a nested MySophisticatedObject.Builder which extends MyPrimitiveObject.Builder, and overrides its build() method. Have a protected constructor in the builder to accept the instance on which to set values:

public class MyPrimitiveObject {
  private String identifier="unknown";
  public static class Builder {
    private final MyPrimitiveObject obj;
    public MyPrimitiveObject build() { return obj; }
    public Builder setidentifier (String val) {
     obj.identifier = val;
     return this;
    }

    public Builder() {
        this(new MyPrimitiveObject());
    }

    public Builder(MyPrimitiveObject obj) {
        this.obj = obj;
    }
  }
  ...
}

public class MySophisticatedObject extends MyPrimitiveObject {
  private String description;

  public static class Builder extends MyPrimitiveObject.Builder {
    private final MySophisticatedObject obj;
    public Builder() {
      this(new MySophisticatedObject());
      super.setIdentifier(generateUUID());
    }     
    public Builder(MySophisticatedObject obj) {
      super(obj);
      this.obj = obj;
    }

    public MySophisticatedObject build() {
      return obj;
    }

    // Add code to set the description etc.
  }
}
like image 186
Jon Skeet Avatar answered Sep 22 '22 17:09

Jon Skeet