문제의 역사:
Kotlin 1.9 이전에는 object 객체가 data일 수 없어, 자동으로 equals, hashCode, toString을 받고 있는 싱글턴 객체를 만들 수 없었습니다. data object가 도입되면서 이 제한이 해제되었습니다. 이제는 값(value) 및 열거형(enum)과 유사한 패턴에 적합한 자동으로 생성된 메서드를 가지는 싱글턴 객체를 만들 수 있습니다.
문제:
이전에는 싱글턴 객체들조차도 올바른 equals(), hashCode(), toString()을 얻기 위해 수동으로 구현하거나 다른 트릭을 사용해야 했습니다. 이는 보일러플레이트 코드 증가와 오류 가능성을 높였습니다.
해결책:
데이터 객체(data object)는 인스턴스가 고유하며, 컬렉션, 직렬화, 비교 및 디버깅용으로 표준적인 equals/hashCode/toString 동작이 필요한 객체를 위해 사용하세요.
코드 예시:
data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "데이터가 없습니다" else -> "다른 상태" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable
주요 특징:
데이터 객체가 속성을 가질 수 있나요?
가질 수 있지만, backing field 없이 val 속성만 가능합니다(싱글턴에는 저장되는 것이 없어야 함).
data object Loading { val status: String get() = "로딩 중..." }
데이터 객체가 일반 객체와 equals 측면에서 어떻게 다릅니까?
일반 객체의 equals는 참조 동등성만 확인하지만, 데이터 객체는 데이터 계약을 비교합니다. 그러나 싱글턴의 경우 항상 동일한 객체입니다. 그럼에도 불구하고 재정의된 equals/hashCode가 컬렉션에 더 유용합니다.
데이터 객체로부터 상속할 수 있나요?
아니요, 데이터 객체는 최종적이며(모든 객체가 그렇듯) 상속할 수 없습니다.
모든 상태에 대해 enum 대신 다양한 데이터 객체를 사용했습니다. 1년 후 문자열별 직렬화가 필요하게 되었고, 객체 이름과 유형을 수동으로 매칭해야 했습니다.
장점:
단점:
네트워크 요청의 반환 값으로 데이터 객체를 사용하여 특별한 상태: Loading, Empty, Error를 사용했습니다. 코드가 컴팩트하고 equals, hashCode, toString이 자동으로 지원됩니다.
장점:
단점: