设计模式之建造者模式

由于需求的变更,有个项目的实体类的构造器变动频繁,即对象实例的组成属性变动频繁。
后来注意到StringBuilder和Swagger的ParameterBuilder的内部实现,发现可以非常灵活的构造出StringBuilder和ParameterBuider的实例,他们都是采用了构造者模式。

1. 以ParameterBuilder为例,构造对象实例方式如下(可以仅选择需要的属性进行赋值)

     // 方式一
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        parameterBuilder
                .description("description")
                .hidden(true)
                .name("name")
                .parameterAccess("parameterAccess")
                .parameterType("parameterType");
        Parameter parameter = parameterBuilder.build();

        // 方式二
        Parameter builder = new ParameterBuilder()
                .name("name")
                .parameterType("paramterType")
                .allowMultiple(true)
                .defaultValue("defaultValue")
                .build();

2. ParameterBuilder的实现(属性与Parameter的一致,为每一个属性添加方法,重点是添加build方法构造Parameter,需要Parameter有一个全部属性的构造函数)

public class ParameterBuilder {
    private String name;
    private String description;
    private String defaultValue;
    private boolean required;
    private boolean allowMultiple;
    private AllowableValues allowableValues;
    private String paramType;
    private String paramAccess;
    private ResolvedType type;
    private ModelReference modelRef;
    private boolean hidden;
    private List<VendorExtension> vendorExtensions = Lists.newArrayList();

    public ParameterBuilder() {
    }

    ParameterBuilder from(Parameter other) {
        return this.name(other.getName()).allowableValues(other.getAllowableValues()).allowMultiple(other.isAllowMultiple()).defaultValue(other.getDefaultValue()).description(other.getDescription()).modelRef(other.getModelRef()).parameterAccess(other.getParamAccess()).parameterType(other.getParamType()).required(other.isRequired()).type((ResolvedType)other.getType().orNull()).hidden(other.isHidden()).vendorExtensions(other.getVendorExtentions());
    }

    public ParameterBuilder name(String name) {
        this.name = (String)BuilderDefaults.defaultIfAbsent(name, this.name);
        return this;
    }

    public ParameterBuilder description(String description) {
        this.description = (String)BuilderDefaults.defaultIfAbsent(description, this.description);
        return this;
    }

    public ParameterBuilder defaultValue(String defaultValue) {
        this.defaultValue = (String)BuilderDefaults.defaultIfAbsent(defaultValue, this.defaultValue);
        return this;
    }

    public ParameterBuilder required(boolean required) {
        this.required = required;
        return this;
    }

    public ParameterBuilder allowMultiple(boolean allowMultiple) {
        this.allowMultiple = allowMultiple;
        return this;
    }

    public ParameterBuilder allowableValues(AllowableValues allowableValues) {
        this.allowableValues = BuilderDefaults.emptyToNull(allowableValues, this.allowableValues);
        return this;
    }

    public ParameterBuilder parameterType(String paramType) {
        this.paramType = (String)BuilderDefaults.defaultIfAbsent(paramType, this.paramType);
        return this;
    }

    public ParameterBuilder parameterAccess(String paramAccess) {
        this.paramAccess = (String)BuilderDefaults.defaultIfAbsent(paramAccess, this.paramAccess);
        return this;
    }

    public ParameterBuilder type(ResolvedType type) {
        this.type = (ResolvedType)BuilderDefaults.defaultIfAbsent(type, this.type);
        return this;
    }

    public ParameterBuilder modelRef(ModelReference modelRef) {
        this.modelRef = (ModelReference)BuilderDefaults.defaultIfAbsent(modelRef, this.modelRef);
        return this;
    }

    public ParameterBuilder hidden(boolean hidden) {
        this.hidden = hidden;
        return this;
    }

    public ParameterBuilder vendorExtensions(List<VendorExtension> extensions) {
        this.vendorExtensions.addAll(BuilderDefaults.nullToEmptyList(extensions));
        return this;
    }

    public Parameter build() {
        return new Parameter(this.name, this.description, this.defaultValue, this.required, this.allowMultiple, this.modelRef, Optional.fromNullable(this.type), this.allowableValues, this.paramType, this.paramAccess, this.hidden, this.vendorExtensions);
    }
}

3. parameter的实现(主要是需要一个全部属性的构造函数)

public class Parameter {
    private final String name;
    private final String description;
    private final String defaultValue;
    private final Boolean required;
    private final Boolean allowMultiple;
    private final ModelReference modelRef;
    private final Optional<ResolvedType> type;
    private final AllowableValues allowableValues;
    private final String paramType;
    private final String paramAccess;
    private final Boolean hidden;
    private final List<VendorExtension> vendorExtensions;

    public Parameter(String name, String description, String defaultValue, boolean required, boolean allowMultiple, ModelReference modelRef, Optional<ResolvedType> type, AllowableValues allowableValues, String paramType, String paramAccess, boolean hidden, List<VendorExtension> vendorExtensions) {
        this.description = description;
        this.defaultValue = defaultValue;
        this.required = required;
        this.allowMultiple = allowMultiple;
        this.modelRef = modelRef;
        this.type = type;
        this.allowableValues = allowableValues;
        this.paramType = paramType;
        this.paramAccess = paramAccess;
        this.name = name;
        this.hidden = hidden;
        this.vendorExtensions = vendorExtensions;
    }

    public Optional<ResolvedType> getType() {
        return this.type;
    }

    public String getName() {
        return this.name;
    }

    public String getDescription() {
        return this.description;
    }

    public String getDefaultValue() {
        return this.defaultValue;
    }

    public Boolean isRequired() {
        return this.required;
    }

    public Boolean isAllowMultiple() {
        return this.allowMultiple;
    }

    public AllowableValues getAllowableValues() {
        return this.allowableValues;
    }

    public String getParamType() {
        return this.paramType;
    }

    public String getParamAccess() {
        return this.paramAccess;
    }

    public ModelReference getModelRef() {
        return this.modelRef;
    }

    public Boolean isHidden() {
        return this.hidden;
    }

    public List<VendorExtension> getVendorExtentions() {
        return this.vendorExtensions;
    }
}

在Lombok中也有两个注解可以方便构造对象实例:@Builder和@Accessors(chain = true),但是使用这两个注解时,均不能构造出父类对象的属性,如下所示:

package cn.ucmed.pangu.lib.builders;

import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 *  @Description:
 *  @author miaoying
 *  @date 2019/3/1
 */
public class Demo {

    public static void main(String[] args) {
        Test test = new Test().setName("name1");
        System.out.println(test); // Test(name=name1, value=null)
        Test2 test2 = Test2.builder().name("name2").build();
        System.out.println(test2); // Test2(name=name2, value=null)

        Son son = Son.builder().sonName("sonName").build();  //  不能设置parentName
        System.out.println(son); // Son(sonName=sonName)

        Daughter daughter = new Daughter().setDaughterName("name");  //  不能设置parentName
        System.out.println(daughter); // Daughter(daughterName=name)
    }
}

@Data
@Accessors(chain = true)
class Test {
    private String name;
    private String value;
}

@Data
@Builder
class Test2 {
    private String name;
    private String value;
}

@Data
class Parent {
    private String parentName;
}

@Data
@Builder
class Son extends Parent {
    private String sonName;
}

@Data
@Accessors(chain = true)
class Daughter extends Parent {
    private String daughterName;
}

原文地址:https://www.cnblogs.com/miaoying/p/10448983.html