Clean Architecture를 기반으로 '다온길' 프로젝트를 진행하던 도중 UseCase에서는 단순히 Repository를 호출만 하는 코드가 늘어나고 있는 것을 발견할 수 있었다. 프로젝트가 커질수록 불필요한 코드들을 관리하기가 조금은 수고스러웠다. 그러던 도중 팀원들과 회의를 하다 이런 이야기가 나왔다.
"UseCase 꼭 필요할까..? 🤔"
😮 UseCase란?
Clean Architecture의 Domain Layer에서 UseCase의 모습을 볼 수 있습니다
UseCase는 서비스를 사용하고 있는 사용자가 해당 서비스를 통해 하고자 하는 것을 의미합니다
예를 들어 쇼핑몰 서비스가 있을 때,
- 상품 검색하기
- 상품 구매하기
- 상품 리뷰 남기기 등
서비스에서 사용자가 사용하고자 하는 최소 요청 단위를 의미합니다
🤓 UseCase는 왜 사용할까?
1. 비즈니스 로직의 캡슐화
UseCase는 위에서 이야기했듯 사용자가 하고자 하는 최소 요청 단위, 즉 비즈니스 로직을 의미합니다
이렇게 비즈니스 로직을 캡슐화 하면 외부 계층에서 비즈니스 로직이 흩어지지 않도록 방지해주고, 다른 계층(Presentation, Data)과 분리하여 관리가 가능합니다
2. 계층 간 의존성 분리
만약 UseCase를 사용하지 않게 된다면 Repository를 통해 직접 전달하는데, 이때 데이터 수정이 발생하면 해당 Repository를 사용하는 많은 부분에서 수정이 이루어질 수가 있습니다
🤔 UseCase 꼭 필요할까?
위에서 설명한 이유에 근거해서 처음엔 당연히 UseCase를 사용하고 있었습니다
그런데 문득 구현을 하다보니 단순히 Repository를 호출하기만 하는 불필요한 코드들이 중가하였고, 그렇다면 UseCase가 굳이 필요할까..? 라는 의문점이 들기 시작하였습니다
그래서 UseCase를 써야하는 이유와 써야하지 않는 이유에 대해 정리하며 회의를 진행해보았습니다
🙆🏻♀️ UseCase 써야한다
1. Screaming Architecture
Screaming Architecture는 소프트웨어의 구조만 보고도 이 시스템이 어떤 일을 하는지 이해할 수 있어야 한다는 개념인데요,
UseCase를 통해 시스템의 도메인 로직을 알 수 있도록 설계하는 것이 핵심이라는 것입니다. 이를 통해 시스템이 어떤 역할을 수행하는지 한 눈에 파악할 수 있습니다
2. 미래의 변화 보호
요구사항이 변경될 때 쉽게 적응할 수 있는 코드 베이스를 제공해야 합니다
즉, 변경해야 하는 코드의 양을 최소화해야 한다는 의견입니다
🙅🏻♀️ UseCase 쓰지 않아도 된다
1. 비즈니스 로직이 맞을까?
UseCase가 실제 코드 안에서 단순히 Repository를 호출하는 일만 한다면, 이 부분이 비즈니스 로직이 맞을까?라는 의문이 가장 크게 들었습니다
예를 들어, Repository의 메서드를 직접 호출해도 충분히 코드의 가독성을 유지하고 로직을 분리할 수 있다면, UseCase는 오히려 코드 관리의 부담을 늘릴 수 있습니다
결과적으로 필요하지 않은 계층이 되어 오버엔지니어링이 될 가능성이 있습니다
그리고 가장 많은 영감(?)을 받은 드로이드나이츠 영상이 있는데요,
https://www.youtube.com/watch?v=3mR8_vT7m1U
영상에서는 단순히 Repository의 메소드를 호출하기만 하는 UseCase를 비즈니스 로직이라고 볼 수 있는가?, 비즈니스 로직을 가지고 있지 않는 UseCase 등에 대한 이야기를 다룹니다
위 이미지에 있는 UseCase 코드의 형태가 저희 프로젝트에서 비슷하게 반복되고 있었습니다
이때 이런 현상은 많은 로직들을 서버에 위임하고 있는 경우에 나타난다고 말씀하셨는데요, 저희가 완전히 Server-Driven까진 아니지만 대부분의 데이터를 서버에서 걸러서 전달해주기 때문에 저희의 상황과 비슷하다는 생각이 들었습니다
그리고 무엇보다도 아키텍처에 정답은 없고, 각자의 상황에 맞게 팀원들과 이야기를 통해 가이드를 만드는 것이 가장 중요하다는 말씀을 해주셨습니다
💡 결과는
그래서...! 저희도 회의를 통해 이러한 이유들을 토대로 한번 UseCase를 없애보자! 라는 결론을 내렸습니다
위에서도 계속 이야기 했지만 저희의 Clean Architecture의 정석(?)대로 구현해본 저희 팀의 경험 상 불필요한 코드인 UseCase는 한번 없애보자는 의견이 가장 컸고, 단순히 Repository를 호출만 하는 UseCase는 없애기로 결정을 하였습니다
하지만 여러 Repository를 동시에 호출해서 데이터를 가공할 필요가 있는 경우에는 UseCase에 모아두면 유지보수성이 높아지기 때문에 구현을 하며 이런 경우에만 UseCase를 만들어서 사용하는 것으로 저희 팀만의 가이드를 만들었습니다
UseCase가 있는 다온길 ver
https://github.com/Journey-Together/Android
GitHub - Journey-Together/Android: 안드드드드드르르르륵탁 🪓
안드드드드드르르르륵탁 🪓. Contribute to Journey-Together/Android development by creating an account on GitHub.
github.com
UseCase가 없는 다온길 ver
https://github.com/Journey-Together/DaOnGil_CleanArchitecture
GitHub - Journey-Together/DaOnGil_CleanArchitecture: 다온길 프로젝트 클린 아키텍처(Hilt) ver 🧼
다온길 프로젝트 클린 아키텍처(Hilt) ver 🧼. Contribute to Journey-Together/DaOnGil_CleanArchitecture development by creating an account on GitHub.
github.com
🍀 마무리
이렇게 UseCase를 없애서 구현을 해보니 아무래도 불필요한 코드를 없애니 관리는 조금 더 편해졌던 것 같습니다
그렇지만 저희 팀은 든든한 서버팀이 데이터를 대부분 필터링해서 필요한 부분만 보내주었기에 이렇게 사용할 수 있었을 것 같다는 생각도 들긴 하네요.. 🤔
물론 UseCase를 없애본 것도 좋은 경험이였지만 무엇보다도 정해진 아키텍처에만 갇히지 않고 저희가 필요한대로 고민하고, 가공하며 고민했던 시간들이 가장 좋은 시간들이었던 것 같습니다
아키텍처라는 개념이 처음엔 너무 어렵기도 하고 어떤 게 정답인지 모르겠어서 헤맸던 시간들이 많았는데 이렇게 고민할 수 있는 시간이 생겨서 덕분에 아키텍처에 대한 고민도 나누고 조금 더 깊게 배워갈 수 있었던 것 같습니다. 또, Clean Architecture가 좋은 아키텍처인가? 라는 글을 본 적이 있는데 다시 한번 고민하고 유연성 있게 바꿔볼 수 있어서 재밌었습니다 ㅎㅎ
역시 같은 고민을 나눌 수 있는 팀원들이 있다는 건 행복하고 감사한 일입니다 🍀
'Android' 카테고리의 다른 글
[Android] Coroutine에서는 왜 Thread보다 교착상태가 덜 발생할까? (0) | 2025.02.10 |
---|---|
[Android] UI는 왜 Main Thread에서만 그려져야 할까? (0) | 2024.10.25 |
[Android] 객체지향 프로그래밍이란? (객체지향 프로그래밍 != SOLID 원칙) (0) | 2024.10.11 |
[Android] 프로젝트에 Hilt로 의존성 주입하기 (다온길 마이그레이션) (0) | 2024.10.05 |
[Android] Dagger와 Hilt로 자동 의존성 주입 이해하기 (0) | 2024.10.03 |