본문 바로가기

Computer

[ Tebah ] Tebah 앱 개발기 : 도메인 설계를 시작하며

안녕하세요. 

 

[ Tebah ] 카테고리에서는 제가 Tebah 앱을 개발하면서 느낀 점들을 정리하려고 합니다. 

 

Tebah 앱은 기본적으로 기독교 신자들을 대상으로 한 커뮤니티 앱입니다. 

 

Tebah 앱은 두가지의 목표를 가지고 있습니다.

 

첫째는 교회 내의 분산된 공지 채널을 하나로 합치는 것입니다. 

 

교회 내에는 다양한 모임이 존재합니다. 하지만, 공지 채널이 하나가 아닌 경우가 많습니다.

 

카카오톡, 네이버 밴드 등 다양한 채널이 존재하기 때문에 공지가 흩어져 있는 단점이 있습니다.

 

저희 앱에서는 하나의 공지 채널로 이를 통일하려고 합니다. 

 

두번째 목표는 기독교 커뮤니티를 활성화하는 것입니다. 

 

교회 사람들은 보통 말이 많습니다. 하지만 의견을 나눌 수 있는 플랫폼이 별로 없습니다. 

 

저희 앱에서는 다양한 컨텐츠를 제공하여 이러한 문제점을 해결하려고 합니다. 


Tebah 앱은 디자이너 한 명과 안드로이드 개발자인 저 이렇게 2명이서 진행하는 프로젝트입니다. 

 

백엔드 개발자가 없다보니 파이어스토어, 파이어베이스 등 다양한 서비스들을 활용해 구현하였습니다. 

 

디자인 패턴은 MVI 패턴을 사용해 구현하고 있습니다.

 

현재는 MVP를 먼저 개발 중에 있습니다. 

 

피드백을 받고 여러 번 개선하는 형태로 서비스를 확장해나가려고 합니다. 


명확하게 처음부터 기획된 프로젝트가 아니다보니 디자이너와 저의 머리속에 있는 상상을 바탕으로 구현을 시작하였습니다.

 

와이어프레임도, 디자인도 정해지지 않은 시기에서 개발을 시작하다보니 막막했습니다. 

 

일단은 프로젝트를 빠르게 진행시키기 위해서 MVP를 먼저 빠르게 만드는 것을 목표로 해보자고 이야기했습니다.

 

그리고 상상을 조금 더 구체화시키기 위해 아주 간단한 형태의 와이어 프레임을 만들어달라고 요청하였습니다. 

 

처음에는 이런 방식으로 구현을 시작하였고 저는 기본적인 Compose UI를 만드는 도중이었습니다.

 

이런 방식으로 프로젝트를 진행하다보니, 추후에 변경될 수 있는 UI를 계속 작업하는게 효율적이지 않다는 생각이 들었습니다. 

 

그래서 이런 저런 방법론들을 찾아보다가 도메인 주도 설계 이론을 접하게 되었습니다. 

 

이번 글에서는 모바일 프로젝트에서 도메인 주도 설계 이론을 적용하는 방법에 대해 다루려고 합니다. 


본론

* 이 내용은 패스트 캠퍼스의 The RED : 강사룡의 앱 안정성 및 확장성 강화를 위한 Android 아키텍처. 강의에 나온 내용을 바탕으로 제가 이해한 것을 정리한 것입니다.

 

강사님에 따르면 Tebah 프로젝트를 진행하는 나와 같은 상황이 회사에서도 종종 발생한다고 합니다.

 

기획이 완성되지 않은 상태로 개발을 시작해야하는 경우가 있다는 것이죠.

 

보통 우리는 4가지의 선택을 할 수 있는데요. 

 

01 기다린다. 

 

02 데이터 스키마 설계.

 

03 화면 중심 설계

 

04 기술적으로 준비한다. 

 

한 번 생각을 해보면 좋을 것 같습니다. 

 

저의 경우에는 3번을 선택해 진행하였습니다. 

 

1번의 경우는 제 성격과도 맞지 않고 실무에서 저런 선택을 하는 사람은 없겠죠.

 

4번의 경우도 파이어 스토어를 사용할 예정이기에 저는 4번의 경우도 해당해서 진행했던 것 같습니다.

 

2번의 경우는 저같은 경우에는 비효율적이라는 생각이 처음부터 들었는데요. 

 

백엔드 Api로 통신을 하는 경우에도 데이터 구조를 그대로 사용하지 않는다는 것을 너무 잘 알고 있었기 때문에 애초에 비효율적이라는 생각이 들었습니다.

 

하지만 제가 진행한 3번, 4번의 경우도 결국에는 한계가 있는 방식임을 프로젝트를 진행하면서 느낄 수 있었습니다.

 

아키텍쳐에 대한 공부는 그래서 끊임없이 해야하는 것 같습니다.


강의에서 강사님은 2번의 경우를 좋지 않게 평가하셨는데요.

 

이렇게 말하시더라고요.

 

"데이터베이스 중심의 설계란 없습니다."

 

이 말이 저는 참 와닿았는데요. 결국 데이터 자체에 집중하다보면

 

각 모듈의 책임이 분리되지 않을 것임을 직감할 수 있었습니다. 

 

강사님은 Behavior focus vs data centric focus라는 주제로 계속 이야기를 하셨는데,

 

도메인 지식은 데이터베이스의 스키마로부터 뽑아낼 수 없으며

 

그렇게 하더라도 비효율적이기 때문에 

 

도메인 모델링은 도메인 전문가와 유저 스토리의 도움으로 이루어져야한다고 말씀하셨습니다.

 

기획자/비즈니스 부서와 함께 핵심 사용자 시나리오부터 정하는게 좋다고 말씀하셨습니다.

 

실재로 구글에서도 Critical User Jorney라고 이 과정을 명칭하며 중요한 프로세스로 다룬다고 합니다.

 

핵심 사용자 시나리오를 정하는 과정자체가 도메인 설계의 핵심이고

 

이 과정에서 우리가 생각해보아야할 것이 참 많다는 생각이 들었습니다. 


기획자 한 명과 함께 단독으로 프로젝트를 진행하면서 느끼는 것은 

 

DDD라고 불리는 도메인 주도 설계의 기법이 실재 프로젝트를 진행하는 데에 큰 도움을 준다는 것이었습니다.

 

저희 프로젝트처럼 기획이 완성되지 않은 프로젝트에서 기획과 개발이 효율적으로 협업하는 방법은 

 

도메인을 먼저 설정하는 것. 

 

핵심 사용자 시나리오를 같이 생각해보는 것.

 

이게 핵심인 것 같습니다. 


핵심 사용자 시나리오를 구성할 때 가장 중요한 것은 

 

가변 요소와 불변 요소를 잘 구분하는 것입니다. 

 

예를 들어 회원 전용 기능이 필요하다면,

 

가변 요소는 회원 정보를 어떻게 저장할 지, 회원 가입 과정이 몇 페이지에 걸쳐서 이루어질 지 같은 것입니다.

 

반면 불변 요소는 회원에게 어떤 정보를 꼭 받아야 하는가? 회원과 비회원의 차이는 무엇인가? 하는 것입니다. 


사실 DDD 자체를 안드로이드 프로젝트에 적용하는 것은 변형이 필요합니다. 

 

이 글에서는 DDD 자체에 초점을 맞추기 보다 저희 프로젝트에서 DDD를 활용한 방법과

 

모바일 프로젝트에 적용할 때의 특이점에 초점을 맞추려고 합니다.

 

*앞으로의 내용들은 DDD 자체라기 보다 DDD를 모바일 프로젝트에 맞게 변형한 내용이라고 할 수 있습니다.


 

도메인 레이어 자체를 하나의 모델로 설명하기는 쉽지 않습니다. 

 

저희 프로젝트에서는 도메인 레이어를 3개의 수직적인 계층으로 분리하였습니다. 

 

형태를 살펴보면 이렇습니다.

 

📦 com.example.tebah
├── data         // 데이터 소스 (Room, Retrofit 등)
├── domain       // ← 여기가 도메인 레이어!
│   ├── model
│   ├── repository
│   └── usecase
└── presentation // UI 계층 (Activity, ViewModel, Compose 등)

 

model, repository, usecase 이렇게 3개의 계층으로 구분되어 있습니다. 

 

각각에 대해서 조금 유의해야할 점을 먼저 설명드리려고 합니다. 

 

model, 도메인 엔티티를 설계할 때 주의해야할 점은

 

저장소, 저장 방법 등은 일단 무시하는 것입니다. 

 

인프라 스트럭쳐보다는 비즈니스 문제만 집중할 수 있도록 설계해야 합니다. 

 

또 transaction에 집중하되, 이를 표시할 스크린이 어떻게 디자인 될 것인가에 대해서는 적게 신경쓰라고 조언합니다.

 

또 원칙적으로, 데이터 계층의 엔티티와 도메인 계층의 엔티티가 같을 것으로 기대해서는 안됩니다.

 

서로의 데이터에 대해 의존이 생기면 데이터 스키마 변경 시 양쪽을 다 고쳐야하기 때문이죠.

 

어느 정도 스키마가 정립된 이후에는 최적화를 고려해볼 수도 있긴 하겠지만 말이죠.

 

다음으로 usecase를 사용할 때에는 보통 코틀린에서는 invoke 메서드를 사용합니다.

 

상태가 없고, 하나의 operation만을 가진 Use Case의 형태로 구성하는 것이죠.

 

UseCase들의 연관성이 떨어질 때에만 사용하는 것이 좋겠습니다.

 

다음으로 Repository입니다. 

 

Repository는 도메인 객체를 저장하고 불러오는 역할을 담당하는 추상화 계층입니다.

 

데이터 저장소에 대한 세부 구현을 감추면서도 마치 컬렉션처럼 도메인 객체를 꺼내거나 저장할 수 있게 도와주는 역할을 담당합니다.

 

Repository의 가장 중요한 점은 의미 있는 도메인 쿼리를 제공한다는 것인데요.

 

비즈니스 개념에 기반한 쿼리를 제공하는 것이 Repository의 목적이라고 할 수 있겠습니다.

 

또 Repository를 설계할 때 꼭 명심해야할 사항이 있습니다.

 

하나의 aggregate root당 하나의 repository를 만드는 것인데요.

 

이 부분을 이해하는 것이 정말 중요하다고 생각합니다.

 

aggregate root는 도메인 객체들의 집합이라고 할 수 있습니다.

 

예를 들어, Order는 하나의 Aggregate이고, 그 안에는 OrderItem, ShippingInfo, PaymentInfo 같은 객체들이 들어있을 수 있는 것이죠.

 

이 때, Order가 그 집합의 대표자라고 할 수 있습니다. 즉 Aggregate root라고 할 수 있죠.

 

Aggregate root라는 것 자체가 의미가 꽤 큰데요.

 

먼저 외부에서는 Aggregate 내부에 직접 접근하지 않습니다.

 

외부에서 데이터를 조회하거나 수정할 땐 항상 root를 통해서 해야 합니다.

 

이 말을 잘 생각해보면 이런 말이라는 생각이 들었습니다.

결국 도메인 레이어는 비즈니스 로직을 담당하는 부분이고 Aggregate Root는 비즈니스 로직을 가장 크게 구분하는 핵심 구성 요소이다. 따라서 비즈니스 로직 자체는 Aggregate Root를 통해서 모두 설명될 수 있게 구성해야 한다.

 

처음부터 Aggregate Root를 잘 정의하는 것이 도메인 레이어를 잘 설계하는 방법이라고 생각합니다.

 

오늘부터는 회의를 통해서 Aggregate Root와 그 외의 세부적인 비즈니스 요구 사항들을 정리해서 코드화하려고 합니다.

 

오늘 글은 여기서 마칩니다.

 

글 읽어주셔서 감사합니다.

 

읽어주시는 분이 많을 거라고 생각하지는 않지만 댓글 많이 남겨주시면 감사하겠습니다.

 

개발 얘기를 많이 나누고 싶네요.

 

감사합니다.

'Computer' 카테고리의 다른 글

[CS] 프로세스와 스레드  (0) 2025.03.26
[Android] JVM vs ART  (0) 2025.03.22
[Android] Kapt Error  (2) 2024.12.10
[Kotlin] 클래스를 상속받을 때 주의할 점  (0) 2024.12.09
[Jetpack Compose] Compose, 최적화를 위한 원칙  (0) 2024.11.21