มาใช้ Lombok ใน Java กันเถอะ

Phayao Boonon
3 min readJan 27, 2019

--

https://www.bookmundi.com/t/best-things-to-do-on-lombok-island

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 ที่ทำให้เขียนโค้ดได้เร็วขึ้น

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

Responses (1)