当遇到多个构造器参数时,要考虑使用构建器(Builder模式)

举个例子,Person类,假设该类有7个属性,其中有2个是必要的参数需要初始化,分别是id和name。

public class Person {
    //必要参数
    private int id;
    private String name;
    //可选参数
    private int age;
    private String sex;
    private String phone;
    private String address;
    private String desc;

  // set/get方法忽略
}

一、不使用建造者模式

Person person = new Person();
person.setId(1);
person.setName("张小毛");
person.setAge(22);
person.setSex("男");
person.setPhone("19999999999");
person.setAddress("beijing");
person.setDesc("JavaBeans模式");

缺点:

a.成员变量不可以是 final 类型,失去了不可变对象的很多好处;

b.对象状态不连续,必须调用7次setter方法才能得到一个具备7个属性值得变量,在这期间用户可能拿到不完整状态的对象。

对象状态不连续:先创建对象、后赋值,用户拿到的对象可能是不完整的(很有可能你只setter了一两个属性就返回了,一些必要的属性没有被赋值)

二、使用建造者模式

public class Person {
    //必要参数
    private final int id;
    private final String name;
    //可选参数
    private int age;
    private String sex;
    private String phone;
    private String address;
    private String desc;

    private Person(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
        this.phone = builder.phone;
        this.address = builder.address;
        this.desc = builder.desc;
    }

    public static class Builder {
        //必要参数
        private final int id;
        private final String name;
        //可选参数
        private int age;
        private String sex;
        private String phone;
        private String address;
        private String desc;

        public Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }

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

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

        public Builder phone(String val) {
            this.phone = val;
            return this;
        }

        public Builder address(String val) {
            this.address = val;
            return this;
        }

        public Builder desc(String val) {
            this.desc = val;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}

观察得知:

a.在要构建类的内部,创建一个静态内部类Builder

b.静态内部类的属性要与构建类的属性一致;

c.构建类的构造参数是静态内部类,使用静态内部类的变量为构建类逐一赋值;

d.静态内部类提供参数的setter方法,并且返回值是当前Builder对象;

e.最终提供一个build方法new出来一个构建类的对象,参数是当前Builder对象;

使用:

Person person = new Person.Builder(1, "张小毛")
        .age(22).sex("男").desc("使用builder模式").build();

Builer模式使用方法的总结:

a.外部类的构造函数私有,且参数为静态内部类;

b.静态内部类拥有外部类相同的属性;

c.为每一个属性,写一个方法,返回的是Builer

d.最后一个方法是build方法,用于构建一个外部类;

优点:

a.减少对象创建过程中引入的多个构造函数、可选参数以及多个setter过度使用导致的不必要的复杂性。

b.看起来很整齐;先赋值,后创建对象,最终调用build()方法才创建了构建类的对象,保证了状态的完整性。

 

 

博客借鉴:https://blog.csdn.net/zxd1435513775/article/details/83016670

posted on 2021-09-12 15:35  smile学子  阅读(27)  评论(0编辑  收藏  举报