How to enforce order of setting parameters through Builder Pattern












2















Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.



I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?



class Example{
private int A;
private int B;

public static class Builder{
}


}










share|improve this question


















  • 3





    You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

    – Andy Turner
    Jan 1 at 9:35











  • @AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

    – Ankur
    Jan 1 at 9:41
















2















Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.



I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?



class Example{
private int A;
private int B;

public static class Builder{
}


}










share|improve this question


















  • 3





    You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

    – Andy Turner
    Jan 1 at 9:35











  • @AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

    – Ankur
    Jan 1 at 9:41














2












2








2


1






Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.



I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?



class Example{
private int A;
private int B;

public static class Builder{
}


}










share|improve this question














Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.



I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?



class Example{
private int A;
private int B;

public static class Builder{
}


}







java builder-pattern






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 1 at 9:32









rakkurakku

111




111








  • 3





    You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

    – Andy Turner
    Jan 1 at 9:35











  • @AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

    – Ankur
    Jan 1 at 9:41














  • 3





    You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

    – Andy Turner
    Jan 1 at 9:35











  • @AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

    – Ankur
    Jan 1 at 9:41








3




3





You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

– Andy Turner
Jan 1 at 9:35





You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.

– Andy Turner
Jan 1 at 9:35













@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

– Ankur
Jan 1 at 9:41





@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?

– Ankur
Jan 1 at 9:41












2 Answers
2






active

oldest

votes


















1














To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.



One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.



Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.






share|improve this answer































    0














    the main idea is to use a different return type in setA setB method, but those type must be the same type or subtype of the builder type.



    public class ExampleBuilderImpl implements  FullExampleBuilder {
    private int a;
    private int b;



    public Example createExample() {
    return new Example(a, b);
    }

    @Override
    public PartExampleBuilder setB(int b) {
    this.b = b;
    return this;
    }

    @Override
    public FullExampleBuilder setA(int a) {
    this.a = a;
    return this;
    }


    public static void main(String args) {


    ExampleBuilderImpl builder = new ExampleBuilderImpl();

    // compiler error
    // builder.setB(1).setA();

    builder.setA(1).setB(2);

    }


    }



    public interface FullExampleBuilder extends PartExampleBuilder {
    FullExampleBuilder setA(int a);

    }



    public interface PartExampleBuilder {
    PartExampleBuilder setB(int b);
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994370%2fhow-to-enforce-order-of-setting-parameters-through-builder-pattern%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.



      One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.



      Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.






      share|improve this answer




























        1














        To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.



        One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.



        Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.






        share|improve this answer


























          1












          1








          1







          To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.



          One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.



          Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.






          share|improve this answer













          To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.



          One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.



          Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 1 at 9:42









          Andy TurnerAndy Turner

          83.4k983141




          83.4k983141

























              0














              the main idea is to use a different return type in setA setB method, but those type must be the same type or subtype of the builder type.



              public class ExampleBuilderImpl implements  FullExampleBuilder {
              private int a;
              private int b;



              public Example createExample() {
              return new Example(a, b);
              }

              @Override
              public PartExampleBuilder setB(int b) {
              this.b = b;
              return this;
              }

              @Override
              public FullExampleBuilder setA(int a) {
              this.a = a;
              return this;
              }


              public static void main(String args) {


              ExampleBuilderImpl builder = new ExampleBuilderImpl();

              // compiler error
              // builder.setB(1).setA();

              builder.setA(1).setB(2);

              }


              }



              public interface FullExampleBuilder extends PartExampleBuilder {
              FullExampleBuilder setA(int a);

              }



              public interface PartExampleBuilder {
              PartExampleBuilder setB(int b);
              }





              share|improve this answer




























                0














                the main idea is to use a different return type in setA setB method, but those type must be the same type or subtype of the builder type.



                public class ExampleBuilderImpl implements  FullExampleBuilder {
                private int a;
                private int b;



                public Example createExample() {
                return new Example(a, b);
                }

                @Override
                public PartExampleBuilder setB(int b) {
                this.b = b;
                return this;
                }

                @Override
                public FullExampleBuilder setA(int a) {
                this.a = a;
                return this;
                }


                public static void main(String args) {


                ExampleBuilderImpl builder = new ExampleBuilderImpl();

                // compiler error
                // builder.setB(1).setA();

                builder.setA(1).setB(2);

                }


                }



                public interface FullExampleBuilder extends PartExampleBuilder {
                FullExampleBuilder setA(int a);

                }



                public interface PartExampleBuilder {
                PartExampleBuilder setB(int b);
                }





                share|improve this answer


























                  0












                  0








                  0







                  the main idea is to use a different return type in setA setB method, but those type must be the same type or subtype of the builder type.



                  public class ExampleBuilderImpl implements  FullExampleBuilder {
                  private int a;
                  private int b;



                  public Example createExample() {
                  return new Example(a, b);
                  }

                  @Override
                  public PartExampleBuilder setB(int b) {
                  this.b = b;
                  return this;
                  }

                  @Override
                  public FullExampleBuilder setA(int a) {
                  this.a = a;
                  return this;
                  }


                  public static void main(String args) {


                  ExampleBuilderImpl builder = new ExampleBuilderImpl();

                  // compiler error
                  // builder.setB(1).setA();

                  builder.setA(1).setB(2);

                  }


                  }



                  public interface FullExampleBuilder extends PartExampleBuilder {
                  FullExampleBuilder setA(int a);

                  }



                  public interface PartExampleBuilder {
                  PartExampleBuilder setB(int b);
                  }





                  share|improve this answer













                  the main idea is to use a different return type in setA setB method, but those type must be the same type or subtype of the builder type.



                  public class ExampleBuilderImpl implements  FullExampleBuilder {
                  private int a;
                  private int b;



                  public Example createExample() {
                  return new Example(a, b);
                  }

                  @Override
                  public PartExampleBuilder setB(int b) {
                  this.b = b;
                  return this;
                  }

                  @Override
                  public FullExampleBuilder setA(int a) {
                  this.a = a;
                  return this;
                  }


                  public static void main(String args) {


                  ExampleBuilderImpl builder = new ExampleBuilderImpl();

                  // compiler error
                  // builder.setB(1).setA();

                  builder.setA(1).setB(2);

                  }


                  }



                  public interface FullExampleBuilder extends PartExampleBuilder {
                  FullExampleBuilder setA(int a);

                  }



                  public interface PartExampleBuilder {
                  PartExampleBuilder setB(int b);
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 1 at 11:42









                  宏杰李宏杰李

                  8,76921123




                  8,76921123






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994370%2fhow-to-enforce-order-of-setting-parameters-through-builder-pattern%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                      ts Property 'filter' does not exist on type '{}'

                      mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window