JavaBean之Builder模式

OkidoGreen發表於2020-04-05

https://blog.csdn.net/kangkanglou/article/details/78724240

靜態工廠和構造器
過載建構函式,分別包含多個不同的引數

無法很好地擴充套件到大量的可選引數

JavaBean方式
呼叫一個無參建構函式來建立物件,然後通過setter方法來設定必要引數

物件構造過程被分割到了幾個呼叫,構造過程中可能導致JavaBean處於不一致的狀態,類無法通過檢驗構造器引數的有效性來保證一致性

Builder模式
不直接生成想要的物件,通過呼叫構造器(或靜態工廠),得到builder物件,客戶端在builder物件上呼叫類似setter方法,來設定每個相關的可選引數,最後,再呼叫build方法來生成不可變物件

public class Person {
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }

    private String name;
    private String address;
    private String firstName;
    private String lastName;

    private Person(String name, String address, String firstName, String lastName) {
        this.address = address;
        this.name = name;
        this.lastName = lastName;
        this.firstName = firstName;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {

        private String name;
        private String address;
        private String firstName;
        private String lastName;

        public Builder name(final String name) {
            this.name = name;
            return this;
        }

        public Builder address(final String address) {
            this.address = address;
            return this;
        }

        public Builder lastName(final String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder firstName(final String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Person build() {
            return new Person(name, address, firstName, lastName);
        }
    }
}


客戶端呼叫

Person p = new Person.Builder().address("上海").firstName("三").lastName("張").name("歐陽").build();
        System.out.println(p);
        Person person = Person.builder().address("上海").firstName("三").lastName("張").name("歐陽").build();
        System.out.println(person);


如果我們使用IDE,我們可以直接使用Lombok外掛的@Builder註解,僅需宣告類屬性

@Builder
@ToString
public class LombokPerson {
    private String name;
    private String address;
    private String firstName;
    private String lastName;
}


檢視生成的class原始碼

public class LombokPerson {
    private String name;
    private String address;
    private String firstName;
    private String lastName;

    @ConstructorProperties({"name", "address", "firstName", "lastName"})
    LombokPerson(String name, String address, String firstName, String lastName) {
        this.name = name;
        this.address = address;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public static LombokPerson.LombokPersonBuilder builder() {
        return new LombokPerson.LombokPersonBuilder();
    }

    public String toString() {
        return "LombokPerson(name=" + this.name + ", address=" + this.address + ", firstName=" + this.firstName + ", lastName=" + this.lastName + ")";
    }

    public static class LombokPersonBuilder {
        private String name;
        private String address;
        private String firstName;
        private String lastName;

        LombokPersonBuilder() {
        }

        public LombokPerson.LombokPersonBuilder name(String name) {
            this.name = name;
            return this;
        }

        public LombokPerson.LombokPersonBuilder address(String address) {
            this.address = address;
            return this;
        }

        public LombokPerson.LombokPersonBuilder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public LombokPerson.LombokPersonBuilder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public LombokPerson build() {
            return new LombokPerson(this.name, this.address, this.firstName, this.lastName);
        }

        public String toString() {
            return "LombokPerson.LombokPersonBuilder(name=" + this.name + ", address=" + this.address + ", firstName=" + this.firstName + ", lastName=" + this.lastName + ")";
        }
    }
}


客戶端呼叫:

        LombokPerson lombokPerson = LombokPerson.builder().address("上海").firstName("三").lastName("張").name("歐陽").build();
        System.out.println(lombokPerson);

 

相關文章