Todo 프로젝트에서 Entity 클래스의 프로퍼티들을 다음과 같이 설정하였다.
- 수정이 가능한 프로퍼티에 대해서는 var로 선언
- 수정이 될 일이 없는 프로퍼티들은 val로 선언
Todo Entity에서 title, content, writer, completed는 수정 요청 시 변경되는 값이다.
@Entity
@Table(name = "todo")
class Todo private constructor(
var title: String,
var content: String,
var writer: String,
// ...
) : BaseEntity() {
// ...
@Enumerated(EnumType.STRING)
var completed: TodoCompleted = TodoCompleted.FALSE
}
그리고 해당 Entity의 값을 Service에서 직접 Setter를 통해 값을 변경했었다.
@Transactional
override fun updateTodo(todoId: Long, request: UpdateTodoRequest): TodoResponse {
// ...
todo.title = request.title
todo.content = request.content
todo.writer = request.writer
}
직접 Setter를 통해 값을 변경하는 것이 문제가 되는 이유
- 변경사항이 생겼을 때 어느 부분에서 변경했는지 찾기 어려움
- 변경한 의도를 파악하기 어려움
Setter를 지양하기 위해 private set 설정을 하려고 했다.
그런데 Kotlin에서 Entity는 open 클래스이기 때문에 private를 사용할 수 없다.
대신 protected set으로 설정해 setter에 대한 접근을 차단할 수 있다.
protected: 상속받는 인터페이스, 클래스 또는 자식 클래스에서만 접근 가능
protected set을 설정하고 setter 대신 update 함수를 적용한 코드는 다음과 같다.
@Entity
@Table(name = "todo")
class Todo private constructor(
title: String,
content: String,
writer: String,
// ....
) : BaseEntity() {
// ..
var title: String = title
protected set
var content: String = content
protected set
var writer: String = writer
protected set
@Enumerated(EnumType.STRING)
var completed: TodoCompleted = TodoCompleted.FALSE
protected set
// ...
fun update(title: String?, content: String?, writer: String?, completed: TodoCompleted?) {
title?.let { this.title = it }
content?.let { this.content = it }
writer?.let { this.writer = it }
completed?.let { this.completed = it }
}
}
이제 Service에서는 Setter 사용할 수 없고 update 함수를 통해 Entity에서 값을 업데이트해야 한다.
@Transactional
override fun updateTodo(todoId: Long, userId: Long, request: UpdateTodoRequest): TodoResponse {
// ...
todo.update(
title = request.title,
content = request.content,
writer = request.writer,
completed = request.completed
)
return todo.toResponse()
}
처음에는 protected set 설정을 하지 않고 Setter를 사용하지 않으면 되지 않을까? 하는 생각도 했었지만 사람 마음이란 게 코드를 작성하다 보면 더 편한 방법을 찾게 되고 그러다가 "구현이 먼저다"라는 합리화를 통해 Setter를 사용하게 될 확률이 있기 때문에 이런 부분을 예방하고자 protected set 설정을 하는 것이 좋다고 생각한다.
'TIL(Today I Learned)' 카테고리의 다른 글
Docker 명령어 1 (0) | 2024.06.28 |
---|---|
Windows에서 Docker 설치 (0) | 2024.06.27 |
TIL - SecurityContextHolder에서 인증 객체 가져오기 (0) | 2024.06.17 |
TIL - Spring Boot에서 Filter 내 발생하는 Exception 처리 (0) | 2024.06.14 |
TIL - 비밀번호 수정 요청 시 기존 비밀번호를 사용하지 못하게 하기 (0) | 2024.06.13 |