Kotlin Sealed class를 사용한 UI 상태 관리 (1/3)

드로이드나이츠 2018 에서 발표한 Kotlin Sealed class 를 이용한 뷰상태 관리 를 조금 더 자세하게 정리해서 공유합니다. SealedClass는 무엇이고? 뷰상태 는 무엇인가?? 하나씩 천천히 정리하겠습니다.

뷰상태란?

극단적으로 말하면 클라이언트 프로그래밍(웹, Android, IOS 등등) 은 상태를 관리하고 표현하는 프로그래밍 이라고 할수 있습니다. 사용자가 보고 만지는 화면은 상태의 집합체 라고 할 수 있습니다. 읽고 있는 텍스트 역시 미디엄 내부에서 관리하는 상태의 일부이며, 폰트 크기, 굵기, 아이콘, 링크, 이미지 등등모두 상태라고 할 수 있습니다.

  • 화면에 보여지는 모든 것은 상태가 있다고 말할 수 있다.
  • 상태란 상황에 따라 변할 수 있다.
  • 클라이언트 프로그래밍은 상태를 관리하고 상태 값을 표현하는 프로그래밍 이라고 할 수 있다.

상태를 왜 이렇게 강조할까?

일반적으로 사용자는 UI를 통해 상태 값을 접하게 됩니다. 만약 상태관리 및 표현에 문제가 있다면 사용자는 잘못된 UI를 만나게됩니다. 그렇기 때문에 상태 관리와 표현은 매우 중요합니다.

예를 들어 은행 어플리케이션에서 입금과 출금 상태가 잘못 관리된다고 생각해보면… 매우 끔찍합니다… 공공기관에서 상태값을 잘못 표시된다면… 사회가 정상적으로 돌아가지 않을 수도 있습니다.

이처럼 상태는 매우 중요합니다. 하지만 관리가 쉽지 않습니다. 상태 관리가 제대로 이루어지지 않는다면 어떻게 될까요?

  1. 상태가 많아지면 코드가 복잡해짐
  2. 코드가 복잡해지면 유지보수 및 관리가 어려워짐
  3. 유지보수 및 관리가 어렵다면 SideEffect가 발생할 확률이 높아짐
  4. 사용자에게 잘못 된 정보를 제공하거나, 서비스가 비정상 종료될 확률이 높아짐

정리하자면 이글의 결론입니다. 좋은 프로그램을 만들려면 상태관리 및 표현을 잘 해야 합니다.

SealedClass란?

SealedClass란 Kotlin에서 제공하는 문법입니다. 대수적타입(Algebraic data type) 중에서도 합타입을 표현할수 있습니다. 대수적타입은 이전에 작성한 포스팅을 참고하면 좋습니다.

어떻게 뷰상태를 잘 관리할까?

앞서 설명한 상태와 Kotlin의 SealedClass를 사용해서 어떻게 뷰상태를 잘 관리 할 수 있을까? Kotlin의 SealedClass는 대수적 타입(그중에서도 합타입, 자세한 설명은 위 링크 참조)입니다. 즉 SealedClass를 생성하는 당시 모든 값을 알고 있습니다. SealedClass로 상태를 표현한다면 SealedClass생성 당시모든 상태에 대해서 알고 있다고 할 수 있습니다.

  • SealedClass 를 상속받는 class는 SealedClass 구현 당시 모두 구현해야 한다.
  • SealedClass 로 상태를 표현구현 한다면 구현 당시 모든 상태에 대해 알고 작성해야 합니다.

예제코드를 통해 살펴보겠습니다. 전체 코드는 위 링크를 확인하시면 됩니다.

그림처럼 나오는 간단한 샘플앱을 만들면서 설명을 하겠습니다.

일반적인 소스

크게 문제 없어보이지만 몇가지 문제를 가지고 있습니다. 문제점을 하나씩 살펴보겠습니다.

  • 상태를 상수로 관리하고 있다. (1~7번째 라인)
  • 상태를 Activity 가 관리하고 있다.

왜 문제일까요? 만약 새로운 상태가 추가된다고 가정해보겠습니다.

ItemD가 추가된다면?

1. 상수값 ITEM_D = 4 를 추가합니다.

2. 버튼 클릭 이벤트를 추가합니다.

예제 코드처럼 코드를 수정하고 실행을 하면 다음과 같은 화면이 출력됩니다. 물론 xml 도 추가해야되만 xml코드는 생략하겠습니다.

그리고 ITEM D 버튼을 클릭하면 어떻게 될까요?

앱이 종료됩니다.

UI 및 상태 생성, 이벤트 전달 코드만 추가 및 수정을 하고 이벤트를 소모하는 코드는 수정하지 않았습니다. 따라서 else 분기를 따르기때문에 exception이 발생합니다. 실제로 잦은 실수가 일어나는 코드 중 하나 입니다.

정상적인 결과를 원한다면 ITEM_D에 대한 분기처리를 해야 합니다.

ITEM_N 이 계속 추가된다면???

  • 상태 상수값을 계속 추가해야 한다.
  • 클릭 이벤트 발생 코드도 계속 추가해야 한다.
  • 이벤트 소모 코드도 계속 추가해야 한다.

상태가 추가될 때마다 이런 소모적인 코드를 반복해서작성해줘야 합니다. 매우 불편하고 의미없는 작업입니다. 또한 다음과 같은 문제가 발생합니다.

  • 상태만 추가하고 비즈니스 로직을 구현하지 않아도 컴파일에 문제가 없다.
  • 런타임에 에러가 발생할 수 있다.
  • ITEM_N 의 값 1, 2, 3, N은 의미가 없다.
  • 중복 된 ITEM_N이 작성 될수도 있다.
  • 요구 사항이 늘어 날 때마다 코드 전체가 영향을 받는다.

예제코드를 어떻게 개선 할까요?

다음 편에서 이어서 작성 하겠습니다.

발표자료