zoukankan      html  css  js  c++  java
  • 设计模式之建造者模式

    由于需求的变更,有个项目的实体类的构造器变动频繁,即对象实例的组成属性变动频繁。
    后来注意到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;
    }

  • 相关阅读:
    hdu 3791 二叉搜索树
    hdu 4041 Eliminate Witches! 栈和队列
    后缀数组讲解
    Theme Section HDU
    Wow! Such Doge! HDU
    Girls' research HDU
    吉哥系列故事――完美队形II HDU
    Best Reward HDU
    String Problem HDU
    最大最小表示法
  • 原文地址:https://www.cnblogs.com/miaoying/p/10448983.html
Copyright © 2011-2022 走看看