java设计模式之构建者模式

构建者模式不难理解,实现起来也很简单。难点在于使用场景。

它一般适用于业务逻辑比较复杂的类,比如jdbc有很多参数,有一些是必填的,比如host、port、user、password,其他的则是可选参数。

如果按照正常的构造方法,参数可能会爆炸。而采用构造者模式,就会使得这个类的构建变得非常简单。

我们可以把校验逻辑放置到 Builder 类中,先创建建造者,并且通过 set() 方法设置建造者的变量值,

然后在使用 build() 方法真正创建对象之前,做集中的校验,校验通过之后才会创建对象。

同时我们把JDBCConfig的构造方法设为private,不对外暴露set方法,这样就只能使用builder模式创建对象,而且对象还是不可变对象。

/**
 * JDBC配置类,变量很多
 * host、port、user、password、database是必选参数,其他都非必须,有默认值
 * 为了避免构造函数参数爆炸,所以使用构建者模式
 */
public class JDBCConfig {
    private String host;
    private int port;
    private String user;
    private String password;
    private String database;
    private Boolean useUnicode;
    private String characterEncoding;
    private Boolean autoReconnect;
    private Boolean failOverReadOnly;
    private int maxReconnects;
    private int initialTimeout;
    private int connectTimeout;
    private int socketTimeout;

    private JDBCConfig(Builder builder) {
        this.host = builder.host;
        this.port = builder.port;
        this.user = builder.user;
        this.password = builder.password;
        this.database = builder.database;
        this.useUnicode=builder.useUnicode;
        this.characterEncoding=builder.characterEncoding;
        this.autoReconnect=builder.autoReconnect;
        this.failOverReadOnly=builder.failOverReadOnly;
        this.maxReconnects=builder.maxReconnects;
        this.initialTimeout=builder.initialTimeout;
        this.connectTimeout=builder.connectTimeout;
        this.socketTimeout=builder.socketTimeout;
    }

    @Override
    public String toString() {
        return "jdbc:mysql://" +
                 host +
                ":" + port +"/"+database+"?"+
                "user=" + user +
                "&password=" + password +
                "&useUnicode=" + useUnicode +
                "&characterEncoding=" + characterEncoding +
                "&autoReconnect=" + autoReconnect +
                "&failOverReadOnly=" + failOverReadOnly +
                "&maxReconnects=" + maxReconnects +
                "&initialTimeout=" + initialTimeout +
                "&connectTimeout=" + connectTimeout +
                "&socketTimeout=" + socketTimeout ;
    }

    public static class Builder {
        private String host;
        private int port;
        private String user;
        private String password;
        private String database;
        private boolean useUnicode = true;
        private String characterEncoding = "gbk";
        private Boolean autoReconnect = false;
        private Boolean failOverReadOnly = false;
        private int maxReconnects = 3;
        private int initialTimeout = 1800;
        private int connectTimeout = 1800;
        private int socketTimeout = 1800;

        public JDBCConfig build() {
            if (StringUtils.isBlank(host)) {
                throw new IllegalArgumentException("...");
            }
            if(port<0){
                throw new IllegalArgumentException("...");
            }
            if (StringUtils.isBlank(user)) {
                throw new IllegalArgumentException("...");
            }
            if (StringUtils.isBlank(password)) {
                throw new IllegalArgumentException("...");
            }
            if (StringUtils.isBlank(database)) {
                throw new IllegalArgumentException("...");
            }
            return new JDBCConfig(this);
        }

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

        public Builder setPort(int port){
            if(port<0){
                throw new IllegalArgumentException("...");
            }
            this.port=port;
            return this;
        }

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

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

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

        public Builder setUseUnicode(boolean useUnicode) {
            this.useUnicode = useUnicode;
            return this;
        }

        public Builder setCharacterEncoding(String characterEncoding) {
            this.characterEncoding = characterEncoding;
            return this;
        }

        public Builder setAutoReconnect(Boolean autoReconnect) {
            this.autoReconnect = autoReconnect;
            return this;
        }

        public Builder setFailOverReadOnly(Boolean failOverReadOnly) {
            this.failOverReadOnly = failOverReadOnly;
            return this;
        }

        public Builder setMaxReconnects(int maxReconnects) {
            this.maxReconnects = maxReconnects;
            return this;
        }

        public Builder setInitialTimeout(int initialTimeout) {
            this.initialTimeout = initialTimeout;
            return this;
        }

        public Builder setConnectTimeout(int connectTimeout) {
            this.connectTimeout = connectTimeout;
            return this;
        }

        public Builder setSocketTimeout(int socketTimeout) {
            this.socketTimeout = socketTimeout;
            return this;
        }
    }

    public static void main(String[] args) {
        JDBCConfig build = new Builder()
                .setHost("127.0.0.1")
                .setPort(8000)
                .setUser("admin")
                .setPassword("admin@12345")
                .setDatabase("fill")
                .setCharacterEncoding("utf8")
                .build();
        System.out.println(build);

    }
}

输出:

jdbc:mysql://127.0.0.1:8000/fill?user=admin&password=admin@12345&useUnicode=true&characterEncoding=utf8&autoReconnect=false&failOverReadOnly=false&maxReconnects=3&initialTimeout=1800&connectTimeout=1800&socketTimeout=1800

 

上一篇:springboot获取配置文件中的值


下一篇:java实现MD5随机盐加密