Builder design pattern pass object Good Morning

This is a builder design pattern .. the builder problem is duplication so

I want to know from an expert with explanation which is better on quality on this code:

(1)

public class Animal {

    private String animalName;
    private int animalAge;

    public static class Builder {
        private Animal animal;

        public Builder() {
            animal = new Animal();
        }

        public Builder getName(String animalName) {
            animal.animalName = animalName;
            return this;
        }

        public Builder getAge(int animalAge) {
            animal.animalAge = animalAge;
            return this;
        }

        public Animal build(){
            animal.build(this);
            return animal;
        }
    }

    public Animal(){ }

    public void build(Builder builder) {
        this.animalName = builder.animal.animalName;
        this.animalAge = builder.animal.animalAge;
    }

    public String getAnimalName() {
        return animalName;
    }

    public int getAnimalAge() {
        return animalAge;
    } 
}


(2)

public class Animal {

    private String animalName;
    private int animalAge;

    public static class Builder{

        private String animalName;
        private int animalAge;

        public Builder getName(String animalName){
            this.animalName = animalName;
            return this;
        }

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


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

    }

    public Animal(Builder builder) {
        this.animalName = builder.animalName;
        this.animalAge = builder.animalAge;
    }

    public String getAnimalName() {
        return animalName;
    }

    public int getAnimalAge() {
        return animalAge;
    }   
}


in first model i pass animal object and create an instance and then the builder fill the data and build the animal again .

in second model i duplicate all the animal instance variables

which is true ? and which not broke builder rules ?
What I've seen the most when it comes to builder patterns is that the object (in your case Animal) will get constructed in the build method of the builder. It is preferred to create instances of objects with all the data that the object should have, eg not creating invalid states of an object. This prevents you from having illegal state in your program which might produce bugs. By constructing your Animal as soon as you create a builder instance you have to make your Animal mutable which is not always what you want. For example, in some cases a class might have only final fields which can only be assigned via constructor.

In your case, constructing the Animal in the build method it would look something like this:

public class Animal {

    private String animalName;
    private int animalAge;

    public static class AnimalBuilder {
        private String animalName;
        private int animalAge;

        public AnimalBuilder() {
        }

        public Builder withName(String animalName) {
            this.animalName = animalName;
            return this;
        }

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

        public Animal build(){
            Animal animal = new Animal();
            animal.animalName = this.animalName;
            animal.animalAge = this.animalAge;
            return animal;
        }
    }

    public Animal(){ }

    public String getAnimalName() {
        return animalName;
    }

    public int getAnimalAge() {
        return animalAge;
    } 
}


You can then use it

Animal animal = new AnimalBuilder()
    .withName("Terry")
    .withAge(5)
    .build();


You can also add a static method builder() to the Animal class which returns a new builder:

public class Animal {
    ...

    public static AnimalBuilder builder() {
        return new AnimalBuilder();
    }
}

Animal animal = Animal.builder()
    .withName("Terry")
    .withAge(5)
    .build();


Does this mean a lot of duplication? Unfortunately, yes, builder patterns need a lot of duplicate code. You can also look at Lombok's Builder annotation which will generate all the builder boilerplate code for you. In that case it will just be

@Builder
public class Animal {

    private String animalName;
    private int animalAge;

    public Animal(){ }

    public String getAnimalName() {
        return animalName;
    }

    public int getAnimalAge() {
        return animalAge;
    } 
}
```