我的个人网站:http://riun.xyz
简单的记录下lombok中的建造者模式及使用。不对该模式本身发表意见看法。
一、Lombok中的建造者
添加@Builder注解后,可直接使用建造者模式创建对象并为其属性赋值。
package com.example.demo.pojo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: HanXu
* on 2021/11/10
* Class description: Builder建造者模式的链式实现
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MessageLogEntity {
private int passagewayType;
private String chatbotId;
private String messageInfo;
public static void main(String[] args) {
MessageLogEntity messageLog = MessageLogEntity.builder()
.chatbotId("chatbotId123")
.messageInfo("messageInfo123")
.passagewayType(1).build();
System.out.println(messageLog);
//MessageLogEntity(passagewayType=1, chatbotId=chatbotId123, messageInfo=messageInfo123)
}
}
从中很容易看出建造者模式的好处:当某个类属性很多时,使用一般的方法创建对象(构造函数)太复杂,容易搞混是为哪个属性赋了哪些值。而使用建造者模式能够很清爽的完成这一过程。
MessageLogEntity messageLog = new MessageLogEntity(1, "chatbotId123", "messageInfo123");
这仅仅是三个属性,试想一下,当一个类有多个属性时,且某些属性是必选的,某些是可选的,业务再复杂些,就会出现很多不同的构造函数:
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HttpRequestDTO {
/**
* 请求url
*/
private String url;
/**
* 请求contentType,默认application/json;charset=UTF-8
*/
private String contentType = MediaType.APPLICATION_JSON_UTF8_VALUE;
/**
* 请求方式,默认post
*/
private String httpMethod = HttpMethod.POST.name();
/**
* 请求超时时间,默认5s
*/
private int connTimeout = 5;
/**
* 会话超时时间,默认5s
*/
private int socketTimeout = 5;
/**
* 连接池获取连接/创建连接超时时间,默认1s
*/
private int connReqTimeout = 1;
//结果化参数
/**
* 请求body 相当于postman中的raw json
*/
private String bodyJson;
private Map<String, Object> head = new HashMap<>();
private Map<String, Object> query = new HashMap<>();
private Map<String, Object> body = new HashMap<>();
private Map<String, Object> template = new HashMap<>();
private Map<String, Object> paths = new HashMap<>();
// 随机数
private String boundary;
private MultipartFile file;
private long startTime = System.currentTimeMillis();
public HttpRequestDTO(){
}
public HttpRequestDTO(String httpMethod, String url, Map<String, Object> head){
this.httpMethod = httpMethod;
this.url=url;
this.head = head;
}
public HttpRequestDTO(String url, Map<String, Object> head, MultipartFile file){
this.url=url;
this.file = file;
this.head = head;
}
public HttpRequestDTO(String url, Map<String, Object> head, String bodyJson){
this.url=url;
this.head = head;
this.bodyJson = bodyJson;
}
public HttpRequestDTO(String url, Map<String, Object> head, Map<String, Object> body){
this.url=url;
this.head = head;
this.body = body;
}
}
面对这么多构造函数,使用时难免弄混,若许多参数类型一样,那就更烦了。
二、如何实现?
Lombok是通过直接操纵抽象语法树(AST)实现的,一个注解帮我们解决了很多事情,那如果自己写建造过程,该怎么写呢?
package com.example.demo.pojo;
/**
* @author: HanXu
* on 2021/11/10
* Class description: Builder建造者模式的链式实现
*/
public class MessageLogDownEntity {
private int passagewayType;
private String chatbotId;
private String messageInfo;
@Override
public String toString() {
return "MessageLogDownEntity{" +
"passagewayType=" + passagewayType +
", chatbotId='" + chatbotId + '\'' +
", messageInfo='" + messageInfo + '\'' +
'}';
}
// TODO: 2021/11/22 省略get set方法
/**
* 供Builder类内部builder,为主体类赋值
* @param messageLogDownEntityBuilder
*/
private MessageLogDownEntity(MessageLogDownEntityBuilder messageLogDownEntityBuilder) {
this.passagewayType = messageLogDownEntityBuilder.passagewayType;
this.chatbotId = messageLogDownEntityBuilder.chatbotId;
this.messageInfo = messageLogDownEntityBuilder.messageInfo;
}
/**
* 供外界直接使用 Class.builder()
* @return
*/
public static MessageLogDownEntityBuilder builder(){
return new MessageLogDownEntityBuilder();
}
/**
* 内部Builder类,主要功能是提供给外部.chatbotId()的方法
*/
public static class MessageLogDownEntityBuilder {
private int passagewayType;
private String chatbotId;
private String messageInfo;
public MessageLogDownEntityBuilder chatbotId(String chatbotId) {
this.chatbotId = chatbotId;
return this;
}
public MessageLogDownEntityBuilder messageInfo(String messageInfo) {
this.messageInfo = messageInfo;
return this;
}
public MessageLogDownEntityBuilder passagewayType(int passagewayType) {
this.passagewayType = passagewayType;
return this;
}
public MessageLogDownEntity build() {
return new MessageLogDownEntity(this);
}
}
public static void main(String[] args) {
MessageLogDownEntity messageDown = MessageLogDownEntity.builder()
.chatbotId("chatbotId123")
.messageInfo("messageInfo123")
.passagewayType(1).build();
System.out.println(messageDown);
//MessageLogDownEntity{passagewayType=1, chatbotId='chatbotId123', messageInfo='messageInfo123'}
}
}
以上就是链式创建者模式的实现。相较于传统的4角色创建者模式,省去了许多不必要的繁琐步骤。
扩展:
为什么不直接在外部主体类中添加chatbotId()这些属性的赋值方法呢?