1

I am trying to create a java class for a line graph (using builder pattern) that encloses many properties within. Based on the application of these properties, I am trying to create inner builder classes (such as X-Axis Properties, Y-Axis properties etc). I am new to Java and I would like to know if it is possible to invoke builder objects like below in my example. I followed through a link Can the builder pattern ever be doing too much?. that would build objects in increments. I liked the idea. However, I do not know how could I put it to use for my scenario.

Invoke method:

new LineGraph().UiPropBuilder(ctx)
               .setBackgroundColor(Color.BLUE)
               .build()
               .XAxisProperties()
               .enableGridLines(true)
               .build()
               .YAxisProperties()
               .enableGridLines(false)
               .build();

Is it possible to call .build() statement only once to create all objects instead of repeating it multiple times?

Class:

public class LineGraph{

   private LineGraph()

   public static class UiPropBuilder{

      private Integer mBackgroundColor;
      private Boolean bTouchEnabled;
      ...

      public UiPropBuilder (Context ctx) { this.ctx = ctx; }

      public UiPropBuilder setBackgroundColor(Integer mBackgroundColor){ this.mBackgroundColor = mBackgroundColor; return this;}

      public UiPropBuilder touchEnabled(Boolean bTouchEnabled){ this.bTouchEnabled = bTouchEnabled; return this;}

      ... some more properties...
      public UiPropBuilder build(){ return new UiPropBuilder(this); }     

   }

// X-Axis properties builder
public static class XAxisProperties{
   // variable declarations and constructor omitted
   public XAxisProperties enableGridLines(Boolean enable) {this.enable = enable); return this;}
   public XAxisProperties build(){ return new XAxisProperties(this);}


// Y-Axis properties Builder

public static class YAxisProperties{
   // variable declarations and constructor omitted
   public YAxisProperties enableGridLines(Boolean enable) {this.enable = enable); return this;}
   public YAxisProperties build(){ return new YAxisProperties(this);}
}
1
  • In your question "to call .build() statement only once to create all objects " . Were you meant to write "to call .build() statement only once to create the with all the properties set " Commented Apr 19, 2016 at 1:16

1 Answer 1

1

One way you could do it would be like this, where you have 3 builder objects that can all reference each other and switch between them. It's similar to what you were already trying to do:

public static class UiPropBuilder {
    private XAxisProperties xAxisProperties = new XAxisProperties();
    private YAxisProperties yAxisProperties = new YAxisProperties();
    // ...
    public XAxisProperties xAxisProperties() { return xAxisProperties; }
    public YAxisProperties yAxisProperties() { return yAxisProperties; }

    public LineGraph build() {
        return new LineGraph(..., ..., ..., ...);
    }

    public class XAxisProperties {
        // ...
        public YAxisProperties yAxisProperties() { yAxisProperties; }
        public UiPropBuilder uiProperties() { return UiPropBuilder.this; }
        public LineGraph build() { return UiPropBuilder.this.build(); }
    }

    public class YAxisProperties {
        // ...
        public XAxisProperties xAxisProperties() { return xAxisProperties; }
        public UiPropBuilder uiProperties() { return UiPropBuilder.this; }
        public LineGraph build() { return UiPropBuilder.this.build(); }
    }
}

A more complicated example is to write something similar to the way a step builder works. We define interfaces for each of the "steps" and implement all of them in a single class. Each of the methods that "switches" the properties actually returns this.

public interface BuildStep       { LineGraph        build();           }
public interface UiSwitchStep    { UiPropBuilder    uiProperties();    }
public interface XAxisSwitchStep { XAxisPropBuilder xAxisProperties(); }
public interface YAxisSwitchStep { YAxisPropBuilder yAxisProperties(); }

public interface UiPropBuilder
extends XAxisSwitchStep, YAxisSwitchStep, BuildStep {
    // UI property setters
    // ...
}

public interface XAxisPropBuilder
extends YAxisSwitchStep, UiSwitchStep, BuildStep {
    // X-axis property setters
    // ...
}

public interface YAxisPropBuilder
extends XAxisSwitchStep, UiSwitchStep, BuildStep {
    // Y-axis property setters
    // ...
}

private static class UiBuilderImpl
implements UiPropBuilder, XAxisPropBuilder, YAxisPropBuilder {
    // implement ALL property setters
    // ...

    @Override
    public XAxisProperties xAxisProperties() {
        return this;
    }
    @Override
    public YAxisProperties yAxisProperties() {
        return this;
    }
    @Override
    public UiPropBuilder uiProperties() {
        return this;
    }
    @Override
    public LineGraph build() {
        return new LineGraph(..., ..., ..., ...);
    }
}

// create new builders through a static method
// which returns the interface type
public static UiPropBuilder builder() {
    return new UiBuilderImpl();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.