생성 과정
과 표현 방법
을 분리해서 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 한다.@Data
@Builder(builderMethodName = "AlsoProblemBuilder")
public class AlsoProblem extends BaseTimeEntity {
private Long problemId;
private AlsoCounter alsoCounter;
private String title;
private String content;
private String category;
private int importanceCount;
private String email;
private String phone;
public static AlsoProblemBuilder builder(String title) {
if(title == null) {
throw new IllegalArgumentException("필수 파라미터 누락");
}
this.title = title;
}
public AlsoProblemDto toDto() {
return AlsoProblemDto.builder()
.title(title)
.content(content)
.category(category)
.importanceCount(importanceCount)
.email(email)
.phone(phone)
.counterId(alsoCounter.getCounterId()).build();
}
public void setAlsoCounter(AlsoCounter alsoCounter) { this.alsoCounter = alsoCounter ;}
}
Lombok
: 프로젝트 롬복은 표준판 코드를 최소화하거나 제거하는 데 사용되는 인기 있고 널리 사용되는 자바 라이브러리입니다. 개발 시간과 노력을 절약해주며, annotation(어노테이션, @)을 사용하여 소스 코드 가독성을 증가시켜줍니다.
build.gradle
dependencies { compileOnly 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24' testCompileOnly 'org.projectlombok:lombok:1.18.24' testAnnotationProcessor 'org.projectlombok:lombok:1.18.24' }
public final class Hero {
private final Profession profession;
private final String name;
private final HairType hairType;
private final HairColor hairColor;
private final Armor armor;
private final Weapon weapon;
private Hero(Builder builder) {
this.profession = builder.profession;
this.name = builder.name;
this.hairColor = builder.hairColor;
this.hairType = builder.hairType;
this.weapon = builder.weapon;
this.armor = builder.armor;
}
}
public static class Builder {
private final Profession profession;
private final String name;
private HairType hairType;
private HairColor hairColor;
private Armor armor;
private Weapon weapon;
public Builder(Profession profession, String name) {
if (profession == null || name == null) {
throw new IllegalArgumentException("profession and name can not be null");
}
this.profession = profession;
this.name = name;
}
public Builder withHairType(HairType hairType) {
this.hairType = hairType;
return this;
}
public Builder withHairColor(HairColor hairColor) {
this.hairColor = hairColor;
return this;
}
public Builder withArmor(Armor armor) {
this.armor = armor;
return this;
}
public Builder withWeapon(Weapon weapon) {
this.weapon = weapon;
return this;
}
public Hero build() {
return new Hero(this);
}
}
Hero mage = new Hero
.Builder(Profession.MAGE, "Riobard")
.withHairColor(HairColor.BLACK)
.withWeapon(Weapon.DAGGER)
.build();
Lombok 없이 사용하기엔 코드가 너무 길고 복잡해진다. 따라서 @Builder
를 사용하면 따로 빌더 클래스를 작성할 필요가 없다.
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(builderMethodName = "HeroBuilder")
@ToString
public class Hero {
private final Profession profession;
private final String name;
private final HairType hairType;
private final HairColor hairColor;
private final Armor armor;
private final Weapon weapon;
public static HeroBuilder builder(String name) {
if(name == null) {
throw new IllegalArgumentException("필수 파라미터 누락");
}
this.name = name;
}
}
Hero hero = Hero.builder("아이언맨")
.profession(Profession.MAGE, "Riobard")
.hairType("Paris flight ticket")
.hairColor(HairColor.BLACK)
.armor("1235-5345")
.weapon(Weapon.DAGGER)
.build();
https://erjuer.tistory.com/106
https://velog.io/@park2348190/Lombok-Builder의-동작-원리
If a class is annotated, then a private constructor is generated with all fields as arguments (as if @AllArgsConstructor(access = AccessLevel.PRIVATE) is present on the class), and it is as if this constructor has been annotated with @Builder instead.
필드의 모든 값에 대한 빌드 메서드가 적용된다.
단, final의 경우 초기화 되지 않은 경우만! 이미 초기화가 됐다면 build 패턴으로 재선언할 수 없다.
Note that this constructor is only generated if you haven't written any constructors and also haven't added any explicit @XArgsConstructor annotations. In those cases, lombok will assume an all-args constructor is present and generate code that uses it; this means you'd get a compiler error if this constructor is not present.
그니까 생성자를 @Builder 어노테이션을 사용했을 땐 임의로 명시하지 말아라. 라는 뜻.
컴파일 과정에서 에러가 난다.
The effect of @Builder is that an inner class is generated named TBuilder, with a private constructor. Instances of TBuilder are made with the method named builder() which is also generated for you in the class itself (not in the builder class).
The TBuilder class contains 1 method for each parameter of the annotated constructor / method (each field, when annotating a class), which returns the builder itself.
즉, 생성자 레벨에서는 내부 클래스를 private 생성자로 만들어 builder를 구현하고 생성자의 파라미터에 해당하는 내용만 메서드로 만들어준다.
해당 객체가 부모 객체를 상속받는 상태일 때, 부모 객체의 필드 값 또한 builder 패턴으로 작성하고 싶을 때 @Builder
대신 사용한다.