解决构造器多参数的设计问题

问题

  在构造类的时候,有些情况下,构造这个类需要的参数会有很多,如果一些参数用户不清楚,你是不是需要自己设定默认值,全部参数都需要提供默认值,这样你的构造方法就需要挺多的了,例如下面这个例子,我是实际参与项目中出现的情况:

例子

  先针对串口类,串口涉及四个参数,一个是波特率,一个是数据位数,一个是停止位,一个是奇偶位。若是比较粗鲁的写法就是如下:

/**
 * Port类
 * 代表串口
 * @author Guo
 *
 */
public class Port {
    private int baud = 1200;        //波特率
    private int databit = 8;        //数据位
    private int stopbit = 1;        //停止位
    private int parity = 0;            //奇偶位
    
    /**
     * 无参数构造方法,串口参数都采用默认的
     */
    public Port() {
        
    }
    
    /**
     * 通过该构造方法设置波特率、数据位、停止位、奇偶位
     * @param baud
     * @param databit
     * @param stopbit
     * @param parity
     */
    public Port(int baud, int databit, int stopbit, int parity) {
        this.baud = baud;
        this.databit = databit;
        this.stopbit = stopbit;
        this.parity = parity;
    }
    
    /**
     * 通过该构造方法设置数据位、停止位、奇偶位,波特率采用默认值
     * @param databit
     * @param stopbit
     * @param parity
     */
    public Port(int databit, int stopbit, int parity) {
        this.databit = databit;
        this.stopbit = stopbit;
        this.parity = parity;
    }
}

  其实该构造器还有很多种情况,这样的话我们写起来就很麻烦了,而且例如上面的两个构造器都是三个参数的,用起来怎么知道是谁。接下来就提出我们的解决方案。

方法之JavaBean模式

  为各个参数提供setter方法,通过setter方法去设置属性的值,从而达到用户选择性设置属性值。

/**
 * Port_JavaBean类
 * 以JavaBean模式去设置属性值
 * @author xujianguo
 */
public class Port_JavaBean {
    private int baud = 1200;        //波特率
    private int databit = 8;        //数据位
    private int stopbit = 1;        //停止位
    private int parity = 0;         //奇偶位
    
    public Port_JavaBean(){}
    
    /**
     * 为各个属性提供setter方法去设置值
     * @return
     */
    public int getBaud() {
        return baud;
    }
    public void setBaud(int baud) {
        this.baud = baud;
    }
    public int getDatabit() {
        return databit;
    }
    public void setDatabit(int databit) {
        this.databit = databit;
    }
    public int getStopbit() {
        return stopbit;
    }
    public void setStopbit(int stopbit) {
        this.stopbit = stopbit;
    }
    public int getParity() {
        return parity;
    }
    public void setParity(int parity) {
        this.parity = parity;
    }
}

  这个JavaBean模式一个重要的缺点:

    因为构造过程被分到了几个调用中构造过程中JavaBean可能处于不一致的状态

方法之Builder模式

  该模式不直接生成想要的对象,而是让客户端调用构造器,得到一个builder对象,然后调用类似setter的方法来设置参数值,这个buidler对象完成后通过这个对象去设置Port类的真正属性。

/**
 * Port_Builder类
 * 以Builder模式构建类
 * @author xujianguo
 */
public class Port_Builder {
    private int baud;        //波特率
    private int databit;    //数据位
    private int stopbit;    //停止位
    private int parity;        //奇偶位
    
    public static class Builder {
        //默认值
        private int baud = 1200;
        private int databit = 8;
        private int stopbit = 1;
        private int parity = 0;
        
        public Builder() {}
        
        /**
         * 设置baud属性值
         * @param baud
         * @return
         */
        public Builder setBaud(int baud) {
            this.baud = baud;
            return this;
        }
        
        /**
         * 设置databit属性值
         * @param databit
         * @return
         */
        public Builder setDatabit(int databit) {
            this.databit = databit;
            return this;
        }
        
        /**
         * 设置stopbit属性值
         * @param stopbit
         * @return
         */
        public Builder setStopbit(int stopbit) {
            this.stopbit = stopbit;
            return this;
        }
        
        /**
         * 设置parity属性值
         * @param parity
         * @return
         */
        public Builder setParity(int parity) {
            this.parity = parity;
            return this;
        }
        
        /**
         * 通过Builder里面设置好的属性,创建串口
         * @return
         */
        public Port_Builder build() {
            return new Port_Builder(this);
        }
    }
    
    /**
     * 私有的构造方法,仅提供给Builder创建它的实例
     * @param builder
     */
    private Port_Builder(Builder builder) {
        this.baud = builder.baud;
        this.databit = builder.databit;
        this.stopbit = builder.stopbit;
        this.parity = builder.parity;
    }
}

   这个模式的最大优点就是首先通过一个Builder类设置好要修改的属性值,然后根据这个Builder对象去创建Port_Builder类,这个就解决了JavaBean模式暴露的状态不一致的问题,而且也具有了JavaBean模式的优点。

 

posted on 2015-05-04 23:14  进击的Ray_xujianguo  阅读(341)  评论(0编辑  收藏  举报

导航