///////
Search
🧩

빌더

GoF 디자인 패턴(Design Pattern)이란?

소프트웨어를 설계할 때 자주 발생하는 문제들을 해결하기 위해 고안된 해결책
생성 패턴, 구조 패턴, 행위 패턴으로 구분

Builder Pattern

생성 패턴 중 하나로, 객체의 생성과 표현을 분리해 객체를 생성하는 패턴

언제 사용하나요 ?

변수가 많은 객체를 생성할 때
기존 객체 생성 방법 2가지
setter → 일관성, 불변성 문제
constructor → 변수가 너무 많으면 가독성 문제, 매개변수의 순서, 이름을 기억해야하므로 휴면 에러 유발

생성자 유무에 따른 빌더 작동 방식

생성자가 없는 경우 : 모든 멤버 변수를 파라미터로 받는 기본 생성자 생성
생성자가 있을 경우 : 따로 생성자를 생성하지 않음

실전

@Getter @Setter // 문제 1 @NoArgsConstructor // 문제 2 @AllArgsConstructor // 문제 3 @Builder // 고려해야할것 @Entity public class Posts
Java
복사

문제 @Setter 사용

Setter는 객체를 언제든지 변경할 수 있다. 그래서 객체의 안정성이 보장받기는 힘들다.
특히 엔티티에서는 어디서 누구에의해 객체가 변경되었는지 추적하는 것이 힘듦.
—> 값 변경이 필요할 때는 의미있는 메서드를 생성하여 사용하는 것이 좋다.

문제  @NoArgsConstructor

Entity 클래스 인스턴스 변수는 직접 접근이 아닌 내부 메소드로 접근해야한다.(Getter) 왜냐하면 JPA는 기본적으로 Entity에 접근하는것이 아니라 Entity proxy에 접근하게 되어있다. (프록시 ..?)
기본생성자의 접근제어는 활용하면 더 좋은 방향으로 사용할 수 있다. @NoArgsConstructor(access = AccessLevel.PROTECTED) —> 무분별하게 객체를 만들지 않는다 = 의미없는 객체를 만들지 않는다

문제  @AllArgsConstructor

우선 @Build를 사용하는 방법은 두 가지가 있다.
1.
클래스에 사용하는법
2.
생성자함수 위에서 사용하는법
문제1번처럼 @Build와 @NoArgsConstructor을 같이사용하면 당연히 오류가 발생합니다.(빌더를 알고, NoArgsConstructor을 이해하고 있다면 생각해볼만한 내용) 이를 해결하려면 @AllArgsConstructor을 같이 써주어야 합니다.
하지만 @AllArgsConstructor은 위험합니다
클래스에 존재하는 모든 필드변수를 포함한 생성자를 자동으로 생성하는데, 변수의 선언 순서(=위치)에 영향을 받게 된다. 만약 변수 선언 위치가 달라진다면 이것도 오류로 이어질 것이다.
그래서 2번의 방식을 추구해야한다.
이를 바탕으로 리팩토링 한다면
@Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Posts { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private String content; private String writer; private Integer viewCount; @Embedded private Period period; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; @Builder public Posts(Long id, String title, String content, String writer, Integer viewCount, Period period) { this.id = id; this.title = title; this.content = content; this.writer = writer; this.viewCount = viewCount; this.period = period; } }
Java
복사