[Android] Clean Architecture의 책임 분리와 의존성 방향
·
Mobile/Android
프로젝트를 시작할 때마다 고민하게 되는 게 있다.프로젝트 구조를 어떻게 잡지?지난 글에서는 OOP와 SOLID를 통해 객체 단위에서 책임과 의존성을 나누는 기준을 정리했다.그렇다면 이 원칙을 프로젝트 전체 구조에는 어떻게 적용해야 할까?이번 글에서는 실제 프로젝트(What’s Your ETF)에 적용했던 구조를 바탕으로 Clean Architecture의 계층과 의존성 방향을 정리해보려고 한다.✏️ Clean Architecture는 무엇을 해결하려는 걸까?프로젝트의 규모가 커질수록 단순히 클래스를 나누는 것만으로는 부족했다.UI와 데이터 처리, 비즈니스 로직이 서로 강하게 연결되어 있으면 하나의 변경이 다른 영역까지 영향을 미치니까!!문제는 파일의 개수가 아니라 서로 다른 이유로 변경되는 코드가 얼마나..
[객체지향] 변경하기 쉬운 코드는 어떻게 만들까? (OOP, SOLID)
·
카테고리 없음
졸업 프로젝트를 진행할 때 스파게티 코드의 나비효과를 겪으면서 처음으로 코드 구조의 중요성을 체감했다...당시에는 잘 모르기도 했고 기능 구현에 집중한 나머지 클래스의 책임을 명확히 나누지 못했다.결론적으로 하나의 기능을 변경하려고 함수를 따라가다가 n개의 파일을 함께 수정해야 했고,그렇기에 코드끼리 강하게 결합되어 한 부분의 변경이 예상하지 못한 다른 기능에 영향을 주기도 했다. 😢이후 MVVM과 Repository 패턴을 적용해봤지만 단순히 파일을 나누는 것만으로는 부족했고하나의 클래스는 어디까지 책임져야 할까?기능 간 변경 영향을 어떻게 줄일 수 있을까?서로 다른 구현을 유연하게 교체하려면 어떻게 해야 할까?이러한 고민을 해결하기 위해 객체지향 프로그래밍과 SOLID 원칙을 다시 공부했다! ✏️..
[Android] 상황에 따라 달라지는 API 중복 호출 방지 방법
·
Mobile/Android
앱을 개발하다 보면 버튼 연타나 빠른 입력 때문에 API가 여러 번 호출되기도 한다.처음에는 모든 중복 호출에 debounce를 적용하면 된다고 생각했다.하지만 검색어는 마지막 입력값, 버튼은 첫 클릭에 대한 즉각적인 반응이 중요하다.따라서 중복 호출을 막기 전에 어떤 요청을 남길지 판단해야 한다. ✏️ 검색어 입력에는 debounce사용자가 삼성전자를 입력하면 다음과 같이 값이 연속으로 바뀐다.삼 → 삼성 → 삼성전 → 삼성전자모든 값으로 API를 호출할 필요는 없다.debounce를 사용하면 일정 시간 동안 새로운 값이 들어오지 않았을 때 마지막 값을 전달할 수 있다.searchQuery .debounce(300L) .collectLatest { query -> searchS..
[Android] 화면 회전에는 살아남는 ViewModel이 프로세스 종료 후에는 사라지는 이유
·
Mobile/Android
Android에서 화면 상태를 관리할 때 ViewModel을 사용하면 화면을 회전해도 기존 데이터를 유지할 수 있다.그래서 처음에는 ViewModel에 상태를 저장해두면 화면이 다시 만들어져도 데이터가 계속 남아 있다고 생각했다.하지만 앱이 백그라운드에 있는 동안 시스템이 프로세스를 종료하면 ViewModel의 데이터도 함께 사라진다.화면 회전과 프로세스 종료는 무엇이 다르고, 프로세스 종료 이후에는 상태를 어떻게 복원해야 할까?이번 글에서는 화면 회전과 프로세스 종료의 차이, ViewModel의 한계와 SavedStateHandle이 필요한 경우를 정리해보려고 한다. ✏️ 화면 회전 시 ViewModel은 왜 유지될까?화면 방향이 변경되면 기존 Activity는 파괴되고 새로운 설정에 맞는 Activ..
[Android/Kotlin] Retrofit·Room 호출에는 무조건 Dispatchers.IO가 필요할까?
·
Mobile/Android
프로젝트에서 Retrofit이나 Room을 사용할 때마다 습관적으로 Dispatchers.IO를 지정해왔다.네트워크와 데이터베이스 작업은 시간이 오래 걸릴 수 있고, 이를 Main 스레드에서 실행하면 UI가 멈출 수 있다고 생각했기 때문이다.그런데 Retrofit과 Room의 함수가 이미 suspend로 선언되어 있다면 정말 매번 Dispatchers.IO로 감싸야 할까? 🤔이번 글에서는 코루틴과 스레드, suspend의 의미를 살펴보고 Retrofit과 Room 호출에 Dispatchers.IO가 반드시 필요한지 정리해보려고 한다. ✏️ 기존에 작성하던 코드기존에는 Repository에서 Retrofit을 호출할 때 다음과 같이 작성했다.suspend fun getUsers(): List = ..
[Android] null-safe 처리를 했는데도 Text()에서 앱이 터진 이유
·
Mobile/Android
😲 문제 상황프로젝트 개발 중 갑자기 앱이 터지는 문제가 발생했어요 🥹에러 로그를 살펴보니 Text() 컴포넌트에서 이런 로그가 찍히고 있었습니다java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object referenceat androidx.compose.ui.text.platform.AndroidParagraphHelper_androidKt.createCharSequence(AndroidParagraphHelper.android.kt:70)Compose의 Text()는 내부적으로 문자열 길이를 계산하기 위해 length()를 호출하는데이때 null이 들어오..
[Android] Firebase로 채팅 앱 만들기 #1 - Firebase 세팅하기
·
Mobile
안녕하세요! 🐶이번 글에서는 채팅 시스템 구현을 위해 필요한 Firebase 기본 세팅 방법을 정리해보려고 합니다✏️ Firebase 프로젝트 추가하기1️⃣ Firebase Console 접속먼저 Firebase Console에 접속해 Firebase 프로젝트 만들기를 클릭합니다 2️⃣ 프로젝트 만들기 원하는 프로젝트의 이름을 입력합니다 Gemini와 Google 애널리틱스 활성화 여부는 필요에 따라 선택해주세요저는 이번 프로젝트에서는 사용하지 않겠습니다!모든 선택을 마치면 프로젝트가 생성됩니다 🎉 ✏️ Android 앱 Firebase에 연결하기1️⃣ Android 앱 등록Firebase Console에서 Android 아이콘을 클릭합니다 2️⃣ 필수 정보 입력Android 패키지 이름(필수): ..
[Android/Compose] Android Chip 사용법
·
Mobile/Android
안녕하세요~ 🎵 오늘은 Android에서 Chip을 사용하는 방법을 정리해보려고 합니다앱을 사용하다 보면 아래와 같은 UI를 종종 볼 수 있습니다이러한 요소를 Chip이라고 부릅니다!이번 글에서는 Chip의 정의와 종류 그리고 구현하는 방법까지 다뤄보겠습니다 🧐 ✏️ Chip이란?🔹 Chip의 정의Chip이란 Material Design 시스템에서 제공하는 UI 컴포넌트로태그, 카테고리, 선택지, 액션 등 작은 정보 단위를 시각적으로 표현할 때 사용합니다 📌 Chip을 사용하면 다음과 같은 장점이 있어요:간결한 정보 표현사용자의 입력/선택 유도공간 절약 🔹 Chip의 종류종류설명예시Assist Chip액션을 보조하는 버튼 형태"주소 검색" 버튼Filter Chip다중 선택 가능한 필터관심사 선택..
[Android/Compose] SGIS API로 단계별 주소 선택기 구현하기
·
Mobile/Android
안녕하세요! 😊 오늘은 통계청에서 제공하는 단게별 주소 조회 API를 사용하여 주소 선택기를 구현하려고 합니다 프로젝트에서 사용자로부터 정확한 주소 입력을 받아야 하는 상황이 있었고 이를 직접 입력 받는 대신단계별로 선택할 수 있게 선택형 UI로 만들면 더 직관적일 것 같아 SGIS API를 사용하게 되었습니다!✏️ SGIS 주소 API 사용 방법🔸 SGIS API 사용 개요SGIS Developers에서 제공하는 공공 API 단계별 주소 조회 API를 사용하였습니다이 API를 통해 시/도 → 시/군/구 → 읍/면/동 단위로 주소 정보를 불러올 수 있습니다💡 초기 설정 및 테스트는 아래 블로그 참고! [Flutter] 공공 API로 주소 검색 & 주소 선택기 만들기 (BLoC)공공 API로 주소..
[Jetpack Compose] Modal Drawer 구현하기
·
Mobile/Android
이번 글에서는 Modal Drawer에 대해 포스팅 하려고 합니다Drawer는 앱에서 매우 자주 사용하는 UI 요소로 화면의 일부분을 슬라이딩하여 열고 닫을 수 있게 합니다이 Drawer는 Scaffold로 간단하게 구현할 수 있지만!이번에는 top bar와 메뉴 버튼이 별도로 없으며 레이아웃 구성을 자유롭게 하기 위해Material3의 Modal Drawer를 사용하여 직접 구현해보았습니다 😎 ✏️ Modal Drawer 의 기본 개념Modal Drawer는 화면에서 사용자가 화면의 일부분을 슬라이딩하여 열고 닫을 수 있는 UI 요소입니다이 Drawer는 기본적으로 DrawerState를 사용하여 Drawer의 열림/닫힘을 제어합니다 🔹 DrawerState다음과 같이 rememberDrawerSt..