Effective Java 创建和销毁对象 2.遇到多个构造器参数时要考虑用构建器



静态工厂跟构造器都有一个共同的局限性:不能很好的扩展到大量的参数。


例:

package com.example.yancy.yancy;


/**
 * Created by yancy on 2017/8/24.
 */


public class Person {
    /**
     * 姓名
     */
    private String name;
    /**
     *性别
     */
    private String sex;
    /**
     *年龄
     */
    private int age;
    /**
     *唯一识别(身份证)
     */
    private String uuid;
    /**
     *状态
     */
    private int status;
    /**
     * 事迹
     */
    private String deed;


    public Person() {
    }
    
    public Person(String name, String uuid) {
        this.name = name;
        this.uuid = uuid;
    }


    public Person(String name, String sex, String uuid) {
        this.name = name;
        this.sex = sex;
        this.uuid = uuid;
    }


    public Person(String name, String sex, int age, String uuid) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.uuid = uuid;
    }


    public Person(String name, String sex, int age, String uuid, int status) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.uuid = uuid;
        this.status = status;
    }


    public Person(String name, String sex, int age, String uuid, int status, String deed) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.uuid = uuid;
        this.status = status;
        this.deed = deed;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public String getSex() {
        return sex;
    }


    public void setSex(String sex) {
        this.sex = sex;
    }


    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }


    public String getUuid() {
        return uuid;
    }


    public void setUuid(String uuid) {
        this.uuid = uuid;
    }


    public int getStatus() {
        return status;
    }


    public void setStatus(int status) {
        this.status = status;
    }


    public String getDeed() {
        return deed;
    }


    public void setDeed(String deed) {
        this.deed = deed;
    }


    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", uuid='" + uuid + '\'' +
                ", status=" + status +
                ", deed='" + deed + '\'' +
                '}';
    }
}

为了得到Person的实例,我们往往会传递大量的用不上的参数,上面的参数还算比较少,随着属性的增加,构造器繁多,不利于管理与阅读。


而且以上还只是Person的一点点属性,还有 生日、学历、地址...

总结:重叠构造器模式可行,但是到参数繁多时,客户端代码难以编写,并且难以阅读。


当然也可以使用无参构造器+get() set()方法。


遗憾的是JavaBeans模式自身有严重的确定啊。因为构造过程被分到几个调用中,会让JavaBeans可能处于不一致的状态,这就需要付出额外的努力来保证线程安全。


幸运的是还有第三种方法,既能保证像重叠构造器模式的安全性,也保证像JavaBeans模式的可读性。


例:


new AlertDialog.Builder(MainActivity.this)
        .setCancelable(false)
        .setTitle("详细信息")
        .setMessage(message)
        .setPositiveButton(getString(R.string.cancel), null)
        .create()
        .show();



简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder就是不错的设计模式。



package com.example.yancy.yancy;


/**
 * Created by yancy on 2017/8/24.
 */


public class Person {
    /**
     * 姓名
     */
    private final String name;
    /**
     * 性别
     */
    private final String sex;
    /**
     * 年龄
     */
    private final int age;
    /**
     * 唯一识别(身份证)
     */
    private final String uuid;
    /**
     * 状态
     */
    private final int status;
    /**
     * 事迹
     */
    private final String deed;




    public static class Builder {
        /**
         * 姓名
         */
        private String name = "";
        /**
         * 性别
         */
        private String sex = "";
        /**
         * 年龄
         */
        private int age = -1;
        /**
         * 唯一识别(身份证)
         */
        private String uuid = "";
        /**
         * 状态
         */
        private int status = -1;
        /**
         * 事迹
         */
        private String deed = "";


        public Builder() {
        }


        public Builder Name(String name) {
            this.name = name;
            return this;
        }


        public Builder Sex(String sex) {
            this.sex = sex;
            return this;
        }


        public Builder Age(int age) {
            this.age = age;
            return this;
        }


        public Builder Uuid(String uuid) {
            this.uuid = uuid;
            return this;
        }


        public Builder Status(int status) {
            this.status = status;
            return this;
        }


        public Builder Deed(String deed) {
            this.deed = deed;
            return this;
        }


        /**
         * 调用私有构造器
         * 这个方法必须调用
         *
         * @return
         */
        public Person builder() {
            return new Person(this);
        }
    }


    /**
     * 私有构造器
     *
     * @param builder
     */
    private Person(Builder builder) {
        name = builder.name;
        sex = builder.sex;
        age = builder.age;
        uuid = builder.uuid;
        status = builder.status;
        deed = builder.deed;
    }


    /**
     * 调用
     *
     * @param args
     */
    public static void main(String[] args) {
        //用哪个参数就调用哪个参数
        Person person = new Builder().Name("张三").Sex("M").Age(18).Uuid("08156565418115151").Status(0).Deed("").builder();
    }
}









































































































































































































































































































评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值