当遇到多个构造器参数时,要考虑使用构建器(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