Programming/Spring

JPA Entity의 @Setter를 지양하는 이유에 대해서 (feat. @Builder)

JeongKyun 2022. 9. 10.
반응형

서론

이번 포스팅에선 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) 어노테이션을 사용하여 객체의 일관성을 더 유지시키는 것이 좋다.)

 

댓글

💲 많이 본 글