최근에 에러 처리를 위한 sealed class에 대해 공부하다가 data object를 마주쳤습니다
data면 data class고, object면 그냥 object지
data object는 도대체 뭐람 ? 🤔
그래서 이번 블로그는 data object에 대해 탐구했던 과정들을 기록해 보고자 합니다 ✏️
아래는 오목 미션을 진행하면서 만든 sealed class입니다
sealed class ValidationResult {
object Success : ValidationResult()
sealed class Failure() : ValidationResult() {
object DoubleThree : Failure()
object DoubleFour : Failure()
object OverLine : Failure()
object Occupied : Failure()
}
}
오목 위치를 받아서 검증을 진행하고, 둘 수 있는 위치면 ValidationResult.Success를, 둘 수 없는 위치라면 그 이유를 반환합니다
해당 코드를 Intellij에서 작성하면 IDE가 문구를 하나 띄워 주는데요 🤔

'sealed' sub-object can be converted to 'data object'
즉, sealed class의 하위 object는 data object로 바꾸라고 제안해 주고 있습니다
왜 바꿔 주어야 하지? 무슨 이점이 있지? 싶어서 찾아 보니,
data object와 object의 가장 큰 차이점은 toString() 메서드 오버라이딩에 있더군요 🙃

data 키워드를 붙이고 object를 출력할 땐 object의 이름만 보이는 걸 알 수 있습니다
반면에 그냥 object를 출력할 땐 패키지 구조와 메모리 주소값도 같이 출력됩니다
object의 경우, 싱글톤으로 선언되며 단 하나의 인스턴스만 존재합니다
따라서 어디에서 사용하든 같은 주솟값에 있는 객체를 참조하게 될 텐데요 !
우리는 object가 메모리의 어떤 위치에 저장되어 있는지 알 필요가 없죠 😎
또한, sealed class 내에 있는 상태들이 어떤 패키지에 구현되어 있는지도 관심사가 아닐 겁니다 🤔
data object는 이런 불필요한 정보들을 toString() 메서드를 오버라이딩 하여 가려줍니다
data class가 toString(), copy(), hashCode(), equals() 메서드를 자동 생성&오버라이드 해 주듯,
data object에서도 해당 메서드들이 자동으로 오버라이드 된다고 합니다
저는 여기서 한 가지 의문이 들었는데요 🤔
object를 어떻게 copy 할 수 있을까요 ... ?
위에서 object는 싱글톤으로 선언되며 단 하나의 인스턴스만 존재한다고 했는데,
data 키워드가 붙어서 copy 메서드를 지원해 준다면?
여러개의 인스턴스를 만들 수 있을까요? 😵💫

object Hwannow
data object Hwannow2
실험을 위해 object 객체를 선언해 주었습니다
object 객체에는 copy 메서드를 지원하지 않아서 빨갛게 오류가 뜨는데요 🤔
data object에는 별 다른 오류가 보이지 않는 모습을 볼 수 있습니다
실행하면 어떻게 될까요?

역시나 에러가 터지는군요 🤔
비교를 위해 임시로 data class를 만들고 java 코드로 디컴파일해 봤습니다

data class의 일부인데요 !
copy() 메서드가 구현되어 있는 것을 볼 수 있습니다
프로퍼티 값을 복사해서 새로운 객체를 반환해 주네요 😎
data object 디컴파일 코드도 볼까요 🔥

data object는 data class와 달리 copy() 메서드가 없습니다 🤔
다행히 object를 copy 하는 일은 벌어지지 않겠군요 😂
이렇게 data object에 대한 탐구는 끝이 났습니다
아직 로그를 막 찍고 디버깅하는 과정을 경험해 보지 않아서 그런지 toString()의 이점은 와닿지 않긴 합니다 😂

하지만 개인적으로 sealed class 내부에서 object & data class가 섞여서 사용될 경우,
앞에 data 키워드가 일관성 있게 붙는 모습이 가독성 측면에서 좋다고 느껴집니다 👍🏻
좋은 글 잘 읽고 갑니다😊
궁금한 점이 있는데, sealed class를 Result로 사용할때 어느 경우에 data class, 또 어느 경우에 data object를 사용하면 좋을까요?