Builder构建器模式
因要对接大华的硬件API,调用Map参数太多所以需要封装一下对应的工具类,参数使用BeanDTO
各实现方式的对比
| 模式 | 优点 | 缺点 |
|---|---|---|
| 经典 Builder 模式 | 参数验证方便,不可变对象 | 代码量较大 |
| Lombok @Builder | 代码简洁 | 依赖外部库 |
传统builder模式
package com.ruoyi.task.utils.params.VO;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
@Getter
public class DistribStatisticParam {
private final Integer pageNum;
private final Integer pageSize;
private final List<String> regionIds;
private final Integer regionType;
private final Integer reportType;
private final String reportTime;
private final String reportBeginTime;
private final Integer reportModel;
private DistribStatisticParam(Builder builder) {
if (builder.pageNum == null) {
throw new IllegalArgumentException("pageNum 不能为空");
}
if (builder.pageSize == null) {
throw new IllegalArgumentException("pageSize 不能为空");
}
if (builder.regionIds.isEmpty()) {
throw new IllegalArgumentException("regionIds 不能为空");
}
if (builder.regionType == null) {
throw new IllegalArgumentException("regionType 不能为空");
}
if (builder.reportType == null) {
throw new IllegalArgumentException("reportType 不能为空");
}
if (StringUtils.isBlank(builder.reportTime)) {
throw new IllegalArgumentException("reportTime 不能为空");
}
if (StringUtils.isBlank(builder.reportBeginTime)) {
throw new IllegalArgumentException("reportBeginTime 不能为空");
}
if (builder.reportModel == null) {
throw new IllegalArgumentException("reportModel 不能为空");
}
this.pageNum = builder.pageNum;
this.pageSize = builder.pageSize;
this.regionIds = builder.regionIds;
this.regionType = builder.regionType;
this.reportType = builder.reportType;
this.reportTime = builder.reportTime;
this.reportBeginTime = builder.reportBeginTime;
this.reportModel = builder.reportModel;
}
public static class Builder {
private Integer pageNum;
private Integer pageSize;
private List<String> regionIds;
private Integer regionType;
private Integer reportType;
private String reportTime;
private String reportBeginTime;
private Integer reportModel;
public Builder pageNum(Integer pageNum) {
this.pageNum = pageNum;
return this;
}
public Builder pageSize(Integer pageSize) {
this.pageSize = pageSize;
return this;
}
public Builder regionIds(List<String> regionIds) {
this.regionIds = regionIds;
return this;
}
public Builder regionType(Integer regionType) {
this.regionType = regionType;
return this;
}
public Builder reportType(Integer reportType) {
this.reportType = reportType;
return this;
}
public Builder reportTime(String reportTime) {
this.reportTime = reportTime;
return this;
}
public Builder reportBeginTime(String reportBeginTime) {
this.reportBeginTime = reportBeginTime;
return this;
}
public Builder reportModel(Integer reportModel) {
this.reportModel = reportModel;
return this;
}
public DistribStatisticParam build() {
return new DistribStatisticParam(this);
}
}
}
Lombok @Builder实现,并重写builder和build方法实现校验字段。
package com.ruoyi.task.utils.params;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.*;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
@Slf4j
@Value
@Builder
public class PersonInfoDTO {
/**
* service子系统编码,默认evo-thirdParty
*/
@Builder.Default
String service = "evo-thirdParty";
/**
* 人员id,调人员全局id生成获取,需唯一
*/
@NotNull(message = "id 不能为空")
Long id;
/**
* 人员姓名,长度1-25位,允许输入的值:数字、字母、下划线、中文、横线、点,最大长度25个字符,不能以空格开头和结尾
*/
@NotBlank(message = "name 不能为空")
@Size(max = 25, message = "name 长度1-25位")
String name;
/**
* 人员编码,1-30位,数字、字母,需唯一
*/
@NotBlank(message = "code 不能为空")
@Size(max = 30, message = "code 长度1-30位")
String code;
/**
* 证件类型
*/
@NotNull(message = "paperType 不能为空")
Integer paperType;
/**
* 证件号码,需唯一
*/
@NotNull(message = "paperNumber 不能为空")
String paperNumber;
/**
* 证件地址,长度1-64位,允许输入的值(如:数字、字母、中文、-、_、()、0、#、*或者空格,首尾不能包含空格)
*/
@NotBlank(message = "paperAddress 不能为空")
@Size(max = 64, message = "paperAddress 长度1-64位")
String paperAddress;
/**
* 构建PersonInfoDTO实例
* @return PersonInfoDTO构建器
*/
public static PersonInfoDTOBuilder builder() {
return new InternalBuilder();
}
/**
* 内部构建器类,用于创建和验证PersonInfoDTO实例
*/
public static class InternalBuilder extends PersonInfoDTOBuilder {
InternalBuilder() {
super();
}
/**
* 构建并验证PersonInfoDTO实例
* @return 经过验证的PersonInfoDTO实例
* @throws IllegalArgumentException 如果参数校验失败
*/
@Override
public PersonInfoDTO build() {
PersonInfoDTO personInfoDTO = super.build();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<PersonInfoDTO>> validate = validator.validate(personInfoDTO);
if (!validate.isEmpty()){
for (ConstraintViolation<PersonInfoDTO> violation : validate){
log.error("参数校验异常:{}",violation.getMessage());
}
throw new IllegalArgumentException("参数校验异常");
}
return personInfoDTO;
}
}
}
自定义 Builder (InternalBuilder)
继承 PersonInfoDTOBuilder,覆盖 build() 方法。
在调用 build() 时会执行字段校验:
使用 ValidatorFactory 创建验证器;
调用 validator.validate(personInfoDTO) 进行校验;
如果存在校验错误,记录日志并抛出 IllegalArgumentException 异常。
替换默认 builder 方法
2287

被折叠的 条评论
为什么被折叠?



