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

问题

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

例子

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

/**
 * 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模式的优点。

时间: 2024-07-30 10:17:52

解决构造器多参数的设计问题的相关文章

C++ 11可变参数接口设计在模板编程中应用的一点点总结

概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量(或属性,C#中属性和成员变量还是有区别的): 类的成员方法: 从编译器的角度看,我们必须明确指定以上3部分,才算完整地定义了一个类并且编译通过. 所谓的“类弱化”,是指类的设计者在定义类的时候,并没有完整定义一个类,而是把类的其中一部分的定义留给类的使用者. 从传统才c++98看,通过模板类,使用

解决url中文参数乱码的问题--解码

<html> <body> <h3 class="projectName" id="projectName"></h3> <script type="text/javascript"> var unitID;    var unitName;    //获取参数的函数    function geturlPara()    {        var url = document.URL;

利用jQuery 解决URL请求参数有中文时出现乱码的问题

利用jQuery 解决URL请求参数有中文时出现乱码的问题 在开发的时候经常会碰到URL中请求参数含有中文的情况,这时如果在前台不作处理,直接在后台利用request.getParameter()拿对应的参数值就会出现中文乱码. 这时可以先利用jQuery对对应中文进行encodeURI(),例子如下: 前台对应代码 <!--省畋无关代码--> <input type="button" id="submitA" value="重发短信&q

SpringMVC 完美解决PUT请求参数绑定问题(普通表单和文件表单)

一 解决方案 修改web.xml配置文件 将下面配置拷贝进去(在原有的web-app节点里面配置 其它配置不变) <!-- 处理PUT提交参数(只对基础表单生效) --> <filter> <filter-name>httpPutFormContentFilter</filter-name> <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filt

二、一个类的构造器的参数有很多时,怎么办?答案:构建器

首先我们举一个例子简单一点的例子,该类中有2个属性,2个必要属性,2个可选择的属性 class A214{ //必要属性 private String import1; private String import2; private String optional1; private String optional2; } 采用这一种方案:重叠构造器 class A214{ //必要属性 private String import1; private String import2; //可选属性

从零开始设计SOA框架(二):请求/响应参数的设计

每个接口都有请求参数.响应参数.其中请求参数分为公共参数和业务参数.响应参数分为两类:正常的响应参数.统一的错误参数 一.请求参数 1.公共参数:每个接口都有的参数,主要包含appkey.时间戳.版本.响应格式.session 参考淘宝开放平台如下: 公共请求参数:a) session:有些接口需要登陆后才能调用,所以需要传递session参数b) timestamp:用于验证相同一组参数值不能重复使用,如其它参数都一样,timestamp也一样可考虑是否参数被他人截获并反复调用,服务端遇到这种

asp.net如何解决传递中文参数乱码问题

其实,解决此问题很简单,只需在传递的中文参数用escape()就可以解决了,至于后台c#只需用Page.Request.Params来获取就可以了! 版权声明:本文为博主原创文章,未经博主允许不得转载.

Python函数的默认参数的设计【原创】

在Python教程里,针对默认参数,给了一个“重要警告”的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3)) 默认值只会执行一次,也没说原因.会打印出结果: [1] [1, 2] [1, 2, 3] 因为学的第一门语言是Ruby,所以感觉有些奇怪. 但肯定的是方法f一定储存了变量L. 准备知识:指针 p指向不可变对象,比如数字.则相当于p指针指向了不同的内存地址. p指向的是可变对象,比如lis

sqlserver 必须声明标量变量 &quot;@id&quot; 什么原因,如何解决 存储过程 带参数

sqlserver 必须声明标量变量 "@id". 原因 set @sql = 'insert into stu(id,name) select top @id from stus'  // 错误 解决办法 set @sql = 'insert into stu(id,name) select top '+CONVERT(char(3),@id) +'from stus'  //正确