1public class BankAccount {
2 public static class Builder {
3 private long accountNumber; //This is important, so we'll pass it to the constructor.
4 private String owner;
5 private String branch;
6 private double balance;
7 private double interestRate;
8 public Builder(long accountNumber) {
9 this.accountNumber = accountNumber;
10 }
11 public Builder withOwner(String owner){
12 this.owner = owner;
13 return this; //By returning the builder each time, we can create a fluent interface.
14 }
15 public Builder atBranch(String branch){
16 this.branch = branch;
17 return this;
18 }
19 public Builder openingBalance(double balance){
20 this.balance = balance;
21 return this;
22 }
23 public Builder atRate(double interestRate){
24 this.interestRate = interestRate;
25 return this;
26 }
27 public BankAccount build(){
28 //Here we create the actual bank account object, which is always in a fully initialised state when it's returned.
29 BankAccount account = new BankAccount(); //Since the builder is in the BankAccount class, we can invoke its private constructor.
30 account.accountNumber = this.accountNumber;
31 account.owner = this.owner;
32 account.branch = this.branch;
33 account.balance = this.balance;
34 account.interestRate = this.interestRate;
35 return account;
36 }
37 }
38 //Fields omitted for brevity.
39 private BankAccount() {
40 //Constructor is now private.
41 }
42 //Getters and setters omitted for brevity.
43}
44
45BankAccount account = new BankAccount.Builder(1234L)
46 .withOwner("Marge")
47 .atBranch("Springfield")
48 .openingBalance(100)
49 .atRate(2.5)
50 .build();
51BankAccount anotherAccount = new BankAccount.Builder(4567L)
52 .withOwner("Homer")
53 .atBranch("Springfield")
54 .openingBalance(100)
55 .atRate(2.5)
56 .build();
1public class User
2{
3 //All final attributes
4 private final String firstName; // required
5 private final String lastName; // required
6 private final int age; // optional
7 private final String phone; // optional
8 private final String address; // optional
9
10 private User(UserBuilder builder) {
11 this.firstName = builder.firstName;
12 this.lastName = builder.lastName;
13 this.age = builder.age;
14 this.phone = builder.phone;
15 this.address = builder.address;
16 }
17
18 //All getter, and NO setter to provde immutability
19 public String getFirstName() {
20 return firstName;
21 }
22 public String getLastName() {
23 return lastName;
24 }
25 public int getAge() {
26 return age;
27 }
28 public String getPhone() {
29 return phone;
30 }
31 public String getAddress() {
32 return address;
33 }
34
35 @Override
36 public String toString() {
37 return "User: "+this.firstName+", "+this.lastName+", "+this.age+", "+this.phone+", "+this.address;
38 }
39
40 public static class UserBuilder
41 {
42 private final String firstName;
43 private final String lastName;
44 private int age;
45 private String phone;
46 private String address;
47
48 public UserBuilder(String firstName, String lastName) {
49 this.firstName = firstName;
50 this.lastName = lastName;
51 }
52 public UserBuilder age(int age) {
53 this.age = age;
54 return this;
55 }
56 public UserBuilder phone(String phone) {
57 this.phone = phone;
58 return this;
59 }
60 public UserBuilder address(String address) {
61 this.address = address;
62 return this;
63 }
64 //Return the finally consrcuted User object
65 public User build() {
66 User user = new User(this);
67 validateUserObject(user);
68 return user;
69 }
70 private void validateUserObject(User user) {
71 //Do some basic validations to check
72 //if user object does not break any assumption of system
73 }
74 }
75}
76