Is this a valid builder pattern option?

Suppose that we have a class User, and UserBuilderin its own package, which we want to be the same and in a consistent state before the initialization, defined as follows:

public class User {

private final String firstName, lastName;
private final int age;
private final String adress;
  protected User(UserBuilder buildUser) { //constructor acessible only in same packge
      this.firstName = buildUser.lastName;
      this.lastName = buildUser.lastName;
      this.age = buildUser.age;
      this.adress = buildUser.adress;
  }

  public String getFirstName() {
  return firstName;
  }
  ... // and other getters
}

And the builder class is as follows:

public class UserBuilder {

    public final String firstName;
    public final String lastName;
    public int age;
    public String adress;

    public UserBuilder(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public UserBuilder setAge(int age) {
        this.age = age;
        return this;
    }

    public UserBuilder setAdress(String adress) {
        this.adress = adress;
        return this;
    }

    public UserBuilder getUser() {
        return this;
    }

    public User build() {
        return new User(getUser());
    }
}

And finally, we create a user in a class that is in another package:

  public static void main(String[] args) {
        User user = new UserBuilder("John","Doe")
                .setAge(22)
                .build();   
       // User user = new User(UserBuilder) //error protected constructor                
    }  

Is this considered a safe and good design? If not, why?

+4
source share
4 answers

My suggestions:

  • Builder User, , Builder, Builder, getter.
  • User private, protected , , .
  • getUser() .

:

public final class User {

    private final String firstName, lastName;
    private final int age;
    private final String address;
    private final List<User> friends;

    private User(Builder builder) {
        this.firstName = builder.lastName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.address = builder.address;
        this.friends = Collections.unmodifiableList(new ArrayList<>(builder.friends)); //immutable list
    }

    public String getFirstName() {
        return firstName;
    }

    public List<User> getFriends() {
        return friends;
    }

    /**
     * other getters;
     */

    public static class Builder {
        private String firstName, lastName;
        private int age;
        private String address;
        private List<User> friends = new ArrayList<>();

        public Builder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

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

        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }

        public Builder addFriend(User friend) {
            this.friends.add(friend);
            return this;
        }

        public User build() {
            return new User(Builder.this);
        }
    }

    public static void main(String[] args) {
        User johnSmith = new User.Builder("John", "Smith").setAge(33).setAddress("New York").build();
    }

}
+1

inmutable, . User, builder, , , User , , , , UserBuilder, UserBuilder , .

, , , ,

0
  • UserBuilder

  • , /, ,

  • User private

0

protected , . Builder User. .

0

Source: https://habr.com/ru/post/1616045/


All Articles