簡體   English   中英

用 Java 中的 Lombok 更新不可變的 object?

[英]Update an immutable object with Lombok in Java?

我有一個域 class Person用 Lombok @Value注釋,因此將其標記為不可變,有 3 個字段。

在我的服務層中,我正在調用存儲庫以檢查此人是否存在。

如果確實存在,我需要從數據庫中獲取Person object 並更新money字段。

由於它是不可變的,因此無法做到這一點。 我正在閱讀一些文章並發現這可以使用構建器模式來完成。

我可能需要在我的Person class 中創建一個updatePerson()但不知道該怎么做。 還是我需要做其他事情?

Person.java

@Value
@Builder
public class Person {

    private final UUID id;
    private final String job;
    private final BigDecimal money;
    
}

我正在使用 Java 15。

您還可以使用 lombok 的另一個功能,它不需要您使用構建器。 它被稱為@With並且使用此注釋將創建不可變的設置器,這意味着設置器返回一個新的 object ,除了您想要更改的屬性之外,它具有舊的屬性。

@Value
public class Person {
    /* You don't need to write final if you are using @Value. Lombok will make the variables final for you. 
    In theory you do not even need to write private, 
    because Lombok makes variables private by default instead of package private.*/
    private UUID id;
    private String job;
    @With 
    private BigDecimal money;
}

Person newPerson = person.withMoney(new Big decimal("10"));

一般來說,我不確定使 object 不可變是否真的是個好主意。 除了 UUID 之外的每個變量似乎都可能在未來發生變化。

使用Lombok

@Value
@Builder(toBuilder = true)
public class Person {

    private final UUID id;
    private final String job;
    private final BigDecimal money;
}

personObjectFromDatabase.toBuilder().setMoney(...).build()

或者

在這種情況下,您可以使用Builder模式:

public class Person {

    private final UUID id;
    private final String job;
    private final BigDecimal money;
    
    public static class PersonBuilder { 
            private UUID id;
            private String job;
            private BigDecimal money;

            public PersonBuilder(Person defaultPerson){ 
                this.id = defaultPerson.getId();
                this.job = defaultPerson.getJob();
                this.money = defaultPerson.getMoney();
            }
            public PersonBuilder withId(UUID id) {
                this.id = UUID;
                return this;
            }
            public PersonBuilder withJob(String job) {
                this.job = job;
                return this;
            }
            public PersonBuilder withMoney(BigDecimal money) {
                this.money = money;
                return this;
            }
            public Person build() {
                return new Person(id, job, money);
            }
     }
}

像下面這樣使用這個構建器:

Person person = new Person.PersonBuilder(personObjectFromDatabase)
    .withMoney(...)
    .build();

或者

您可以創建一個copyWith()方法:

public class Person {
    ...
    public Person copyWith(BigDecimal money) {
        return new Person(this.id, this.job, money);
    }
}

class 是不可變的; 您永遠無法更改該 class 實例的值。

相反,您必須創建 class 的新實例。

不要寫生成器; 您已經在使用 Lombok,只需使用@Builder注釋,Lombok 就會為您創建一個構建器。

編輯:您正在使用構建器注釋。 您正在尋找的解決方案似乎是這樣的:

您必須創建 class 的新實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM