I am studying Gang Of Four design patterns and I want to implement a builder pattern in Java.It seems there are two options to build a builder pattern:Using two different classes: A target class and a builder classUsing a nested static inner builder class inside the target classUsing builder class as a separate classOn both approaches, the target class member variables must be final, thus the target class instances will be immutable.In this approach, target class will have two constructors. The first constructor will include all member variables of the class as a parameter. And second constructor will take one parameter of its own type, that which builder.build() method returns by using the first constructor of the target class.Domain Object Classpackage impl.first;public class DomainObject {    private final int id;    private final String name;    private final String surname;    private final boolean isMarried;    // includes all member variables    public DomainObject(int id, String name, String surname, boolean isMarried) {        this.id = id;        this.name = name;        this.surname = surname;        this.isMarried = isMarried;    }    public DomainObject(DomainObject domainObject) {        this.id = domainObject.getId();        this.name = domainObject.getName();        this.surname = domainObject.getSurname();        this.isMarried = domainObject.isMarried();    }    // getters    public int getId() {        return id;    }    public String getName() {        return name;    }    public String getSurname() {        return surname;    }    public boolean isMarried() {        return isMarried;    }}Domain Object Builder Classpackage impl.first;public final class DomainObjectBuilder {    private int id;    private String name;    private String surname;    private boolean isMarried;    // No-arg Default Constructor    public DomainObjectBuilder() { }    public DomainObject build() {        return new DomainObject(id, name, surname, isMarried);    }    public DomainObjectBuilder id(int id) {        this.id = id;        return this;    }    public DomainObjectBuilder name(String name) {        this.name = name;        return this;    }    public DomainObjectBuilder surname(String surname) {        this.surname = surname;        return this;    }    public DomainObjectBuilder isMarried(boolean isMarried) {        this.isMarried = isMarried;        return this;    }}Demo codepackage impl.first;public class DomainObjectDemo {    public static void main(String[] args) {        DomainObjectBuilder builder = new DomainObjectBuilder();        DomainObject dom;        // Test #1 : None of member variables are set        System.out.println(Test #1 : None of member variables are set);        System.out.println(******************************************\n);        dom = new DomainObject(builder.build());        printDomObject(dom);        // Test #2 : Half of objects are set        System.out.println(Test #2 : Half of objects are set);        System.out.println(*********************************\n);        builder.id(1299).name(Levent).surname(Divilioglu).isMarried(false);        dom = new DomainObject(builder.build());        printDomObject(dom);        // Test #3 : All of objects are set        System.out.println(Test #3 : All of objects are set);        System.out.println(********************************\n);        builder.id(1299).name(Levent).surname(Divilioglu).isMarried(false);        dom = new DomainObject(builder.build());        printDomObject(dom);    }    public static void printDomObject(DomainObject dom) {        System.out.println(Instance HashCode:  + dom.hashCode());        System.out.println(Id               :  + dom.getId());        System.out.println(Name             :  + dom.getName());        System.out.println(Surname          :  + dom.getSurname());        System.out.println(isMarried        :  + dom.isMarried());        System.out.println();    }}OutputTest #1 : None of member variables are set******************************************Instance HashCode: 705927765Id               : 0Name             : nullSurname          : nullisMarried        : falseTest #2 : Half of objects are set*********************************Instance HashCode: 366712642Id               : 1299Name             : LeventSurname          : DiviliogluisMarried        : falseTest #3 : All of objects are set********************************Instance HashCode: 1829164700Id               : 1299Name             : LeventSurname          : DiviliogluisMarried        : falseUsing builder class as an inner static classDomain object with inner static builder classpackage impl.second;public class DomainObject {    private final int id;    private final String name;    private final String surname;    private final boolean isMarried;    public DomainObject(Builder domainObject) {        this.id = domainObject.id;        this.name = domainObject.name;        this.surname = domainObject.surname;        this.isMarried = domainObject.isMarried;    }    public static class Builder {        private int id;        private String name;        private String surname;        private boolean isMarried;        // No-arg Default Constructor        public Builder() { }        public DomainObject build() {            return new DomainObject(this);        }        public Builder id(int id) {            this.id = id;            return this;        }        public Builder name(String name) {            this.name = name;            return this;        }        public Builder surname(String surname) {            this.surname = surname;            return this;        }        public Builder isMarried(boolean isMarried) {            this.isMarried = isMarried;            return this;        }    }    // getters    public int getId() {        return id;    }    public String getName() {        return name;    }    public String getSurname() {        return surname;    }    public boolean isMarried() {        return isMarried;    }}Demo codepackage impl.second;public class DomainObjectDemo {    public static void main(String[] args) {        DomainObject.Builder builder = new DomainObject.Builder();        DomainObject dom;        // Test #1 : None of member variables are set        System.out.println(Test #1 : None of member variables are set);        System.out.println(******************************************\n);        dom = builder.build();        printDomObject(dom);        // Test #2 : Half of objects are set        System.out.println(Test #2 : Half of objects are set);        System.out.println(*********************************\n);        builder.id(1299).name(Levent).surname(Divilioglu).isMarried(false);        dom = builder.build();        printDomObject(dom);        // Test #3 : All of objects are set        System.out.println(Test #3 : All of objects are set);        System.out.println(********************************\n);        builder.id(1299).name(Levent).surname(Divilioglu).isMarried(false);        dom = builder.build();        printDomObject(dom);    }    public static void printDomObject(DomainObject dom) {        System.out.println(Instance HashCode:  + dom.hashCode());        System.out.println(Id               :  + dom.getId());        System.out.println(Name             :  + dom.getName());        System.out.println(Surname          :  + dom.getSurname());        System.out.println(isMarried        :  + dom.isMarried());        System.out.println();    }}OutputTest #1 : None of member variables are set******************************************Instance HashCode: 705927765Id               : 0Name             : nullSurname          : nullisMarried        : falseTest #2 : Half of objects are set*********************************Instance HashCode: 366712642Id               : 1299Name             : LeventSurname          : DiviliogluisMarried        : falseTest #3 : All of objects are set********************************Instance HashCode: 1829164700Id               : 1299Name             : LeventSurname          : DiviliogluisMarried        : falseAs it is obvious, on two different approach, three Domain Object instances are have different unique hashcodes thus each builder returns unique class instances.What is the best practice, what are the pros and cons of each approach?
Implementing builder pattern In Java with a static inner and a Concrete standalone class
java;design patterns;static