建造者模式 2021-11-22 17:31 > 简单的记录下lombok中的建造者模式及使用。不对该模式本身发表意见看法。 ### 一、Lombok中的建造者 添加@Builder注解后,可直接使用建造者模式创建对象并为其属性赋值。 ```java 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) } } ``` 从中很容易看出建造者模式的好处:当某个类属性很多时,使用一般的方法创建对象(构造函数)太复杂,容易搞混是为哪个属性赋了哪些值。而使用建造者模式能够很清爽的完成这一过程。 ```java MessageLogEntity messageLog = new MessageLogEntity(1, "chatbotId123", "messageInfo123"); ``` 这仅仅是三个属性,试想一下,当一个类有多个属性时,且某些属性是必选的,某些是可选的,业务再复杂些,就会出现很多不同的构造函数: ```java 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)实现的,一个注解帮我们解决了很多事情,那如果自己写建造过程,该怎么写呢? ```java 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()这些属性的赋值方法呢? --END--
发表评论