Why do we need a Builder class when implementing a Builder pattern?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












I have seen many implementations of the Builder pattern (mainly in Java). All of them have an entity class (let's say a Person class), and a builder class PersonBuilder. The builder "stacks" a variety of fields and returns a new Person with the arguments passed. Why do we explicitly need a builder class, instead of putting all the builder methods in the Person class itself?



For example:



class Person 

private String name;
private Integer age;

public Person()


Person withName(String name)
this.name = name;
return this;


Person withAge(int age)
this.age = age;
return this;




I can simply say Person john = new Person().withName("John");



Why the need for a PersonBuilder class?



The only benefit I see, is we can declare the Person fields as final, thus ensuring immutability.










share|improve this question









New contributor




Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.























    up vote
    1
    down vote

    favorite












    I have seen many implementations of the Builder pattern (mainly in Java). All of them have an entity class (let's say a Person class), and a builder class PersonBuilder. The builder "stacks" a variety of fields and returns a new Person with the arguments passed. Why do we explicitly need a builder class, instead of putting all the builder methods in the Person class itself?



    For example:



    class Person 

    private String name;
    private Integer age;

    public Person()


    Person withName(String name)
    this.name = name;
    return this;


    Person withAge(int age)
    this.age = age;
    return this;




    I can simply say Person john = new Person().withName("John");



    Why the need for a PersonBuilder class?



    The only benefit I see, is we can declare the Person fields as final, thus ensuring immutability.










    share|improve this question









    New contributor




    Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have seen many implementations of the Builder pattern (mainly in Java). All of them have an entity class (let's say a Person class), and a builder class PersonBuilder. The builder "stacks" a variety of fields and returns a new Person with the arguments passed. Why do we explicitly need a builder class, instead of putting all the builder methods in the Person class itself?



      For example:



      class Person 

      private String name;
      private Integer age;

      public Person()


      Person withName(String name)
      this.name = name;
      return this;


      Person withAge(int age)
      this.age = age;
      return this;




      I can simply say Person john = new Person().withName("John");



      Why the need for a PersonBuilder class?



      The only benefit I see, is we can declare the Person fields as final, thus ensuring immutability.










      share|improve this question









      New contributor




      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I have seen many implementations of the Builder pattern (mainly in Java). All of them have an entity class (let's say a Person class), and a builder class PersonBuilder. The builder "stacks" a variety of fields and returns a new Person with the arguments passed. Why do we explicitly need a builder class, instead of putting all the builder methods in the Person class itself?



      For example:



      class Person 

      private String name;
      private Integer age;

      public Person()


      Person withName(String name)
      this.name = name;
      return this;


      Person withAge(int age)
      this.age = age;
      return this;




      I can simply say Person john = new Person().withName("John");



      Why the need for a PersonBuilder class?



      The only benefit I see, is we can declare the Person fields as final, thus ensuring immutability.







      java design-patterns builder-pattern






      share|improve this question









      New contributor




      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 2 hours ago









      Robert Harvey

      163k39373587




      163k39373587






      New contributor




      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 4 hours ago









      Boyan Kushlev

      1095




      1095




      New contributor




      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Boyan Kushlev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          4
          down vote













          One reason would be to ensure that all of the passed-in data follows business rules.



          Your example doesn't take this into consideration, but let's say that someone passed in an empty string, or a string consisting of special characters. You would want to do some sort of logic based around making sure that their name is actually a valid name (which is actually a very difficult task).



          You could put that all in your Person class, especially if the logic is very small (for example, just making sure that an age is non-negative) but as the logic grows it makes sense to separate it.






          share|improve this answer
















          • 1




            The example in the question provides a simple rule violation: there isn't an age given for john
            – Caleth
            3 hours ago


















          up vote
          1
          down vote













          Why use/provide a builder class:



          • To make immutable objects — the benefit you've identified already.  Useful if the construction takes multiple steps.  FWIW, immutability should be seen a significant tool in our quest to write maintainable and bug free programs.

          • If the runtime representation of the final (possibly immutable) object is optimized for reading and/or space usage, but not for update.  String and StringBuilder are good examples here.  Repeatedly concatenating strings is not very efficient, so the StringBuilder uses a different internal representation that is good for appending — but not as good on space usage, and not as good for reading and using as the regular String class.

          • To clearly separate constructed objects from objects under construction.  This approach requires a clear transition from under-construction to constructed.  For the consumer, there is no way to confuse an under-construction object with a constructed object: the type system will enforce this.  That means sometimes we can use this approach to "fall into the pit of success", as it were, and, when making abstraction for others (or ourselves) to use (like an API or a layer), this can be a very good thing.





          share|improve this answer



























            up vote
            1
            down vote













            The builder permits you an object to work with across space and time that explicitly isn't the final object, thus protecting you from mistakes and broken semantics. This permits your domain objects to strictly enforce validity at all times, if that sort of thing tickles your fancy. And at the very least, it can facilitate never having a Widget laying around that isn't actually a Widget, according to your business rules.






            share|improve this answer



























              up vote
              0
              down vote













              Another reason that hasn't been explicitly mentioned here already, is that the build() method can verify that all fields are set, which is probably the most likely failure mode that would otherwise occur.



              Another benefit is that your Person object would end up having a more simple lifetime and a simple set of invariant. You know that once you have a Person p, you have a p.name and a valid p.age. None of your methods have to be designed to handle situations like "well what if age is set but not name, or what if name is set but not age?" This reduces the overall complexity of the class.






              share|improve this answer




















              • "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                – Vincent Savard
                42 mins ago


















              up vote
              0
              down vote













              It looks like you're talking about Josh Blochs Builder Pattern. This should not be confused with the Gang of Four Builder Pattern. These are different beasts. They both solve construction problems but in fairly different ways.



              I assume the other class you're referring to is the anonymous inner class that Josh calls for. It can be a separate full blown class if you like and don't mind using a long constructor like an API that humans rarely touch but the classic case is an anonymous inner class that keeps you immutable by delaying building the person class until it has all the info it needs to fully build it in one shot.



              The truth is you can construct your object without using another class. But then you have to choose. You lose either the ability to simulate named parameters in languages that don't have them (like java) or you lose the ability to remain immutable throughout the objects lifetime.



              Immutable example, has no names for parameters



              Person p = new Person("Arthur Dent", 42);


              You can build everything with a single simple factory method or even a constructor. This will let you stay immutable but you loose the simulation of named parameters. That gets hard to read with many parameters. Computers don't care but it's hard on the humans.



              Simulated named parameter example with traditional setters. Not immutable.



              Person p = new Person();
              p.name("Arthur Dent");
              p.age(42);


              You can do everything with setters. Whether or not they return this is only important users of your class hate coming up with meaningful names for intermediate steps. What's important here is that while you are still kind of simulating named parameters you're no longer immutable. Each use of a setter changes object state.



              So what you get by adding the class is you can do both. It just demands you do a lot of keyboard typing.



              As for business rules, even following Josh Blochs builder pattern with his inner class you don't get to enforce that anything gets called besides your first required parameters method and build. The required parameters don't get to simulate named parameters here. Just the optional ones do.



              If you want to simulate named parameters for your required parameters you need more then the Josh Bloch builder. You need an internal Domain Specific Language (iDSL).



              This lets you demand that they call age() and name() before calling build(). But you can't do it just by returning this each time. Each thing that returns returns a different thing that forces you to call the next thing.



              Use might look like this:



              Person p = personBuilder
              .name("Arthur Dent")
              .age(42)
              .build()
              ;


              But this:



              Person p = personBuilder
              .age(42)
              .build()
              ;


              is a compiler error because age() is only valid to call on the type returned by name().



              These iDSLs are extremely powerful (JOOQ for example) and very nice to use but they are a fair bit of work to set up. I'd recommend saving them for things that will have a fair bit of source code written against them.






              share|improve this answer






















                Your Answer







                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "131"
                ;
                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',
                convertImagesToLinks: false,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );






                Boyan Kushlev is a new contributor. Be nice, and check out our Code of Conduct.









                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f380397%2fwhy-do-we-need-a-builder-class-when-implementing-a-builder-pattern%23new-answer', 'question_page');

                );

                Post as a guest






























                5 Answers
                5






                active

                oldest

                votes








                5 Answers
                5






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                4
                down vote













                One reason would be to ensure that all of the passed-in data follows business rules.



                Your example doesn't take this into consideration, but let's say that someone passed in an empty string, or a string consisting of special characters. You would want to do some sort of logic based around making sure that their name is actually a valid name (which is actually a very difficult task).



                You could put that all in your Person class, especially if the logic is very small (for example, just making sure that an age is non-negative) but as the logic grows it makes sense to separate it.






                share|improve this answer
















                • 1




                  The example in the question provides a simple rule violation: there isn't an age given for john
                  – Caleth
                  3 hours ago















                up vote
                4
                down vote













                One reason would be to ensure that all of the passed-in data follows business rules.



                Your example doesn't take this into consideration, but let's say that someone passed in an empty string, or a string consisting of special characters. You would want to do some sort of logic based around making sure that their name is actually a valid name (which is actually a very difficult task).



                You could put that all in your Person class, especially if the logic is very small (for example, just making sure that an age is non-negative) but as the logic grows it makes sense to separate it.






                share|improve this answer
















                • 1




                  The example in the question provides a simple rule violation: there isn't an age given for john
                  – Caleth
                  3 hours ago













                up vote
                4
                down vote










                up vote
                4
                down vote









                One reason would be to ensure that all of the passed-in data follows business rules.



                Your example doesn't take this into consideration, but let's say that someone passed in an empty string, or a string consisting of special characters. You would want to do some sort of logic based around making sure that their name is actually a valid name (which is actually a very difficult task).



                You could put that all in your Person class, especially if the logic is very small (for example, just making sure that an age is non-negative) but as the logic grows it makes sense to separate it.






                share|improve this answer












                One reason would be to ensure that all of the passed-in data follows business rules.



                Your example doesn't take this into consideration, but let's say that someone passed in an empty string, or a string consisting of special characters. You would want to do some sort of logic based around making sure that their name is actually a valid name (which is actually a very difficult task).



                You could put that all in your Person class, especially if the logic is very small (for example, just making sure that an age is non-negative) but as the logic grows it makes sense to separate it.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 4 hours ago









                Deacon

                3115




                3115







                • 1




                  The example in the question provides a simple rule violation: there isn't an age given for john
                  – Caleth
                  3 hours ago













                • 1




                  The example in the question provides a simple rule violation: there isn't an age given for john
                  – Caleth
                  3 hours ago








                1




                1




                The example in the question provides a simple rule violation: there isn't an age given for john
                – Caleth
                3 hours ago





                The example in the question provides a simple rule violation: there isn't an age given for john
                – Caleth
                3 hours ago













                up vote
                1
                down vote













                Why use/provide a builder class:



                • To make immutable objects — the benefit you've identified already.  Useful if the construction takes multiple steps.  FWIW, immutability should be seen a significant tool in our quest to write maintainable and bug free programs.

                • If the runtime representation of the final (possibly immutable) object is optimized for reading and/or space usage, but not for update.  String and StringBuilder are good examples here.  Repeatedly concatenating strings is not very efficient, so the StringBuilder uses a different internal representation that is good for appending — but not as good on space usage, and not as good for reading and using as the regular String class.

                • To clearly separate constructed objects from objects under construction.  This approach requires a clear transition from under-construction to constructed.  For the consumer, there is no way to confuse an under-construction object with a constructed object: the type system will enforce this.  That means sometimes we can use this approach to "fall into the pit of success", as it were, and, when making abstraction for others (or ourselves) to use (like an API or a layer), this can be a very good thing.





                share|improve this answer
























                  up vote
                  1
                  down vote













                  Why use/provide a builder class:



                  • To make immutable objects — the benefit you've identified already.  Useful if the construction takes multiple steps.  FWIW, immutability should be seen a significant tool in our quest to write maintainable and bug free programs.

                  • If the runtime representation of the final (possibly immutable) object is optimized for reading and/or space usage, but not for update.  String and StringBuilder are good examples here.  Repeatedly concatenating strings is not very efficient, so the StringBuilder uses a different internal representation that is good for appending — but not as good on space usage, and not as good for reading and using as the regular String class.

                  • To clearly separate constructed objects from objects under construction.  This approach requires a clear transition from under-construction to constructed.  For the consumer, there is no way to confuse an under-construction object with a constructed object: the type system will enforce this.  That means sometimes we can use this approach to "fall into the pit of success", as it were, and, when making abstraction for others (or ourselves) to use (like an API or a layer), this can be a very good thing.





                  share|improve this answer






















                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    Why use/provide a builder class:



                    • To make immutable objects — the benefit you've identified already.  Useful if the construction takes multiple steps.  FWIW, immutability should be seen a significant tool in our quest to write maintainable and bug free programs.

                    • If the runtime representation of the final (possibly immutable) object is optimized for reading and/or space usage, but not for update.  String and StringBuilder are good examples here.  Repeatedly concatenating strings is not very efficient, so the StringBuilder uses a different internal representation that is good for appending — but not as good on space usage, and not as good for reading and using as the regular String class.

                    • To clearly separate constructed objects from objects under construction.  This approach requires a clear transition from under-construction to constructed.  For the consumer, there is no way to confuse an under-construction object with a constructed object: the type system will enforce this.  That means sometimes we can use this approach to "fall into the pit of success", as it were, and, when making abstraction for others (or ourselves) to use (like an API or a layer), this can be a very good thing.





                    share|improve this answer












                    Why use/provide a builder class:



                    • To make immutable objects — the benefit you've identified already.  Useful if the construction takes multiple steps.  FWIW, immutability should be seen a significant tool in our quest to write maintainable and bug free programs.

                    • If the runtime representation of the final (possibly immutable) object is optimized for reading and/or space usage, but not for update.  String and StringBuilder are good examples here.  Repeatedly concatenating strings is not very efficient, so the StringBuilder uses a different internal representation that is good for appending — but not as good on space usage, and not as good for reading and using as the regular String class.

                    • To clearly separate constructed objects from objects under construction.  This approach requires a clear transition from under-construction to constructed.  For the consumer, there is no way to confuse an under-construction object with a constructed object: the type system will enforce this.  That means sometimes we can use this approach to "fall into the pit of success", as it were, and, when making abstraction for others (or ourselves) to use (like an API or a layer), this can be a very good thing.






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 1 hour ago









                    Erik Eidt

                    21.2k33053




                    21.2k33053




















                        up vote
                        1
                        down vote













                        The builder permits you an object to work with across space and time that explicitly isn't the final object, thus protecting you from mistakes and broken semantics. This permits your domain objects to strictly enforce validity at all times, if that sort of thing tickles your fancy. And at the very least, it can facilitate never having a Widget laying around that isn't actually a Widget, according to your business rules.






                        share|improve this answer
























                          up vote
                          1
                          down vote













                          The builder permits you an object to work with across space and time that explicitly isn't the final object, thus protecting you from mistakes and broken semantics. This permits your domain objects to strictly enforce validity at all times, if that sort of thing tickles your fancy. And at the very least, it can facilitate never having a Widget laying around that isn't actually a Widget, according to your business rules.






                          share|improve this answer






















                            up vote
                            1
                            down vote










                            up vote
                            1
                            down vote









                            The builder permits you an object to work with across space and time that explicitly isn't the final object, thus protecting you from mistakes and broken semantics. This permits your domain objects to strictly enforce validity at all times, if that sort of thing tickles your fancy. And at the very least, it can facilitate never having a Widget laying around that isn't actually a Widget, according to your business rules.






                            share|improve this answer












                            The builder permits you an object to work with across space and time that explicitly isn't the final object, thus protecting you from mistakes and broken semantics. This permits your domain objects to strictly enforce validity at all times, if that sort of thing tickles your fancy. And at the very least, it can facilitate never having a Widget laying around that isn't actually a Widget, according to your business rules.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 47 mins ago









                            svidgen

                            11.1k22754




                            11.1k22754




















                                up vote
                                0
                                down vote













                                Another reason that hasn't been explicitly mentioned here already, is that the build() method can verify that all fields are set, which is probably the most likely failure mode that would otherwise occur.



                                Another benefit is that your Person object would end up having a more simple lifetime and a simple set of invariant. You know that once you have a Person p, you have a p.name and a valid p.age. None of your methods have to be designed to handle situations like "well what if age is set but not name, or what if name is set but not age?" This reduces the overall complexity of the class.






                                share|improve this answer




















                                • "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                  – Vincent Savard
                                  42 mins ago















                                up vote
                                0
                                down vote













                                Another reason that hasn't been explicitly mentioned here already, is that the build() method can verify that all fields are set, which is probably the most likely failure mode that would otherwise occur.



                                Another benefit is that your Person object would end up having a more simple lifetime and a simple set of invariant. You know that once you have a Person p, you have a p.name and a valid p.age. None of your methods have to be designed to handle situations like "well what if age is set but not name, or what if name is set but not age?" This reduces the overall complexity of the class.






                                share|improve this answer




















                                • "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                  – Vincent Savard
                                  42 mins ago













                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                Another reason that hasn't been explicitly mentioned here already, is that the build() method can verify that all fields are set, which is probably the most likely failure mode that would otherwise occur.



                                Another benefit is that your Person object would end up having a more simple lifetime and a simple set of invariant. You know that once you have a Person p, you have a p.name and a valid p.age. None of your methods have to be designed to handle situations like "well what if age is set but not name, or what if name is set but not age?" This reduces the overall complexity of the class.






                                share|improve this answer












                                Another reason that hasn't been explicitly mentioned here already, is that the build() method can verify that all fields are set, which is probably the most likely failure mode that would otherwise occur.



                                Another benefit is that your Person object would end up having a more simple lifetime and a simple set of invariant. You know that once you have a Person p, you have a p.name and a valid p.age. None of your methods have to be designed to handle situations like "well what if age is set but not name, or what if name is set but not age?" This reduces the overall complexity of the class.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered 1 hour ago









                                Alexander

                                95259




                                95259











                                • "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                  – Vincent Savard
                                  42 mins ago

















                                • "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                  – Vincent Savard
                                  42 mins ago
















                                "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                – Vincent Savard
                                42 mins ago





                                "[...] can verify that all fields are set [...]" The point of the Builder pattern is that you don't have to set all fields yourself and you can fall back to sensible defaults. If you need to set all fields anyway, maybe you should not use that pattern!
                                – Vincent Savard
                                42 mins ago











                                up vote
                                0
                                down vote













                                It looks like you're talking about Josh Blochs Builder Pattern. This should not be confused with the Gang of Four Builder Pattern. These are different beasts. They both solve construction problems but in fairly different ways.



                                I assume the other class you're referring to is the anonymous inner class that Josh calls for. It can be a separate full blown class if you like and don't mind using a long constructor like an API that humans rarely touch but the classic case is an anonymous inner class that keeps you immutable by delaying building the person class until it has all the info it needs to fully build it in one shot.



                                The truth is you can construct your object without using another class. But then you have to choose. You lose either the ability to simulate named parameters in languages that don't have them (like java) or you lose the ability to remain immutable throughout the objects lifetime.



                                Immutable example, has no names for parameters



                                Person p = new Person("Arthur Dent", 42);


                                You can build everything with a single simple factory method or even a constructor. This will let you stay immutable but you loose the simulation of named parameters. That gets hard to read with many parameters. Computers don't care but it's hard on the humans.



                                Simulated named parameter example with traditional setters. Not immutable.



                                Person p = new Person();
                                p.name("Arthur Dent");
                                p.age(42);


                                You can do everything with setters. Whether or not they return this is only important users of your class hate coming up with meaningful names for intermediate steps. What's important here is that while you are still kind of simulating named parameters you're no longer immutable. Each use of a setter changes object state.



                                So what you get by adding the class is you can do both. It just demands you do a lot of keyboard typing.



                                As for business rules, even following Josh Blochs builder pattern with his inner class you don't get to enforce that anything gets called besides your first required parameters method and build. The required parameters don't get to simulate named parameters here. Just the optional ones do.



                                If you want to simulate named parameters for your required parameters you need more then the Josh Bloch builder. You need an internal Domain Specific Language (iDSL).



                                This lets you demand that they call age() and name() before calling build(). But you can't do it just by returning this each time. Each thing that returns returns a different thing that forces you to call the next thing.



                                Use might look like this:



                                Person p = personBuilder
                                .name("Arthur Dent")
                                .age(42)
                                .build()
                                ;


                                But this:



                                Person p = personBuilder
                                .age(42)
                                .build()
                                ;


                                is a compiler error because age() is only valid to call on the type returned by name().



                                These iDSLs are extremely powerful (JOOQ for example) and very nice to use but they are a fair bit of work to set up. I'd recommend saving them for things that will have a fair bit of source code written against them.






                                share|improve this answer


























                                  up vote
                                  0
                                  down vote













                                  It looks like you're talking about Josh Blochs Builder Pattern. This should not be confused with the Gang of Four Builder Pattern. These are different beasts. They both solve construction problems but in fairly different ways.



                                  I assume the other class you're referring to is the anonymous inner class that Josh calls for. It can be a separate full blown class if you like and don't mind using a long constructor like an API that humans rarely touch but the classic case is an anonymous inner class that keeps you immutable by delaying building the person class until it has all the info it needs to fully build it in one shot.



                                  The truth is you can construct your object without using another class. But then you have to choose. You lose either the ability to simulate named parameters in languages that don't have them (like java) or you lose the ability to remain immutable throughout the objects lifetime.



                                  Immutable example, has no names for parameters



                                  Person p = new Person("Arthur Dent", 42);


                                  You can build everything with a single simple factory method or even a constructor. This will let you stay immutable but you loose the simulation of named parameters. That gets hard to read with many parameters. Computers don't care but it's hard on the humans.



                                  Simulated named parameter example with traditional setters. Not immutable.



                                  Person p = new Person();
                                  p.name("Arthur Dent");
                                  p.age(42);


                                  You can do everything with setters. Whether or not they return this is only important users of your class hate coming up with meaningful names for intermediate steps. What's important here is that while you are still kind of simulating named parameters you're no longer immutable. Each use of a setter changes object state.



                                  So what you get by adding the class is you can do both. It just demands you do a lot of keyboard typing.



                                  As for business rules, even following Josh Blochs builder pattern with his inner class you don't get to enforce that anything gets called besides your first required parameters method and build. The required parameters don't get to simulate named parameters here. Just the optional ones do.



                                  If you want to simulate named parameters for your required parameters you need more then the Josh Bloch builder. You need an internal Domain Specific Language (iDSL).



                                  This lets you demand that they call age() and name() before calling build(). But you can't do it just by returning this each time. Each thing that returns returns a different thing that forces you to call the next thing.



                                  Use might look like this:



                                  Person p = personBuilder
                                  .name("Arthur Dent")
                                  .age(42)
                                  .build()
                                  ;


                                  But this:



                                  Person p = personBuilder
                                  .age(42)
                                  .build()
                                  ;


                                  is a compiler error because age() is only valid to call on the type returned by name().



                                  These iDSLs are extremely powerful (JOOQ for example) and very nice to use but they are a fair bit of work to set up. I'd recommend saving them for things that will have a fair bit of source code written against them.






                                  share|improve this answer
























                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    It looks like you're talking about Josh Blochs Builder Pattern. This should not be confused with the Gang of Four Builder Pattern. These are different beasts. They both solve construction problems but in fairly different ways.



                                    I assume the other class you're referring to is the anonymous inner class that Josh calls for. It can be a separate full blown class if you like and don't mind using a long constructor like an API that humans rarely touch but the classic case is an anonymous inner class that keeps you immutable by delaying building the person class until it has all the info it needs to fully build it in one shot.



                                    The truth is you can construct your object without using another class. But then you have to choose. You lose either the ability to simulate named parameters in languages that don't have them (like java) or you lose the ability to remain immutable throughout the objects lifetime.



                                    Immutable example, has no names for parameters



                                    Person p = new Person("Arthur Dent", 42);


                                    You can build everything with a single simple factory method or even a constructor. This will let you stay immutable but you loose the simulation of named parameters. That gets hard to read with many parameters. Computers don't care but it's hard on the humans.



                                    Simulated named parameter example with traditional setters. Not immutable.



                                    Person p = new Person();
                                    p.name("Arthur Dent");
                                    p.age(42);


                                    You can do everything with setters. Whether or not they return this is only important users of your class hate coming up with meaningful names for intermediate steps. What's important here is that while you are still kind of simulating named parameters you're no longer immutable. Each use of a setter changes object state.



                                    So what you get by adding the class is you can do both. It just demands you do a lot of keyboard typing.



                                    As for business rules, even following Josh Blochs builder pattern with his inner class you don't get to enforce that anything gets called besides your first required parameters method and build. The required parameters don't get to simulate named parameters here. Just the optional ones do.



                                    If you want to simulate named parameters for your required parameters you need more then the Josh Bloch builder. You need an internal Domain Specific Language (iDSL).



                                    This lets you demand that they call age() and name() before calling build(). But you can't do it just by returning this each time. Each thing that returns returns a different thing that forces you to call the next thing.



                                    Use might look like this:



                                    Person p = personBuilder
                                    .name("Arthur Dent")
                                    .age(42)
                                    .build()
                                    ;


                                    But this:



                                    Person p = personBuilder
                                    .age(42)
                                    .build()
                                    ;


                                    is a compiler error because age() is only valid to call on the type returned by name().



                                    These iDSLs are extremely powerful (JOOQ for example) and very nice to use but they are a fair bit of work to set up. I'd recommend saving them for things that will have a fair bit of source code written against them.






                                    share|improve this answer














                                    It looks like you're talking about Josh Blochs Builder Pattern. This should not be confused with the Gang of Four Builder Pattern. These are different beasts. They both solve construction problems but in fairly different ways.



                                    I assume the other class you're referring to is the anonymous inner class that Josh calls for. It can be a separate full blown class if you like and don't mind using a long constructor like an API that humans rarely touch but the classic case is an anonymous inner class that keeps you immutable by delaying building the person class until it has all the info it needs to fully build it in one shot.



                                    The truth is you can construct your object without using another class. But then you have to choose. You lose either the ability to simulate named parameters in languages that don't have them (like java) or you lose the ability to remain immutable throughout the objects lifetime.



                                    Immutable example, has no names for parameters



                                    Person p = new Person("Arthur Dent", 42);


                                    You can build everything with a single simple factory method or even a constructor. This will let you stay immutable but you loose the simulation of named parameters. That gets hard to read with many parameters. Computers don't care but it's hard on the humans.



                                    Simulated named parameter example with traditional setters. Not immutable.



                                    Person p = new Person();
                                    p.name("Arthur Dent");
                                    p.age(42);


                                    You can do everything with setters. Whether or not they return this is only important users of your class hate coming up with meaningful names for intermediate steps. What's important here is that while you are still kind of simulating named parameters you're no longer immutable. Each use of a setter changes object state.



                                    So what you get by adding the class is you can do both. It just demands you do a lot of keyboard typing.



                                    As for business rules, even following Josh Blochs builder pattern with his inner class you don't get to enforce that anything gets called besides your first required parameters method and build. The required parameters don't get to simulate named parameters here. Just the optional ones do.



                                    If you want to simulate named parameters for your required parameters you need more then the Josh Bloch builder. You need an internal Domain Specific Language (iDSL).



                                    This lets you demand that they call age() and name() before calling build(). But you can't do it just by returning this each time. Each thing that returns returns a different thing that forces you to call the next thing.



                                    Use might look like this:



                                    Person p = personBuilder
                                    .name("Arthur Dent")
                                    .age(42)
                                    .build()
                                    ;


                                    But this:



                                    Person p = personBuilder
                                    .age(42)
                                    .build()
                                    ;


                                    is a compiler error because age() is only valid to call on the type returned by name().



                                    These iDSLs are extremely powerful (JOOQ for example) and very nice to use but they are a fair bit of work to set up. I'd recommend saving them for things that will have a fair bit of source code written against them.







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited 1 min ago

























                                    answered 22 mins ago









                                    candied_orange

                                    48.5k1686172




                                    48.5k1686172




















                                        Boyan Kushlev is a new contributor. Be nice, and check out our Code of Conduct.









                                         

                                        draft saved


                                        draft discarded


















                                        Boyan Kushlev is a new contributor. Be nice, and check out our Code of Conduct.












                                        Boyan Kushlev is a new contributor. Be nice, and check out our Code of Conduct.











                                        Boyan Kushlev is a new contributor. Be nice, and check out our Code of Conduct.













                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f380397%2fwhy-do-we-need-a-builder-class-when-implementing-a-builder-pattern%23new-answer', 'question_page');

                                        );

                                        Post as a guest













































































                                        Comments

                                        Popular posts from this blog

                                        Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                        Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                        Confectionery