Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between builder pattern and constructor [closed]

The builder pattern is just a way to build an object similar to what a constructor does, so why use a builder pattern instead of plain old constructors?

like image 231
Alecu Avatar asked Apr 26 '15 17:04

Alecu


People also ask

What is the difference between factory pattern and builder pattern?

A Factory Design Pattern is used when the entire object can be easily created and object is not very complex. Whereas Builder Pattern is used when the construction process of a complete object is very complex.

What is the advantage of builder pattern?

Advantages of the Builder pattern include: Allows you to vary a product's internal representation. Encapsulates code for construction and representation. Provides control over steps of construction process.

What is the difference between abstract factory and builder design patterns?

Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately. Builder often builds a Composite.

What is the use of builder pattern in Java?

The builder pattern simplifies the creation of objects. It also simplifies the code as your do not have to call a complex constructor or call several setter methods on the created object. The builder pattern can be used to create an immutable class.


2 Answers

I agree with your view that a Builder is really just a glorified constructor, and that the "builder pattern is just a way to build an object similar to what a constructor does".

However, here are a few of scenarios where the complexity of constructing an object makes the use of a Builder compelling.

Object's dependencies collected over period of time

In Java, StringBuilder is commonly used when building a string over a period of time, or rather, within a complex procedure. For instance, if a server is communicating with a client over a socket, and wants to append some client responses to the string, but not others, and perhaps remove certain responses that were previously appended,the StringBuilder class can be used to do so. At the end of the client/server session, the server can invoke StringBuilder#toString to get the built String.

Lots of parameters

If a constructor has dozens of parameters, it may make the code more readable or easy to maintain to use a builder.

E.g.

new Foo(1,2,3,4,5,6,7,8,9,10,11,12)

Vs.

Foo.newBuilder()
   .bar(1)
   .bar(2)
   .quux(3)
   ...
   .build()

Constructing object graphs

Similar to the "lots of parameters" scenario, I think that the scenario where a builder is most compelling is when constructing a complex object graph. The other answers in this question refer to the telescoping anti-pattern. This scenario (building a complex object graph) can lead to "telescoping", which the Builder helps resolve.

For instance, imagine you have an object-oriented pipeline interface, where a Pipeline depends on Sequence which depends on Stage. A PipelineBuilder would not only provide a nice wrapper around the constructor of Pipeline, but also around the constructors Sequence and Stage, allowing you to compose a complex Pipeline from a single Builder interface.

Instead of telescoping constructors like so:

new Pipeline(
    new Sequence(
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        ),
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        )
    )
)

A PipelineBuilder would allow you to "collapse" the telescope.

Pipeline.newBuilder()
    .sequence()
        .stage(new StageFunction () {
            public function execute() {...}
        })
        .stage(new StageFunction () {
           public function execute() {...}
        })
    .build()

(Even though I have used indentation in a way that is reflective of the telescoping constructors, this is merely cosmetic, as opposed to structural.)

like image 199
maxenglander Avatar answered Oct 10 '22 14:10

maxenglander


From the Wikipedia page:

The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once

So if I have an object requiring many construction parameters, and those parameters are required in a variety of combinations (thus making some parameters optional) then a builder is a good approach.

e.g. I could create multiple different constructors for an object, or I could do the following:

new ObjectBuilder().withParam1(1).withParam4(4).withParam19(19).build();

thus allowing me to select the parameters required, and not have to define many different constructors. Note also that the above can allow you to populate a builder, and set parameters/call build() multiple times to create a set of related objects easily.

like image 11
Brian Agnew Avatar answered Oct 10 '22 13:10

Brian Agnew