设计模式之美--建造者模式

建造者模式的作用:创建对象;
为什么要使用创建者模式来创建对象,普通的new对象不可以吗?

  1. 如果使用构造器来创建对象,当参数值的数量过多时,代码中的构造器数量和形式较混乱,并且给构造器中的参数赋值,且参数数量太多。很容易出错,看起来也不是那么清晰;
  2. 如果用无参构造或者有参构造(对一些必填的参数)来new出对象,然后对其他的不必填的参数使用set方法填充。肯定比上面完全使用有参构造器更加简洁清晰;
  3. 如果有个需求 对于创建出来的对象的成员变量有些额外逻辑的限制条件;为了保证创建出来的对象一定是正确有效的对象。可以使用建造者模式;
  4. 当然对于对象中的必填参数可以使用有参构造器来创建,并在构造器里写校验逻辑,但有涉及到第一个问题:必填参数过多呢,参数过乱呢?
  • 总结:构造器创建对象可以有校验逻辑,但是参数多较乱可读性差;使用set方法,简单清晰,但是无法做到必要的参数校验;
  • 建造者模式在创建好对象后,该对象就不能随意修改内部的值(如set方法)
/**
 * 建造器模式demo
 * @author lq
 * @version : ResourcePoolConfig.java, v 0.1 2022年12月23日 10:47 lq Exp $
 */
public class ResourcePoolConfig {
    private String name;
    private int maxTotal;
    private int maxIdle;
    private int minIdle;

    private ResourcePoolConfig(Builder builder) {
        this.name = builder.name;
        this.maxTotal = builder.maxTotal;
        this.maxIdle = builder.maxIdle;
        this.minIdle = builder.minIdle;
    }
    // 省略get方法,不暴露set方法,保证创建出来的对象是不可变对象

    public static class Builder {
        private static final int DEFAULT_MAX_TOTAL = 8;
        private static final int DEFAULT_MAX_IDLE = 8;
        private static final int DEFAULT_MIN_IDLE = 0;

        private String name;
        private int maxTotal = DEFAULT_MAX_TOTAL;
        private int maxIdle = DEFAULT_MAX_IDLE;
        private int minIdle = DEFAULT_MIN_IDLE;

        public ResourcePoolConfig build() {
            //校验逻辑都在这里写:必填校验、依赖关系校验、约束校验
            if (StringUtils.isBlank(name)) {
                throw new IllegalArgumentException("...");
            }
            if (maxIdle > maxTotal) {
                throw new IllegalArgumentException("..."); 
            }
            if (minIdle > maxTotal || minIdle > maxIdle) {
                throw new IllegalArgumentException("...");
            }
            return new ResourcePoolConfig(this);
        }

        public Builder setName(String name) {
            if (StringUtils.isBlank(name)) {
                throw new IllegalArgumentException("...");
            }
            this.name = name;
            return this;
        }

        public Builder setMaxTotal(int maxTotal) {
            if (maxTotal <= 0) {
                throw new IllegalArgumentException("...");
            }
            this.maxTotal = maxTotal;
            return this;
        }
        
        public Builder setMaxIdle(int maxIdle) {
            if (maxIdle < 0) {
                throw new IllegalArgumentException("...");
            }
            this.maxIdle = maxIdle;
            return this;
        }
        
        public Builder setMinIdle(int minIdle) {
            if (minIdle < 0) {
                throw new IllegalArgumentException("...");
            }
            this.minIdle = minIdle;
            return this;
        }
    }
    
}
ResourcePoolConfig config = new ResourcePoolConfig.Builder()
                .setName("xxx")
                .setMaxTotal(8)
                .build();
posted @   lq-12040  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示