data class랑 class랑 뭐가 그렇게 다른데?
·
외부 활동/우아한테크코스 8기
안녕하세요! 최근 우테코 프리코스 과정을 진행하면서 굉장히 많은걸 배우고 있어요.이번 2주차 자동차 경주 미션을 진행하면서 다른 분들의 코드를 리뷰할 기회가 있었는데, 한 가지 흥미로운 점을 발견했어요. 바로 핵심 도메인 객체인 Car를 설계하는 방식이 크게 두 가지로 나눠지는 점이에요.data class를 사용해 불변(immutable) 객체로 구현한 방식일반 class에서 내부 상태를 직접 변경하는 가변(mutable) 객체로 구현한 방식 (public var 또는 백킹 프로퍼티 활용)저는 테스트 용이성과 코드의 안정성을 높이기 위해 data class를 선택했는데요, 이 주제로 동료들과 토론을 나누다 보니 문득 이런 궁금증이 생겼어요."그래서, 정말 성능 차이가 얼마나 날까?"마침 이번 미션의 핵..
우아한테크코스 2주차 회고 '의미 있는 도전을 해보자'
·
외부 활동/우아한테크코스 8기
여러분 안녕하세요ㅎㅎ 회고록으로 찾아뵙는 건 처음인 것 같아요.사실 1주차는 이미 지나갔습니다..ㅋㅋ 여러모로 일거리가 한꺼번에 오는 바람에 타이밍을 놓쳤지만! 2주차부터 착실하게 회고를 진행해보려고 해요😅1주차 문자열 덧셈 계산기 미션이 '객체의 책임'이라는 추상적인 개념을 붙들고 씨름하는 시간이었다면, 2주차 자동차 경주 미션은 그 책임을 '어떻게 테스트 가능한 코드로 분리할 것인가'에 대한 구체적인 답을 찾는 과정이었어요.1주차에 "선 설계, 후 구현"의 힘을 어렴풋이 느꼈다면, 2주차에는 '테스트 용이성'이라는 명확한 잣대를 가지고 설계를 진행했어요. 이번에도 README.md에 기능 목록을 먼저 정의했지만, 목록을 작성하는 동시에 '이 기능을 어떻게 테스트할 것인가?'를 함께 고민했습니다.MV..
[Android] 앱을 배포해 봅시다.
·
Android
열심히 Develop 에서 코드를 짜고 QA까지 통과했다면 릴리즈를 위해서 AAB 를 추출해야겠죠?앞으로 CI/CD로 자동화까지 고려하고 있지만, 기본적인 워크 플로우를 알고있어야 자동화에 문제가 생겨도 핸들링이 가능할테니 차근차근 따라옵시다.1. release/version branch1.1 브랜치 만들기먼저 릴리즈를 위한 커밋을 하기 위해서 develop에서 release/버전명 (예: release/1.0.0) 브랜치를 생성해줍시다.이렇게 만들었다면 브랜치를 이동해주세요!1.2 Baseline Profile 생성하기최신 코드에 맞춰서 Baseline Profile도 업데이트 해줘야 앱 성능에 도움이 됩니다.먼저 빌드 변형(Build Variant)을 release로 변경해줍니다. 그 후에 Andro..
[Android] 컨벤션 플러그인 뜯어고치기
·
Android
이전 포스팅에서 멀티모듈 설계와 같이 빌드 로직을 설계했었어요. 당시에는 사용하는데에 문제가 없었고 나름 잘 설계했다고 생각했었어요. 이전 방식은(해당 포스팅) feature나 data 같은 아키텍처 레이어별로 미리 만들어둔 플러그인을 적용하는 방식이었어요. 그러나 최근에 baselineprofile처럼 특수한 모듈이 생기면서 문제가 보이기 시작했어요.baselineprofile 모듈을 추가 하면서 테스트 환경에 중복되는 설정을 줄이려고 하니 플러그인을 재사용하기 어려웠어요. 그리고 Hilt가 필요 없는 :core:designsystem 같은 모듈에도 Hilt 설정이 적용되고 있었어요. 그리고 추후에 Proto dataStore 를 적용한다고 가정했을때도 지금의 플러그인을 사용할 수 없었어요. 이번 포스..
[Android Compose] 골치덩어리 EdgeToEdge를 잘 써보자.
·
Android/Compose
시작은 불편함에서..Android 15부터 Edge-to-Edge가 기본으로 적용되면서, 이제 앱의 콘텐츠가 시스템 바 아래까지 확장되는 것이 표준이 되었어요. 덕분에 개발자들은 더 넓은 화면을 자유롭게 사용할 수 있게 되었습니다. 하지만 동시에 디자인에 맞춰 상태 바(Status Bar)의 색상을 화면과 자연스럽게 연결해야 하는 과제가 생겼어요😅저도 이 작업을 진행하면서 고민이 많았어요. 이전에는 systemuicontroller 같은 라이브러리를 사용하면 간단히 해결됐지만 Android 16(Tiramisu)부터 Deprecated 되었고, 더 근본적인 문제가 있었어요.LaunchedEffect나 DisposableEffect 안에서 시스템 바 색상을 변경하는 코드를 호출해야 했는데, 이 방식은 스..
[Android] Baseline Profile 적용기 feat. Fake 주입 실패
·
Android
안녕하세요, 오늘은 UX개선 방법중 하나인 Baseline Profile에 대해서 얘기해보려고합니다. 앱 성능 최적화는 언제나 중요한 과제인것 같아요. Lazy를 사용해서 렌더링 최적화를 하고 메모리 사용을 개선하는 등등 부드러운 UX를 제공하기 위해 저도 안드로이드 개발자로서 노력하고 있습니다.그중에서 특히 사용자가 가장 먼저 마주하는 앱 시작 속도는 전체적인 앱 경험에 큰 영향을 끼치죠. 당장 저도 로딩이 길면 화가납니다그래서 안드로이드 진영에서 성능을 최적화 할 방법중 Baseline Profile 을 도입했어요. 오늘은 Baseline Profile을 적용하면서 있었던 일을 공유해보려 합니다ㅎㅎBaseline Profile이 뭔데?Baseline Profile은 앱 설치 시 또는 백그라운드에서 자..
[Android Compose] AboutLibraries로 오픈소스 라이선스 화면을 만들기
·
Android/Compose
앱을 출시하기 전 꼭 포함해야 하는 화면 중 하나가 바로 '오픈소스 라이선스' 명시입니다. 일반적으로 가장 먼저 떠올리는 방법은 Google에서 제공하는 play-services-oss-licenses-plugin 사용하는 방식이겠죠. 저도 공식 지원인 플러그인을 적용했습니다.하지만 막상 구현하고 보니 화면이 제대로 표시되지 않았어요. 세팅하는 과정에서 뭔가 잘못했나? 싶어서 여러번 봤지만 특별하게 잘못된 부분은 없었습니다..// app/build.gradle.ktsplugins { id("com.google.android.gms.oss-licenses-plugin")}// ... dependencies// Activity 코드startActivity(Intent(this, OssLicensesMe..
[Android] 실용적인 멀티모듈 아키텍처 설계 실전기 (Domain 레이어와 build-logic)
·
Android
안녕하세요! AI가 영어 일기를 첨삭해주는 앱, 'Hilingual' 프로젝트를 진행하고 있는 안드로이드 개발자 한민재입니다."AI가 영어 일기를 첨삭해주는 앱"이라는 아이디어로 시작된 Hilingual 프로젝트는 초기 단계부터 명확한 목표를 가지고 있었어요. 바로 지속 가능한 확장성 확보와 팀 단위 개발 생산성 극대화인데요. 저희는 팀 리더의 명확한 비전과 릴리즈에 대한 강한 의지를 바탕으로, 단순한 사이드 프로젝트를 넘어 '실무에 준하는 프로덕트', '수익을 창출해도 부끄럽지 않을 프로덕트'를 만들자는 높은 목표를 세웠어요. 향후 기능 확장의 가능성이 무궁무진하다고 판단했기에, 프로젝트 규모가 커짐에 따라 발생할 수 있는 코드의 강한 결합, 긴 빌드 시간, 명확한 의존성 분리, 그리고 개발자 간의 코..
[Android Compose] @Composable 종속성을 StateFlow로 바꿔보자
·
Android/Compose
안녕하세요, Android 개발자 한민재입니다.최근 Hilingual 프로젝트의 네비게이션 로직을 리팩토링 했어요. 이번 글에서는 @Composable에 의존하던 내비게이션 상태 로직을 UI와 분리된 상태 홀더(State Holder) 패턴과 StateFlow 를 통해 개선한 과정을 상세히 공유해 보려고 합니다. (해당 작업 PR입니다.)UI와 결합된 로직리팩토링 이전, MainNavigator 클래스는 앱의 메인 화면 탐색을 관리했어요. 이 클래스는 DroidKnightsApp을 레퍼런스로 사용했던 코드에요. 그러나 최근에 해당 작업자 본인이 말하길 “땜빵코드”라 꼭 고쳐서 쓰라고 조언을 받았습니다 😅저는 그 얘기를 듣고 한참을 고민했었어요. 좋은 코드같았는데 뭐가 문제였을까? 하면서 고민한 결과 몇..
[Android Compose] flowWithLifecycle은 언제 쓰면 좋을까?
·
Android/Compose
안녕하세요! Compose로 개발하다 보면 Side Effect를 어떻게 처리할지 항상 고민인데요. 저도 ViewModel에서 발생한 이벤트를 LaunchedEffect로 받아서 스낵바를 보여주거나 화면을 전환하는 코드를 자주 작성했어요. 그런데 문득 앱이 백그라운드로 전환됐을 때 flow 수집이 중단되나? 생각이 들어서 테스트 해보니 LaunchedEffect가 계속 동작하는걸 발견했어요.이번 글에서는 제가 겪었던 문제와 flowWithLifecycle API로 해결한 경험, 그리고 이 과정에서 만든 재사용 가능한 확장 함수까지 공유해보려합니다! (해당 작업 PR 입니다)어떤 문제가 있었나요?보통 ViewModel의 단방향 이벤트(Side Effect)를 처리할 때 LaunchedEffect를 많이 사..