這個(gè)專題,我們將要學(xué)習(xí)一下設(shè)計(jì)模式,建造者模式——快速構(gòu)建對(duì)象。
閱讀目錄:
- 什么是建造者模式;
- 建造者模式源碼實(shí)戰(zhàn);
- 建造者模式lombok快速實(shí)現(xiàn);
- 如何“萬物皆可建造者”快速創(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)部類();
- 那么我們分析其實(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);
}
- 我們繼續(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();