Builder pattern (Effective Java)

Recently, I've had a lot of opportunities to use the Effective Java Builder pattern mainly in Java, so I'll write it down for my own organization. It's just a simple summary.

Builder pattern example

For example, if you want to use OKHttpClient while developing Android,

OkHttpClient okHttpClient = new OkHttpClient(); 

And create an instance, but if you want to output the response to the log here

 OkHttpClient okHttpClient = new OkHttpClient.Builder()
                        .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                          .build();

I will. Here is an example of a Builder pattern.

What are you doing

Normally, the class creates an instance by newing the user, but in the case of the Builder pattern, it is a little different.

I will prepare a static class in the class.

public class Example {
    private int a;
    private int b;
    private int c;
    private int d;
    private int e;

    public static class ExampleBuilder {
        private int a;
        private int b;
        private int c;
        private int d;
        private int e;

    }
}

Then, set a value in the field and grow a method that returns the Builder itself for each field.

public class Example {
    private int a;
    private int b;
    private int c;
    private int d;
    private int e;

    public static class ExampleBuilder {
        private int a;
        private int b;
        private int c;
        private int d;
        private int e;

        public Builder a(int a) {
            this.a = a;
            return this;
        }

        public Builder b(int b) {
            this.b = b;
            return this;
        }
        //c,d omitted
        public Builder e(int e) {
            this.e = e;
            return this;
        }

    }
}

Meanwhile, at that time, we will prepare a private constructor for the Example class.

public class Example {
    private int a;
    private int b;
    private int c;
    private int d;
    private int e;

    //Builder omitted

    private Example(Builder builder) {
        this.a = builder.a;
        this.b = builder.b;
        this.c = builder.c;
        this.d = builder.d;
        this.e = builder.e;
    }
}

The argument is the Builder created earlier, and I will pass that field to the Example field. Since it is an inner class, you can access the field directly.

And finally, implement the build method in the Builder.

public static class ExampleBuilder {
        private int a;
        private int b;
        private int c;
        private int d;
        private int e;

        public Builder a(int a) {
            this.a = a;
            return this;
        }

        public Builder b(int b) {
            this.b = b;
            return this;
        }
        //c,d omitted
        public Builder e(int e) {
            this.e = e;
            return this;
        }

        public Example build() {
            return new Example(this);
        }

    }

Since the argument this is the Builder itself, if the Builder is passed to the private constructor and the value is set in the field, the value will be set in the Example field.

With this, when you want to use Example,

Example example = new Example.Builder.a(1).b(2).c(3).d(4).e(5).build();

You can get an example with values set in all fields. If you set the field only in part

Example example = new Example.Builder.a(1).d(4).build();

It is okay to set only the required value.

What makes me happy

I personally feel that the advantage of the Builder method is that ** the parameters passed to the constructor are easy to understand **.

The more arguments you pass to the constructor, the harder it is to see.

Example example = new Example(int aaaaaa, int bbbbbbb, int ccccccc, int ddddddd, int eeeeeeee);


If you implement it with the Builder pattern, readability will be improved because it is clearly stated what is set.

Also, if it is an optional parameter, you have to pass null one by one when not using it. There is also a method called the telescoping constructor pattern, in which multiple constructors are prepared, but it becomes difficult to read. If it is a Builder pattern, it is not necessary to set parameters that are not used, so the user does not have to be aware of it.

At the end

This time I wrote about the Effective Java Builder pattern, but I would like to write a lot about the GoF Builder pattern as well.

reference

By Joshua Bloch Translated by Yoshiki Shibata Effective Java Second Edition

Recommended Posts

Builder pattern (Effective Java)
Builder pattern
Builder Pattern
Introduction to Effective java by practicing and learning (Builder pattern)
[Java] Strategy pattern
Effective Java Chapter 2
Java design pattern
java callback pattern
Design pattern (2): Builder
[Java] Singleton pattern
Effective Java Chapter 6 34-35
[Java] Adapter pattern
Effective Java Chapter 4 15-22
Effective Java Chapter 3
Java pattern memo
My DAO pattern (Java)
Java Lambda Command Pattern
Java design pattern summary
[Design pattern] Java core library
Enum Strategy pattern in Java
[Java] Draw a simple pattern
From Ineffective Java to Effective Java
Rethinking design patterns with Java8 lambda expressions & Stream --Builder pattern -
Effective Java 3rd Edition Chapter 5 Generics
Java
Effective Java 3rd Edition Chapter 8 Methods
JNA (Java Native Access) pattern collection
Java
Java beginner design pattern (Factory Method pattern)
[Effective Java] Avoid creating unnecessary objects
[Java] Implement a function that uses a class implemented in the Builder pattern
Object Mother pattern and Test Data Builder pattern
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
Force non-instantiation with Effective Java private constructor
Effective Java 3rd Edition Chapter 9 Program General