서론
이번 포스팅에선 JPA의 Entity를 사용할 때 @Setter를 지양해야하는 이유에 대해 알아보려합니다. 물론 @Setter의 사용이 100% 잘못되었다는 것이 아닙니다. 양방향 바인딩 시 Setter 사용이 더 용이할 수 있으나 이번 포스팅에선 일반적인 케이스만 다뤄보도록 하겠습니다.
@Setter를 지양해야하는 이유
@Setter는 사용 의도/목적이 분명치 않다. (Update인지 Create인지)
Entity를 만들 때는 외부에서 쉽게 변경할 수 없게 @Setter를 사용하지않는다. 그 이유는 @Setter를 사용하면 의도가 불명확하고 변경하면 안되는 중요한 값임에도 불구하고 변경 가능한 값으로 착각할 수 있다. (== 안정성 보장이 안된다.)
그러면 만약 값을 업데이트 시켜줘야하는 상황일 때, Setter를 사용하지않고 어떻게 하면 될까? 방법은 간단하다. 아래의 예시를 보자.
Setter [O]
private int age;
public void setAge(int age) {
this.age = age;
}
Setter [X]
private int age;
public void updateAgeInfo(int age) {
this.age = age;
}
위의 예시를 보면, 나이를 setAge 하는부분에 대해서 보다 개발자의 의미가 들어가있는 updateAgeInfo의 이름으로 수정한 것을 확인할 수 있다. 위와 같이 작성을 해주면 메서드의 이름만을 보고도 변경 의도를 한눈에 확인할 수 있다는 장점이 있다.
무분별한 변경으로 객체의 일관성을 보장하기 어렵다. [@Builder 패턴 적용 권장]
위 내용은 빌더 패턴의 장점과 연관되어있기에 해당 장점을 알아보면서 빌더 패턴을 사용하면 왜 좋은지, 어떻게 개선이 되는지 이해해보자.
Builder 패턴 사용 시 장점
- 가독성을 높일 수 있다.
- 필요한 데이터만 bulid할 수 있다.
가독성을 높일 수 있다.
빌더 패턴을 사용하면 매개 변수가 많아져도 가독성을 높일 수 있다는 장점이 있다. 아래의 예시를 보자.
Builder 패턴 적용 전
Board board =
new Board("안녕하세요 과거일지입니다.", "안정균", "관리자")
Builder 패턴 적용 후
Board board =
Board
.builder()
.title("안녕하세요 과거일지입니다.")
.writer("안정균")
.role("관리자")
.build();
사용 전을 먼저 보면, 파라미터에 작성되어있는 값이 어떤 의미를 가진 변수인지 확인이 어렵지만, Builder 패턴을 사용하면 변수명을 보고 어떤 데이터인지 확인하기 쉬워진다. 따라서, 가독성이 높아지는 것을 확인할 수 있다.
필요한 데이터만 build할 수 있다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private boardSeq
private String title;
private String writer;
private String role;
@Builder
public Board(String title, String writer, String role) {
this.title = title;
this.writer = writer;
this.role = role;
}
위의 예시와 같이 Auto Increament가 적용되어있어 boardSeq는 알아서 증가가되는 형태이기 때문에, 따로 값을 넣을 필요가 없기때문에 생성자에서 필요한 데이터만 @Builder를 사용하여 빌더 패턴을 적용할 수 있다.
정리
빌더 패턴을 적용하면, 객체의 일관성을 유지하기 위해 객체 생성 시점에 값들을 넣어줌으로써, Setter의 사용을 줄일 수 있게 된다.그리고, 기본 생성자 접근자를 protected로 변경하면 new Board() 사용을 막을 수 있어 객체의 일관성을 더욱 유지할 수 있게된다.
(JPA 기본 스펙 상 기본 생성자를 요구하는데, protected로 제어하는 것은 허용해주기 때문에 @NoArgsConstructor(access = AccessLevel.PROTECTED) 어노테이션을 사용하여 객체의 일관성을 더 유지시키는 것이 좋다.)
'Programming > Spring' 카테고리의 다른 글
[Spring] 스프링 빈 생명 주기에 대해서 (Spring Bean Life Cycle) (0) | 2022.08.08 |
---|---|
원활한 MSA를 위한 Spring Cloud란? (개념/ 종류/ Config Server/ Gateway) (0) | 2022.06.16 |
[Spring Boot] JPA Entity 현재시간(current_timestamp) 적용 방법(@CreationTimestamp/ @UpdateTimestamp) (1) | 2022.06.09 |
[Spring Boot] Jackson을 이용하여 Response값 Filtering 방법 (개념/ 예제) (2) | 2022.06.07 |
[Spring] 의존성 주입(Dependency Injection)이란? (개념/ 예제/ 총 정리) (2) | 2022.05.31 |
댓글