มาใช้ Lombok ใน Java กันเถอะ
Lombok เป็นหนึ่งในเครื่องมือสำคัญและเป็นที่นิยมของชาว Java ทั้งหลาย เพราะจะมาช่วยสร้าง boilerplate code ให้จะทำให้โค้ดเราดูสั้นอ่านง่ายมากขึ้น และทำให้เขียนโปรแกรมได้เร็วมากขึ้น Lombok จะสร้าง boilerplate code ตอนเวลา compile
Install
Lombok สามารถใช้ dependency management ทั้ง Maven และ Gradle
Maven
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
Gradle
compileOnly 'org.projectlombok:lombok:1.18.4'
@Getter/Setter
การเขียนโปรแกรมแบบ OOP เราจะต้อง encapsulate field ของ class เอาไว้จำกัดการเข้าถึงจากภายนอก ดังนั้นจะต้องมี Getter/Setter เพื่อใช้ในการเข้าถึงหรือมีเงื่อนไขในการตั้งค่า จะทำให้โค้ดส่วนนี้มีมากแปรผันตรงกับจำนวนของ field
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
// Getter
public String getBar() {
return bar;
}
// Setter
public void setBar(String bar) {
this.bar = bar;
}
}
แต่ Lombok มี annotation ที่มาช่วยให้เราสร้าง Getter/Setter ให้ด้วย @Getter และ @Setter จะเห็นได้ว่าจะลดโค้ดส่วนของ Getter/Setter ลงได้เยอะมาก
@Getter
@Setter
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
}
@Getter/@Setter สามารถใช้ในระดับ field ได้ด้วยเพื่อกำหนดให้ field ว่าจะมีแค่ Getter หรือ Setter อีกทั้งยังสามารถกำหนด AccessLevel ได้ด้วย
@Getter
public class Foo {
@Setter(AccessLevel.PROTECTED)
private String bar;
private String baz;
public Foo(String bar) {
this.bar = bar;
}
}
@ToString
ใน Object class จะมี method toString()
เป็น default เพื่อที่จะพิมพ์ค่าของ object นั้น ซึ่งถ้าเป็น class ที่ไม่ได้ override toString()
ก็จะพิมพ์เป็น address ของ object นั้นออกมา
@ToString
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
}
// Foo@5594a1b5 - Vanilla Java
// Foo(bar=Hello) - with Lombok
@EqualsAndHashCode
เช่นกันใน Object class เมื่อใช้ method equal()
จะเป็นการเปรียบเทียบว่าเป็น object เดียวกันหรือไม่ (มี address เดียวกัน) จะไม่สามารถเปรียบเทียบข้อมูล (content) ได้ ดังนั้น @EqualsAndHashCode
annotation ของ Lombok ช่วยเราได้
@EqualsAndHashCode
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
}Foo foo = new Foo("Hello");
Foo bar = new Foo("Hello");
System.out.println(foo.equals(foo)); // true
@NoArgsConstructor/AllArgsConstructor
ปรกติแล้วใน class เราอาจจะต้อง implement constructor ที่มี arguments ของ field ทั้งหมด หรือ constructor ที่ไม่มี argument เลย ดังนั้น @NoArgsConstructor
annotation จะช่วยสร้าง constructor ที่ไม่มี argument และ @AllArgsConstructor
จะช่วยสร้าง constructor ที่มี argument ของ private filed ทั้งหมดให้ และเราสามารถใช้ร่วมกันใน class เดียวได้เพื่อสร้าง constructor ทั้งสองแบบ
@NoArgsConstructor
@AllArgsConstructor
public class Foo {
private String bar;
private String baz;
}
@RequiredArgsConstructor
Lombok มี @RequiredArgsConstructor
annotation เพื่อสร้าง static constructor ด้วยการกำหนด parameter “staticName” และกำหนดให้ field ให้เป็น final ด้วย @NonNull
annotation
@RequiredArgsConstructor(staticName = "of")
public class Foo {
@NonNull private String bar;
private String baz;
}Foo.of("Hello");
@Data
Lombok ยังทำให้เราสะดวกเพิ่มขึ้นอีกด้วย @Data
annotation เพราะว่าจะเป็นการรวม annotation@Setter
, @Getter
, @RequiredArgsConstructor
, @ToString
, @EqualsAndHashCode
ดังนั้นจะสร้าง boilerplate code ให้เราแทบทั้งหมด (ครบจบใน annotation เดียว)
@Data
public class Foo {
private String bar;
private String baz;
}
@Value
แต่ก็ยังมี annotation ที่คล้ายกับ @Data
แต่เป็น immutable (ไม่สามารถเปลี่ยนค่าได้) นั้นก็คือ @Value
เป็นการรวม @Getter
, @ToString
, @EqualsAndHashCode
, @AllArgsConstructor
, @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
จะเห็นได้ว่าไม่มี Setter ทำให้เปลี่ยนแปลงค่าไม่ได้
@Value
public class Foo {
private String bar;
private String baz;
}
@Builder
Lombok ยังรองรับ Builder pattern ด้วย @Builder ทำให้เราสร้าง Builder class ได้ง่ายๆ ใช้สำหรับ class ที่สร้าง instance เพียงครั้งเดียว
@Builder
public class Foo {
private String bar;
private String baz;
}Foo.builder()
.bar("Hello")
.baz("World")
.build();
@Synchronized
ถ้าเราเขียน Concurrency ใน Java จะใช้ synchronized keyword สำหรับ thread safe
public class Foo {
private final Object lock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized("lock")
public void bar() {
System.out.println("bar");
}
}
@Getter(lazy = true)
บางครั้งเราต้องการ Getter ที่คำนวนอะไรบางอย่างเพียงครั้งเดียว และสามารถ cache มันไว้ไว้ Lombok สามารถกำหนดค่า parameter ของ Setter ให้ lazy = true เพื่อที่จะลดการประมวลผลของ CPU ลงได้
public class Foo {
@Getter(lazy = true)
private final double[] bar = bar();
private double[] bar() {
return new double[10000];
}
}
สรุป
Lombok เหมาะและจำเป็นมากสำหรับ Java Developer ที่ทำให้เขียนโค้ดได้เร็วขึ้น