網頁

2019/11/30

Lombok @Builder 用法

Java在建構類別的實例時,如果類別的成員變數/屬性(member variable/attributes)很多,可以利用設計模式的建造者模式(Builder Pattern)替代傳統以建構式(constructor)的方式來建立物件。

Builder Pattern的缺點就是程式碼量變多,約比原本要多寫2-3倍的程式碼。

不過有了Lombok的@Builder annotation就不用自己手刻Builder程式碼了,Lombok套件會自動生成Builder的程式碼。

IDE及專案要先裝好Lombok


例如下面是一個簡單的Customer類別,在類別名稱前掛上Lombok的@Builder即可使用Builder Pattern來建立物件。

@Data則用來產生toString()印出物件內容。

Customer

package com.abc.demo.model;
import lombok.Builder;
import lombok.Data;

@Builder // <--
@Data
public class Customer {

    private Long id;
    private String name;
    private Integer age;
    private Long createTime;

}

Builder預設是使用Lombok全屬性建構標記@AllArgsConstructor(access = AccessLevel.PACKAGE)產生的全屬性建構式作為Builder要建構的屬性。

如此即可在程式中直接使用Builder Pattern建構物件。

Main

package com.abc.demo;

import com.abc.demo.model.Customer;

public class Main {

    public static void main(String[] args) {

        Customer employee = 
                Customer.builder()
                        .id(1L)
                        .name("John")
                        .age(27)
                        .createTime(System.currentTimeMillis())
                        .build();

        System.out.println(employee); // Customer(id=1, name=John, age=27, createTime=1575120459647)

    }

}

如果要自訂某個屬性的Builder Pattern的setter方法,則建立一個類別名稱 + Builder的Builder,並在裡面撰寫自訂的setter。

例如希望name屬性在被設為空字串""null時使用預設的名稱"guest",則建立一個CustomerBuilder並撰寫自訂的屬性setter。

Customer

package com.abc.demo.model;

import org.springframework.util.StringUtils;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Customer {

    private Long id;
    private String name;
    private Integer age;
    private Long createTime;
    
    public static class CustomerBuilder {
        
        public CustomerBuilder name (String name) {
            if (StringUtils.isEmpty(name)) {
                this.name = "guest";
            }
            return this;
        }
        
    }

}

Main

package com.abc.demo;

import com.abc.demo.model.Customer;

public class Main {

    public static void main(String[] args) {

        Customer employee = 
                Customer.builder()
                        .id(1L)
                        .name(null) // <-- name設為null
                        .age(27)
                        .createTime(System.currentTimeMillis())
                        .build();

        System.out.println(employee); // Customer(id=1, name=guest, age=27, createTime=1575122201560)

    }

}

但注意若沒有呼叫該屬性的Builder的setter則自訂的方法不會被執行。

Main

package com.abc.demo;

import com.abc.demo.model.Customer;

public class Main {

    public static void main(String[] args) {

        Customer employee = 
                Customer.builder()
                        .id(1L)
//                        .name(null)
                        .age(27)
                        .createTime(System.currentTimeMillis())
                        .build();

        System.out.println(employee); // Customer(id=1, name=null, age=27, createTime=1575122683993)

    }

}

以上即為Lombok @Builder的基本使用法。

如果類別有繼承父類別,則可改用@SuperBuilder


參考:

沒有留言:

張貼留言