設(shè)計(jì)模式那點(diǎn)事-萬物皆可“建造者”

這個(gè)專題,我們將要學(xué)習(xí)一下設(shè)計(jì)模式,建造者模式——快速構(gòu)建對(duì)象。

閱讀目錄:

  1. 什么是建造者模式;
  2. 建造者模式源碼實(shí)戰(zhàn);
  3. 建造者模式lombok快速實(shí)現(xiàn);
  4. 如何“萬物皆可建造者”快速創(chuàng)建對(duì)象;

1. 什么是建造者模式

工廠模式實(shí)現(xiàn):獲取對(duì)象;
建造模式實(shí)現(xiàn):創(chuàng)建對(duì)象;


建造模式利用一個(gè)導(dǎo)演者(Director)和具體建造者(Builder)對(duì)象,將所需的零件一個(gè)個(gè)建造出來,從而建造出完整的產(chǎn)品對(duì)象。建造者模式將產(chǎn)品結(jié)構(gòu)和產(chǎn)品零件
的建造過程隱藏起來,把対建造過程進(jìn)行指揮具體建造者的責(zé)任分割開,達(dá)成責(zé)任劃分和封裝的目的。

建造模式的結(jié)構(gòu)

2. 建造者模式源碼實(shí)戰(zhàn)

我們?cè)谠O(shè)置BasicProperties()時(shí)候,是不是要寫這么復(fù)雜的引用鏈代碼,是不是有時(shí)候感覺到一臉蒙蔽?

public class MQBuilder {
    public static void main(String[] args) {
        // 一個(gè)是replyTo設(shè)置回調(diào)隊(duì)列,另一是correlationId(相關(guān)性Id)為每個(gè)隊(duì)列設(shè)置唯一值
        AMQP.BasicProperties props = new AMQP.BasicProperties().builder().correlationId("XP123")
                .replyTo("replyQueueName").build();
    }
}

那好我們就可以分析一下源碼了。
正如溫故知新——內(nèi)部類中,我們知道靜態(tài)內(nèi)部類對(duì)象的創(chuàng)建方式:
外部類.內(nèi)部類 XX=new 外部類.內(nèi)部類();

  1. 那么我們分析其實(shí)BasicProperties就是一個(gè)靜態(tài)內(nèi)部類,最后的build方法【返回的Product產(chǎn)品】也就是new AMQP.basicProperties(XXX),完成具體建造類的功能之一:返回建造完畢產(chǎn)品對(duì)象。
    public AMQP.BasicProperties build() {
                return new AMQP.BasicProperties(this.contentType, 
this.contentEncoding, this.headers, this.deliveryMode, this.priority, 
this.correlationId, this.replyTo, this.expiration, this.messageId, 
this.timestamp, this.type, this.userId, this.appId, this.clusterId);
            }
  1. 我們繼續(xù)看new AMQP.BasicProperties().builder()這個(gè)調(diào)用鏈,其實(shí)就是創(chuàng)建了內(nèi)部靜態(tài)內(nèi)build對(duì)象。

Builder里面包含了零件信息,用戶可以將自己需求傳入到Builder對(duì)象,實(shí)現(xiàn)實(shí)時(shí)傳入到Director的效果。

      public static final class Builder {
            private String contentType;
            private String contentEncoding;
            private Map<String, Object> headers;
            private Integer deliveryMode;
            private Integer priority;
            private String correlationId;
         ...
  
            public Builder() {
            }

            public AMQP.BasicProperties.Builder contentType(String contentType) {
                this.contentType = contentType;
                return this;
            }

            public AMQP.BasicProperties.Builder contentEncoding(String contentEncoding) {
                this.contentEncoding = contentEncoding;
                return this;
            }

            public AMQP.BasicProperties.Builder headers(Map<String, Object> headers) {
                this.headers = headers;
                return this;
            }

            public AMQP.BasicProperties.Builder deliveryMode(Integer deliveryMode) {
                this.deliveryMode = deliveryMode;
                return this;
            }

            ...
            public AMQP.BasicProperties build() {
                return new AMQP.BasicProperties(this.contentType, this.contentEncoding, this.headers, this.deliveryMode, this.priority, this.correlationId, this.replyTo, this.expiration, this.messageId, this.timestamp, this.type, this.userId, this.appId, this.clusterId);
            }
        }
    }

3. 建造者模式lombok快速實(shí)現(xiàn)

在lombok插件中使用@Builder注解,就可以為POJO提供建造者模式:

源代碼:

@Builder(toBuilder = true)
@Getter
public class Address {
    private String address;
    private String phone;
}

class反編譯文件

package com.protoType.MySchema;

public class Address
{
  private String address;
  private String phone;

  Address(String address, String phone)
  {
    this.address = address; this.phone = phone; } 
  public static AddressBuilder builder() { return new AddressBuilder(); }

  public AddressBuilder toBuilder() { return new AddressBuilder().address(this.address).phone(this.phone); }

  public String getAddress() { return this.address; } 
  public String getPhone() { return this.phone;
  }

  public static class AddressBuilder
  {
    private String address;
    private String phone;

    public AddressBuilder address(String address)
    {
      this.address = address; return this; } 
    public AddressBuilder phone(String phone) { this.phone = phone; return this; } 
    public Address build() { return new Address(this.address, this.phone); } 
    public String toString() { return "Address.AddressBuilder(address=" + this.address + ", phone=" + this.phone + ")";
    }
  }
}

4. 如何“萬物皆可建造者”快速創(chuàng)建對(duì)象

場景:不想每次使用Map的時(shí)候都要先new Map,然后一次次的put,那么就可以使用建造者模式來實(shí)現(xiàn)MapExample。

public class MapExample {

    private MapExample() {

    }

    /**
     * 快速創(chuàng)建Map對(duì)象
     */
    public static MapExample.Builder builder() {
        return new MapExample.Builder();
    }

    public static class Builder {

        private Map<String, Object> map;

        Builder() {
            map = new HashMap<>();
        }

        public MapExample.Builder put(String key, Object value) {
            map.put(key, value);
            return this;
        }

        public MapExample.Builder putAll(Map<String, Object> objectMap) {
            map.putAll(objectMap);
            return this;
        }

        public Map<String, Object> build() {
            return map;
        }

    }
}

使用方式:

        Map<String, Object> map = MapExample.builder().
                put("url", request.getURI().toString()).
                put("header", request.getHeaders()).
                put("body", new String(body)).
                put("response", responseBody).
                put("executeTime", System.currentTimeMillis() - startTime).
                build();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容