• 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
  • 相关阅读:
    WPF 中依赖属性的继承(Inherits)
    使用FluentValidation来进行数据有效性验证
    使用ASP.Net WebAPI构建REST服务(六)——Self-Host
    使用ASP.Net WebAPI构建REST服务(五)——客户端
    使用ASP.Net WebAPI构建REST服务(四)——参数绑定
    使用ASP.Net WebAPI构建REST服务(三)——返回值
    使用ASP.Net WebAPI构建REST服务(二)——路由
    使用ASP.Net WebAPI构建REST服务(一)——简单的示例
    WPF在代码中创建DataTemplate时候的异常
    一个简单的WeakList的实现
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15858881.html
Copyright © 2020-2023  润新知