2026-01-26
1일 1아티클
LY
암묵적 연관성
문제 상황
class MessageModel(
val content: MessageContent,
val timestampMillis: Long,
val senderUserId: UserId,
...
)
sealed class MessageContent {
data object Empty: MessageContent()
data class Error(val errorType: ErrorType): MessageContent()
data class Text(val text: String): MessageContent()
data class Event(val eventType: EventType): MessageContent()
}
fun bindToViews(message: MessageModel) {
val isVisible = isContentValid(message.messageContent)
layoutContainer.isVisible = isVisible
if (!isVisible) {
return
}
timestampTextView.text = formatter.format(message.timestampMillis)
... // 기타 뷰 업데이트 로직
contentTextView.text = getMessageText(message.content)
}
private fun isContentValid(content: MessageContent): Boolean = when (content) {
MessageContent.Empty,
is MessageContent.Error -> false
is MessageContent.TextMessage,
is MessageContent.EventMessage -> true
}
private fun getMessageText(content: MessageContent): String = when (content) {
MessageContent.Empty,
is MessageContent.Error -> error("Invalid message type as `messageText`")
is MessageContent.TextMessage -> content.text
is MessageContent.EventMessage -> content.eventType.toMessageString()
}
문제점
getMessageText구현이 암묵적으로isContentvalid와 연관isContentValid가true반환 시에만getMessageText를 호출 가능하지만, 이를 위반해도 런타임 에러로만 감지 가능- 타입이 추가되거나 업데이트될 때,
isContentValid와getMessageText간의 동작 일관성 확인 필요 - → 리팩터링이나 기능 확장 시
getMessageText를 오용해도 알아채기 어려움
해결 방법
- 공통 로직을 하나의 함수로 합하여 해결
- 단독으로
getMessageText를 사용해도 안전성 확보 isContentValid와getMessageText간의 일관성 보장
- 단독으로
private fun isContentValid(content: MessageContent): Boolean =
getMessageText(content) != null
/**
* 메시지 콘텐츠[content]를 표시 가능한 텍스트 표현으로 변환하여 반환한다.
* 단 표시할 수 없는 콘텐츠 유형(error/empty)인 경우 null을 반환한다.
*/
private fun getMessageText(content: MessageContent): String? = when (content) {
MessageContent.Empty,
is MessageContent.Error -> null
is MessageContent.TextMessage -> content.text
is MessageContent.EventMessage -> content.eventType.toMessageString()
}
함수 간에 암묵적인 연관성이 있을 경우 함수를 하나로 합치거나 연관성이 명확한 구현으로 변경할 것
오늘 배운 것
- API 고도화 작업
- 사용자 파라미터 추가
- 사용자 정의 에러 코드 작성 및 에러 핸들링
- 로컬 테스팅을 통한 잘못된 로직 수정
- 입력값 검증 로직 추가
- Swagger 고도화 작업
- 버전 업그레이드
- JWT Header 설정
- 담당 API의 명세서 작성
내일 할 일
- 기타 업무