[设计模式/Java] 设计模式之建造者模式【10】
1 概述:建造者模式
模式定义
-
建造者模式是一种创建型设计模式,它允许你创建复杂对象的【步骤】与【表示方式】相分离。
-
主要目的: 将一个复杂对象的【构建过程】与其【表示】相分离,从而可以创建具有不同表示形式的对象。
模式的组成
建造者模式包含以下几个主要角色:
- 产品(Product):要构建的复杂对象。产品类通常包含多个部分或属性。
- 抽象建造者(Builder):定义了构建产品的抽象接口,包括构建产品的各个部分的方法。
- 具体建造者(Concrete Builder):实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
- 指导者(Director):负责调用建造者的方法来构建产品,指导者并不需要了解具体的构建过程,只需关心产品的构建顺序和方式。
模式特点
优点
- 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
- 可以更好地控制构建过程,隐藏具体构建细节。
- 如:构建过程中,校验部分字段的值内容
-
代码复用性高,可以在不同的构建过程中重复使用相同的建造者。
-
减少客户端创建复杂对象的代码量
缺点
- 如果产品的属性较少,建造者模式可能会导致代码冗余。
- 增加了系统的类和对象数量。
适用场景
-
主要解决:在软件系统中,一个复杂对象的创建通常由多个部分组成,这些部分的组合经常变化,但组合的算法相对稳定。
-
何时使用:
- 当一些基本部件不变,而其组合经常变化时。
- 需要生成的对象具有复杂的内部结构。
- 需要生成的对象内部属性相互依赖。
- 如何解决?
- 将变与不变的部分分离开。
案例实践
案例:快餐厅的套餐
案例描述
-
去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出不同的"套餐"。
-
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。
- 汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。
- 冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
-
我们将创建一个表示食物条目(比如汉堡和冷饮)的
Item接口和实现Item接口的实体类;
以及一个表示食物包装的Packing接口和实现Packing接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。 -
然后,我们创建一个
Meal类,带有Item的ArrayList和一个通过结合Item来创建不同类型的Meal对象的MealBuilder。BuilderPatternDemo类使用MealBuilder来创建一个Meal。

Iteam / Packing : 创建一个表示食物条目和食物包装的接口
- Item
public interface Item {
public String name();
public Packing packing();
public float price();
}
- Packing
public interface Packing {
public String pack();
}
Wrapper : 创建实现 Packing 接口的实体类
- Wrapper
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
- Bottle
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
Burger / ColdDrink : 创建实现 Item 接口的抽象类,该类提供了默认的功能
- Burger
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
- ColdDrink
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
VegBurger / ChickenBurger / Coke / Pepsi : 创建扩展了 Burger 和 ColdDrink 的实体类
- VegBurger
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
- ChickenBurger
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
- Coke
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
- Pepsi
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
Meal : 创建一个 Meal 类,带有上面定义的 Item 对象
- Meal : 英译
- n. 一餐;早(或午、晚)餐;一餐所吃的食物;谷物粗粉(用作饲料或加工面粉)
- v. 吃饭;碾碎
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
MealBuilder : 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象
public class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
BuilderPatternDemo : BuiderPatternDemo 使用 MealBuilder 来演示建造者模式
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
out
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0
Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5
案例:Java StringBuilder
Java中的StringBuilder。
案例:Lombok 对 Java 实体Bean 的@Builder注解
基本使用
@Builder注释为你的类生成相对略微复杂的构建器API。@Builder可以让你以下面显示的那样调用你的代码,来初始化你的实例对象:
Student.builder()
.no( "001" )
.name( "admin" )
.birthday( 18 )
.phone( "110" )
.build();
@Builder可以放在类、构造函数或方法上。
虽然放在类上和放在构造函数上这两种模式是最常见的用例,但
@Builder最容易用放在方法的用例来解释。
原理
- 那么
@Builder内部帮我们做了什么?
- 创建一个名为
ThisClassBuilder的内部静态类,并具有和实体类形同的属性(称为构建器)。- 在构建器中:对于目标类中的所有的属性和未初始化的
final字段,都会在构建器中创建对应属性。- 在构建器中:创建一个无参的
default构造函数。- 在构建器中:对于实体类中的每个参数,都会对应创建类似于setter的方法,只不过方法名与该属性名相同。 且返回值是构建器本身(便于链式调用),如上例所示。
- 在构建器中:一个
build()方法,调用此方法,就会根据设置的值进行创建实体对象。- 在构建器中:同时也会生成一个
toString()方法。- 在实体类中:会创建一个
builder()方法,它的目的是用来创建构建器。
- 例如:
@Builder
public class User {
private final Integer code = 200;
private String username;
private String password;
}
编译后:
// 编译后:
public class User {
private String username;
private String password;
User(String username, String password) {
this.username = username; this.password = password;
}
public static User.UserBuilder builder() {
return new User.UserBuilder();
}
public static class UserBuilder {
private String username;
private String password;
UserBuilder() {}
public User.UserBuilder username(String username) {
this.username = username;
return this;
}
public User.UserBuilder password(String password) {
this.password = password;
return this;
}
public User build() {
return new User(this.username, this.password);
}
public String toString() {
return "User.UserBuilder(username=" + this.username + ", password=" + this.password + ")";
}
}
}
@Builder中配合使用 @Singular 注解,作用于【集合属性】
@Singular
@Builder也可以为集合类型的参数或字段生成一种特殊的方法。
它采用修改列表中一个元素而不是整个列表的方式,可以是增加一个元素,也可以是删除一个元素。
Student.builder()
.sno( "001" )
.sname( "admin" )
.sage( 18 )
.sphone( "110" ).sphone( "112" )
.build();
- 这样就可以轻松地将
List <String>字段中包含2个字符串。
但是想要这样来操作集合,你需要使用
@Singular来注释字段或参数。
- 在使用
@Singular注释注释一个集合字段(使用@Builder注释类),lombok会将该构建器节点视为一个集合,并生成两个adder方法而不是setter方法。
- 一个向集合添加单个元素
- 一个将另一个集合的所有元素添加到集合中
- 将不生成仅设置集合(替换已添加的任何内容)的
setter。 还生成了clear方法。
这些
singular构建器相对而言是有些复杂的,主要是来保证以下特性:
- 在调用
build()时,生成的集合将是不可变的。- 在调用
build()之后调用其中一个adder方法或clear方法不会修改任何已经生成的对象。如果对集合修改之后,再调用build(),则会创建一个基于上一个对象创建的对象实体。- 生成的集合将被压缩到最小的可行格式,同时保持高效。
@Singular只能应用于lombok已知的集合类型。目前,支持的类型有:
- java.util:
- Iterable, Collection, 和List (一般情况下,由压缩的不可修改的ArrayList支持).
- Set, SortedSet, and NavigableSet (一般情况下,生成可变大小不可修改的HashSet或者TreeSet).
- Map, SortedMap, and NavigableMap (一般情况下,生成可变大小不可修改的HashMap或者TreeMap).
- Guava’s com.google.common.collect:
- ImmutableCollection and ImmutableList
- ImmutableSet and ImmutableSortedSet
- ImmutableMap, ImmutableBiMap, and ImmutableSortedMap
- ImmutableTable
来看看使用了
@Singular注解之后的编译情况:
@Builder
public class User {
private final Integer id;
private final String zipCode = "123456";
private String username;
private String password;
@Singular
private List<String> hobbies;
}
编译后:
public class User {
private final Integer id;
private final String zipCode = "123456";
private String username;
private String password;
private List<String> hobbies;
User(Integer id, String username, String password, List<String> hobbies) {
this.id = id; this.username = username;
this.password = password; this.hobbies = hobbies;
}
public static User.UserBuilder builder() {
return new User.UserBuilder();
}
public static class UserBuilder {
private Integer id;
private String username;
private String password;
private ArrayList<String> hobbies;
UserBuilder() {
}
public User.UserBuilder id(Integer id) { this.id = id; return this; }
public User.UserBuilder username(String username) { this.username = username; return this; }
public User.UserBuilder password(String password) { this.password = password; return this; }
public User.UserBuilder hobby(String hobby) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.add(hobby);
return this;
}
public User.UserBuilder hobbies(Collection<? extends String> hobbies) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.addAll(hobbies);
return this;
}
public User.UserBuilder clearHobbies() {
if (this.hobbies != null) {
this.hobbies.clear();
}
return this;
}
public User build() {
List hobbies;
switch(this.hobbies == null ? 0 : this.hobbies.size()) {
case 0:
hobbies = Collections.emptyList();
break;
case 1:
hobbies = Collections.singletonList(this.hobbies.get(0));
break;
default:
hobbies = Collections.unmodifiableList(new ArrayList(this.hobbies));
}
return new User(this.id, this.username, this.password, hobbies);
}
public String toString() {
return "User.UserBuilder(id=" + this.id + ", username=" + this.username + ", password=" + this.password + ", hobbies=" + this.hobbies + ")";
}
}
}
- 其实,
lombok的创作者还是很用心的,在进行build()来创建实例对象时,并没有直接使用Collections.unmodifiableList(Collection)此方法来创建实例,而是分为三种情况:
- 第1种,当集合中没有元素时,创建一个空list
- 第2种,当集合中存在一个元素时,创建一个不可变的单元素list
- 第3种,根据当前集合的元素数量创建对应合适大小的list
当然我们看编译生成的代码,创建了三个关于集合操作的方法:
hobby(String hobby):向集合中添加一个元素
hobbies(Collection<? extends String> hobbies):添加一个集合所有的元素
clearHobbies():清空当前集合数据
@Singular 注解配置value属性
- 先来看看
@Singular注解的详情:
@Target({FIELD, PARAMETER})
@Retention(SOURCE)
public @interface Singular {
// 修改添加集合元素的方法名
String value() default "";
}
- 测试如何使用注解属性value
@Builder
public class User {
private final Integer id;
private final String zipCode = "123456";
private String username;
private String password;
@Singular(value = "testHobbies")
private List<String> hobbies;
}
// 测试类
public class BuilderTest {
public static void main(String[] args) {
User user = User.builder()
.testHobbies("reading")
.testHobbies("eat")
.id(1)
.password("admin")
.username("admin")
.build();
System.out.println(user);
}
}
说明,当我们使用了注解属性value之后,我们在使用添加集合元素时的方法名发生相应的改变。
但是,同时生成的添加整个集合的方法名发生改变了吗?我们再来看看编译后的代码:
// 编译后:
public class User {
// 省略部分代码,只看关键部分
public static class UserBuilder {
public User.UserBuilder testHobbies(String testHobbies) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.add(testHobbies);
return this;
}
public User.UserBuilder hobbies(Collection<? extends String> hobbies) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.addAll(hobbies);
return this;
}
public User.UserBuilder clearHobbies() {
if (this.hobbies != null) {
this.hobbies.clear();
}
return this;
}
}
}
可以看到,只有添加一个元素的方法名发生了改变。
lombok中的@Builder.Default注解
lombok中的@Builder.Default注解为成员变量赋默认值
(1)只对成员变量设置默认值,builder构造默认值是无效的
User
import com.alibaba.fastjson2.JSON;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.UUID;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class User {
private String id = UUID.randomUUID().toString();;
private final String zipCode = "123456";
private String username;
private String password;
@Singular
private List<String> hobbies;
}
如果我们用,java的
new操作创建对象,是会对 User 设置默认值的
public static void main(String[] args) {
User user = new User();
User user2 = new User();
log.info("user:{}", JSON.toJSONString( user ));
log.info("user2:{}", JSON.toJSONString( user2 ));
}
out
user:{"id":"c470357e-72e0-4780-b500-22ab1bb115ee","zipCode":"123456"}
user2:{"id":"2879436b-7884-4d57-83c9-17aa52bd0a4e","zipCode":"123456"}
但是
Builder方式创建对象,是无效的
public static void main(String[] args) {
User userByBuilder = User.builder().build();
User userByBuilder2 = User.builder().build();
log.info("userByBuilder:{}", JSON.toJSONString( userByBuilder ));
log.info("userByBuilder2:{}", JSON.toJSONString( userByBuilder2 ));
}
out
user:{"hobbies":[],"zipCode":"123456"}
user2:{"hobbies":[],"zipCode":"123456"}
原因在于,编译生成的
User.class文件,保留了成员变量的初始值,但是在UserBuilder中,只有成员变量,而没有默认值
//编译后:
import com.alibaba.fastjson2.JSON;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class User {
private static final Logger log = LoggerFactory.getLogger(User.class);
private String id = UUID.randomUUID().toString();
private final String zipCode = "123456";
private String username;
private String password;
private List<String> hobbies;
public static UserBuilder builder() {
return new UserBuilder();
}
public String getId() {
return this.id;
}
public String getZipCode() {
Objects.requireNonNull(this);
return "123456";
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public List<String> getHobbies() {
return this.hobbies;
}
public void setId(String id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User)) {
return false;
} else {
User other = (User)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$zipCode = this.getZipCode();
Object other$zipCode = other.getZipCode();
if (this$zipCode == null) {
if (other$zipCode != null) {
return false;
}
} else if (!this$zipCode.equals(other$zipCode)) {
return false;
}
Object this$username = this.getUsername();
Object other$username = other.getUsername();
if (this$username == null) {
if (other$username != null) {
return false;
}
} else if (!this$username.equals(other$username)) {
return false;
}
Object this$password = this.getPassword();
Object other$password = other.getPassword();
if (this$password == null) {
if (other$password != null) {
return false;
}
} else if (!this$password.equals(other$password)) {
return false;
}
Object this$hobbies = this.getHobbies();
Object other$hobbies = other.getHobbies();
if (this$hobbies == null) {
if (other$hobbies != null) {
return false;
}
} else if (!this$hobbies.equals(other$hobbies)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof User;
}
public int hashCode() {
int PRIME = 59;
int result = 1;
Object $id = this.getId();
result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $zipCode = this.getZipCode();
result = result * 59 + ($zipCode == null ? 43 : $zipCode.hashCode());
Object $username = this.getUsername();
result = result * 59 + ($username == null ? 43 : $username.hashCode());
Object $password = this.getPassword();
result = result * 59 + ($password == null ? 43 : $password.hashCode());
Object $hobbies = this.getHobbies();
result = result * 59 + ($hobbies == null ? 43 : $hobbies.hashCode());
return result;
}
public String toString() {
String var10000 = this.getId();
return "User(id=" + var10000 + ", zipCode=" + this.getZipCode() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ", hobbies=" + this.getHobbies() + ")";
}
public User() {
}
public User(String id, String username, String password, List<String> hobbies) {
this.id = id;
this.username = username;
this.password = password;
this.hobbies = hobbies;
}
public static class UserBuilder {
private String id;
private String username;
private String password;
private ArrayList<String> hobbies;
UserBuilder() {
}
public UserBuilder id(String id) {
this.id = id;
return this;
}
public UserBuilder username(String username) {
this.username = username;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public UserBuilder hobby(String hobby) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.add(hobby);
return this;
}
public UserBuilder hobbies(Collection<? extends String> hobbies) {
if (hobbies == null) {
throw new NullPointerException("hobbies cannot be null");
} else {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.addAll(hobbies);
return this;
}
}
public UserBuilder clearHobbies() {
if (this.hobbies != null) {
this.hobbies.clear();
}
return this;
}
public User build() {
List<String> hobbies;
switch (this.hobbies == null ? 0 : this.hobbies.size()) {
case 0 -> hobbies = Collections.emptyList();
case 1 -> hobbies = Collections.singletonList((String)this.hobbies.get(0));
default -> hobbies = Collections.unmodifiableList(new ArrayList(this.hobbies));
}
return new User(this.id, this.username, this.password, hobbies);
}
public String toString() {
return "User.UserBuilder(id=" + this.id + ", username=" + this.username + ", password=" + this.password + ", hobbies=" + this.hobbies + ")";
}
}
}
(2)设置@Builder.Default注解后,通过标识判断是否启用默认值
User
import com.alibaba.fastjson2.JSON;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.UUID;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class User {
@Builder.Default
private String id = UUID.randomUUID().toString();;
private final String zipCode = "123456";
private String username;
private String password;
@Singular
private List<String> hobbies;
}
测试
public static void main(String[] args) {
User user = new User();
User user2 = new User();
log.info("user:{}", JSON.toJSONString( user ));
log.info("user2:{}", JSON.toJSONString( user2 ));
User userByBuilder = User.builder().build();
User userByBuilder2 = User.builder().build();
log.info("userByBuilder:{}", JSON.toJSONString( userByBuilder ));
log.info("userByBuilder2:{}", JSON.toJSONString( userByBuilder2 ));
}
运行结果:
user:{"id":"4e54f5e9-d131-4fe7-a139-80a4b7a24f7c","zipCode":"123456"}
user2:{"id":"a674bbd5-79af-48e7-8576-d96df5b82c01","zipCode":"123456"}
userByBuilder:{"hobbies":[],"id":"b121eded-b369-407a-bc21-6ab994550a05","zipCode":"123456"}
userByBuilder2:{"hobbies":[],"id":"b26b3314-d778-40ef-866d-dd7f181e0025","zipCode":"123456"}
User 编译后:
import com.alibaba.fastjson2.JSON;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class User {
private static final Logger log = LoggerFactory.getLogger(User.class);
private String id;
private final String zipCode = "123456";
private String username;
private String password;
private List<String> hobbies;
private static String $default$id() {
return UUID.randomUUID().toString();
}
public static UserBuilder builder() {
return new UserBuilder();
}
public String getId() {
return this.id;
}
public String getZipCode() {
Objects.requireNonNull(this);
return "123456";
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public List<String> getHobbies() {
return this.hobbies;
}
public void setId(String id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User)) {
return false;
} else {
User other = (User)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$zipCode = this.getZipCode();
Object other$zipCode = other.getZipCode();
if (this$zipCode == null) {
if (other$zipCode != null) {
return false;
}
} else if (!this$zipCode.equals(other$zipCode)) {
return false;
}
Object this$username = this.getUsername();
Object other$username = other.getUsername();
if (this$username == null) {
if (other$username != null) {
return false;
}
} else if (!this$username.equals(other$username)) {
return false;
}
Object this$password = this.getPassword();
Object other$password = other.getPassword();
if (this$password == null) {
if (other$password != null) {
return false;
}
} else if (!this$password.equals(other$password)) {
return false;
}
Object this$hobbies = this.getHobbies();
Object other$hobbies = other.getHobbies();
if (this$hobbies == null) {
if (other$hobbies != null) {
return false;
}
} else if (!this$hobbies.equals(other$hobbies)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof User;
}
public int hashCode() {
int PRIME = 59;
int result = 1;
Object $id = this.getId();
result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $zipCode = this.getZipCode();
result = result * 59 + ($zipCode == null ? 43 : $zipCode.hashCode());
Object $username = this.getUsername();
result = result * 59 + ($username == null ? 43 : $username.hashCode());
Object $password = this.getPassword();
result = result * 59 + ($password == null ? 43 : $password.hashCode());
Object $hobbies = this.getHobbies();
result = result * 59 + ($hobbies == null ? 43 : $hobbies.hashCode());
return result;
}
public String toString() {
String var10000 = this.getId();
return "User(id=" + var10000 + ", zipCode=" + this.getZipCode() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ", hobbies=" + this.getHobbies() + ")";
}
public User() {
this.id = $default$id();
}
public User(String id, String username, String password, List<String> hobbies) {
this.id = id;
this.username = username;
this.password = password;
this.hobbies = hobbies;
}
public static class UserBuilder {
private boolean id$set;
private String id$value;
private String username;
private String password;
private ArrayList<String> hobbies;
UserBuilder() {
}
public UserBuilder id(String id) {
this.id$value = id;
this.id$set = true;
return this;
}
public UserBuilder username(String username) {
this.username = username;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public UserBuilder hobby(String hobby) {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.add(hobby);
return this;
}
public UserBuilder hobbies(Collection<? extends String> hobbies) {
if (hobbies == null) {
throw new NullPointerException("hobbies cannot be null");
} else {
if (this.hobbies == null) {
this.hobbies = new ArrayList();
}
this.hobbies.addAll(hobbies);
return this;
}
}
public UserBuilder clearHobbies() {
if (this.hobbies != null) {
this.hobbies.clear();
}
return this;
}
public User build() {
List<String> hobbies;
switch (this.hobbies == null ? 0 : this.hobbies.size()) {
case 0 -> hobbies = Collections.emptyList();
case 1 -> hobbies = Collections.singletonList((String)this.hobbies.get(0));
default -> hobbies = Collections.unmodifiableList(new ArrayList(this.hobbies));
}
String id$value = this.id$value;
if (!this.id$set) {
id$value = User.$default$id();
}
return new User(id$value, this.username, this.password, hobbies);
}
public String toString() {
return "User.UserBuilder(id$value=" + this.id$value + ", username=" + this.username + ", password=" + this.password + ", hobbies=" + this.hobbies + ")";
}
}
}
@Builder 全局配置
# 是否禁止使用@Builder
lombok.builder.flagUsage = [warning | error] (default: not set)
# 是否使用Guaua
lombok.singular.useGuava = [true | false] (default: false)
# 是否自动使用singular,默认是使用
lombok.singular.auto = [true | false] (default: true)
参考文献
Y FAQ for 建造者模式
Q: 与工厂模式的区别?
- 与工厂模式的区别是:建造者模式更加关注于零件装配的顺序。
Y 推荐文献
X 参考文献
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号