Thông thường, khi chúng ta cần khởi tạo một đối tượng với rất nhiều thông tin, chúng ta có thể sử dụng Builder Pattern để làm điều này.
Ví dụ như, mình có class Student như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package com.huongdanjava.lombok; public class Student { private String firstName; private String middleName; private String lastName; private String country; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "Student{" + "firstName='" + firstName + '\'' + ", middleName='" + middleName + '\'' + ", lastName='" + lastName + '\'' + ", country='" + country + '\'' + '}'; } } |
Để tạo đối tượng Student với tất cả các thông tin sử dụng Builder Pattern, chúng ta cần tạo một đối tượng StudentBuilder như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.huongdanjava.lombok; public class StudentBuilder { private Student student; public StudentBuilder() { student = new Student(); } public StudentBuilder firstName(String firstName) { student.setFirstName(firstName); return this; } public StudentBuilder lastName(String lastName) { student.setLastName(lastName); return this; } public StudentBuilder middleName(String middleName) { student.setMiddleName(middleName); return this; } public StudentBuilder country(String country) { student.setCountry(country); return this; } public Student build() { return student; } } |
và sử dụng đối tượng StudentBuilder này để tạo đối tượng Student:
1 2 3 4 5 6 7 8 |
Student student = new StudentBuilder() .firstName("Khanh") .middleName("Huu") .lastName("Nguyen") .country("Viet Nam") .build(); System.out.printf(student.toString()); |
Kết quả:
Với Project Lombok, chúng ta sẽ có một cách dễ dàng hơn để tạo đối tượng StudentBuilder bằng cách sử dụng annotation @Builder như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.lombok; import lombok.*; @Getter @Setter @Builder @ToString public class Student { private String firstName; private String middleName; private String lastName; private String country; } |
Với annotation @Builder, khi generate class, một class Builder mới sẽ được generate. Với ví dụ trên của chúng ta, nếu bây giờ các bạn kiểm tra tập tin Student class nằm trong thư mục /target/classes/com/huongdanjava/lombok, các bạn sẽ thấy tập tin này có nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.huongdanjava.lombok; import java.beans.ConstructorProperties; public class Student { private String firstName; private String middleName; private String lastName; private String country; @ConstructorProperties({"firstName", "middleName", "lastName", "country"}) Student(String firstName, String middleName, String lastName, String country) { this.firstName = firstName; this.middleName = middleName; this.lastName = lastName; this.country = country; } public static Student.StudentBuilder builder() { return new Student.StudentBuilder(); } public String getFirstName() { return this.firstName; } public String getMiddleName() { return this.middleName; } public String getLastName() { return this.lastName; } public String getCountry() { return this.country; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public void setLastName(String lastName) { this.lastName = lastName; } public void setCountry(String country) { this.country = country; } public String toString() { return "Student(firstName=" + this.getFirstName() + ", middleName=" + this.getMiddleName() + ", lastName=" + this.getLastName() + ", country=" + this.getCountry() + ")"; } public static class StudentBuilder { private String firstName; private String middleName; private String lastName; private String country; StudentBuilder() { } public Student.StudentBuilder firstName(String firstName) { this.firstName = firstName; return this; } public Student.StudentBuilder middleName(String middleName) { this.middleName = middleName; return this; } public Student.StudentBuilder lastName(String lastName) { this.lastName = lastName; return this; } public Student.StudentBuilder country(String country) { this.country = country; return this; } public Student build() { return new Student(this.firstName, this.middleName, this.lastName, this.country); } public String toString() { return "Student.StudentBuilder(firstName=" + this.firstName + ", middleName=" + this.middleName + ", lastName=" + this.lastName + ", country=" + this.country + ")"; } } } |
Các bạn có thể thấy một class mới Student.StudentBuilder đã được thêm vào.
Bây giờ, các bạn có thể sử dụng Student.StudentBuilder class này:
1 2 3 4 5 6 7 8 |
Student student = Student.builder() .firstName("Khanh") .middleName("Huu") .lastName("Nguyen") .country("Viet Nam") .build(); System.out.printf(student.toString()); |
Kết quả:
Ngoc Quyen
Hi anh. Em thấy có thể dùng phương thức set cho nó. Tại sao còn sinh ra builder làm gì nhỉ
Khanh Nguyen
Trong trường hợp một đối tượng có quá nhiều thuộc tính thì việc gọi nhiều phương thức set() sẽ có phần hơi bất tiện. Sử dụng Builder Pattern để code gọn hơn thôi em!