Sealed Class를 활용해서 서버응답 모델 깔끔하게 정의하기

Ted Park
박상권의 삽질블로그
5 min readJan 10, 2022

서버응답 필드가 경우에 따라서 null일때가 있고 아닐때가 있는 경우
모델을 만들때 어쩔 수 없이 Nulllable 필드로 만들어 왔습니다.
Sealed class를 활용해서 깔끔하게 만드는 방법에 대해 공유합니다.

저는 배달앱을 만들고 있는 개발자입니다.
사실 아닙니다. 그렇다고 가정을 해보겠습니다.

서비스에서 정의하는 User는 고객/업체사장님/관리자 로 나뉘어져 있습니다.
그리고 각각의 사용자를 나타내는데 필요한 정보를 가지고 있을것 입니다.

  • 고객: 이름, 주소, 전화번호, …
  • 업체 사장님: 이름, 주소, 사업자 등록증, …
  • 관리자: 이름, 부서, …

User API를 호출했을때 해당 사용자는
사용자 일 수도 있고 / 업체 사장님 일 수도 있고 / 관리자 일 수도 있습니다.

서버 응답은 각각에 맞춰서 다르게 내려올 것입니다.

// 고객
{
"type": "customer",
"name": "박상권",
"address": "서울시 성동구 탄탄대로1길 xxx",
"phoneNumber": "010-7777-7777",
...
}

// 업체 사장님
{
"type": "store",
"name": "몽고반점",
"address": "서울시 강남구 생각한대로7길 xxx",
"businessNumber": "111-12-35546",
...
}

// 관리자
{
"type": "admin",
"name": "박드로이드",
"department": "안드로이드팀",
...
}

위와 같은 서버 응답일때
지금까지 우리는 User 모델 클래스를 아래와 같이 정의해왔습니다.

  • 모든 사용자는 이름을 갖고 있습니다.
  • 업체 사장님은 사업자등록번호를 갖고 있지만, 고객/관리자는 없습니다.
  • 관리자는 부서이름이 있지만, 고객/업체사장님은 없습니다.

그래서 억울하지만 Nullable필드를 많이 만들어야 합니다..😡😡

이게 왜 억울하냐면
type == STORE 일때는 항상 businessNumber를 가지고 있음에도 불구하고
이 필드를 사용할때 Null체크를 하거나 느낌표 친구들을 불러야 합니다.

if (user.businessNumber != null) {
// 할거 하기
}
val businessNumber = user.businessNumber!!
// 할거 하기

고객, 관리자 type이라서 사용할때도 마찬가지입니다.

사용자 type에 따라서 논리적으로는 해당 필드가 Null일 수 없음에도 불구하고
Nullable로 정의되어 있는 필드를 처리해주어야 하는것이죠

이럴때 Sealed Class를 사용해서 효율적으로 User 모델을 나눠주면 됩니다.

1. Sealed class정의

  • 각 사용자마다 정의된 필드만 가지고 있는 모델 구조로 만들어줘서 Nullable한 필드가 없어집니다.
  • 별도의 type이라는 필드도 필요없이 class의 정의 자체가 해당 사용자의 type을 의미합니다.

2. 원본 User에 mapping 함수 추가

  • 각 type에 맞춰서 해당 사용자마다 맞는 class를 생성해줍니다.
  • 각 type마다 필요한 필드들이 Null일 수 없기 때문에 NonNull처리 할 수 있습니다.

서버문제로 인해 해당 type일때 NonNull이어야 하는 필드 값을 내려주지 않는 실수를 할 수도 있으므로 아래와 같이 유연하게 처리할 수도 있습니다.

Type.ADMIN -> User.Admin(
name,
department ?: run {
// 해당 필드 문제 오류 리포팅 남기기
"알 수 없음"
}

# User 고도화 하기

위와 같이 Sealed class를 활용해도 충분히 Null인 필드없이 효율적으로 사용할 수도 있습니다.

여기에 공통으로 정의되어 있는 name을 상위 class인 User의 필드로 만들어두면 나중에 유용하게 사용할 수도 있습니다.

사용자의 type에 상관없이 이름만을 가져와서 표시하고 싶은 경우,
어떤 class인지 알필요 없이 user.name으로 사용하기만 하면 됩니다.

이상으로 서버응답으로부터 어쩔 수 없이 Nullable로 만들어야 하는 상황들을
Sealed class로 해결하는 방법에 대해서 공유해드렸습니다.

코틀린을 공부할때 이론으로만 알아두었던 Sealed class를
이런 상황일때 사용할 수 있다고 생각하니 코틀린과의 친밀도가 +1 되셨을겁니다.

여러분이 알고 계시는 Sealed class의 또 다른 꿀팁이 있다면 댓글로 남겨주세요.

감사합니다. 피쓰!

안드로이드 개발자들이 모여있는 오픈채팅방에 참여해보세요 .
Q&A 및 팁을 공유하는 방입니다.

--

--