建造者模式

9 篇文章 0 订阅

我的个人网站: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()这些属性的赋值方法呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值