问题引入
例如Person类有以下属性:
/** * @author 爱飘de小子 * @date 2018年11月24日 下午2:28:23 * @version 1.0 */@Datapublic class Person { //必要属性 private String id; private String name; //非必要属性 private String address; private String gender; private Integer age; public Person() { } public Person(String id, String name, String address, String gender, Integer age) { this.id = id; this.name = name; this.address = address; this.gender = gender; this.age = age; } }复制代码
注: get和set方法采用lombok插件的注解@Data生成(其中无参构造器可以用@NoArgsConstructor注解,有参构造器可以通过@AllArgsConstructor注解生成)
当客户端要创建一个Person实例时,传统的方式会这样创建:
//方式一 Person person = new Person(); person.setId("1"); person.setName("爱飘de小子"); person.setAge(24); person.setGender("男"); //方式二 Person person2 = new Person("1", "爱飘de小子", null, "男", 24);复制代码
方式一 通过javabeans模式,提供的get和set方法创建实例,创建实例很容易,不足的是代码不够简洁。
方式二 通过构造器创建实例,如果对象的属性较少,这种方式的最优的,如果属性过多,这种方式并对客户端来讲并不友好。
如果使用构造器重载,参数多的情况下,需要重载的构造器个数将会以指数形式增长。
##builder模式 builder模式也叫作重叠构造器模式,改造Person对象如下:
import lombok.Data; /** * @author 爱飘de小子 * @date 2018年11月24日 下午2:28:23 * @version 1.0 */@Datapublic class Person { //必要属性 private String id; private String name; //非必要属性 private String address; private String gender; private Integer age; private Person(Builder builder) { this.id = builder.id; this.name = builder.name; this.address = builder.address; this.gender = builder.gender; this.age = builder.age; } @Data public static class Builder { private String id; private String name; private String address; private String gender; private Integer age; //必要属性 public Builder(String id,String name) { this.id = id; this.name = name; } public Builder setAddress(String address) { this.address = address; return this; } public Builder setGender(String gender) { this.gender = gender; return this; } public Builder setAge(Integer age) { this.age = age; return this; } } }复制代码
注:内部类Builder的setXXX方法每次都返回builder本身,这样保证了Builder模式传参的灵活性。
客户端使用:
Person person = new Person. Builder("1","爱飘de小子") .setAddress("成都") .setAge(24) .setGender("男") .build(); Person person1 = new Person .Builder("2","轮回") .setAge(21) .build();复制代码
使用Builder模式相对于构造器的好处是传参灵活,客户端代码简洁,客户端的使用非常方便与易读。
缺点: 1.每次创建Person对象都会创建Builder对象。 2.服务端代码陈余。