Lombok

Lombok เป็นหนึ่งในเครื่องมือสำคัญและเป็นที่นิยมของชาว Java ทั้งหลาย เพราะจะมาช่วยสร้าง boilerplate code ให้จะทำให้โค้ดเราดูสั้นอ่านง่ายมากขึ้น และทำให้เขียนโปรแกรมได้เร็วมากขึ้น Lombok จะสร้าง boilerplate code ตอนเวลา compile

Install

Lombok สามารถใช้ dependency management ทั้ง Maven และ Gradle ดังตัวอย่าง pom.xml ของ Maven ด้านล่าง

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

@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();

Credit:

https://medium.com/@phayao/%E0%B8%A1%E0%B8%B2%E0%B9%83%E0%B8%8A%E0%B9%89-lombok-%E0%B9%83%E0%B8%99-java-%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B9%80%E0%B8%96%E0%B8%AD%E0%B8%B0-504952359d76