Skip to content

refactor: 6주차 제로#45

Open
jeongkyueun wants to merge 5 commits into
mainfrom
zero-m6
Open

refactor: 6주차 제로#45
jeongkyueun wants to merge 5 commits into
mainfrom
zero-m6

Conversation

@jeongkyueun
Copy link
Copy Markdown
Collaborator

@jeongkyueun jeongkyueun commented May 6, 2026

📌refactor: 6주차 미션_제로

기존의 MVC 형태의 코드를 안드로이드 권장 아키텍처인 MVVM(Model-View-ViewModel)으로 변환하고, Hilt를 사용하여 의존성 주입을 구현했습니다.

🔗 관련 이슈

Closes #42

✨ 변경 사항

  1. Hilt 의존성 주입 설정
  • libs.versions.toml 및 build.gradle.kts에 Hilt 라이브러리 추가
  • HiltAndroidApp을 적용한 Week2Application 생성 및 Manifest 등록
  • di 패키지에 NetworkModule, DataModule을 생성하여 Retrofit 및 DataStore 객체 주입 설정
  1. Repository 계층 생성
  • LocalRepository (ProductRepository): DataStoreManager를 사용하여 로컬 데이터(상품 리스트, 위시리스트 상태) 관리
  • RemoteRepository (UserRepository): ReqResService를 사용하여 서버 API 호출 관리
  1. ViewModel 도입
  • 각 화면(Home, Wishlist, Profile, AllProducts, ProductDetail)에 대응하는 ViewModel 생성
  • Fragment에 집중되어 있던 데이터 처리 및 상태 관리 로직을 ViewModel로 이동
  1. Fragment 및 UI 로직 수정
  • @androidentrypoint를 적용하여 ViewModel 주입
  • 관찰 가능한 데이터(Flow, LiveData)를 사용하여 데이터 변경 시 UI가 자동 업데이트되도록 구현

🔍 테스트

  • 테스트 완료
  • 에러 없음
  • Hilt 설정 완료 및 의존성 주입 적용
  • Local/Remote Repository 분리 및 구현
  • 화면별 ViewModel 생성 완료
  • Fragment와 ViewModel 간의 데이터 바인딩/관찰 로직 연결
  • 기존 기능(상품 목록, 위시리스트 토글, 프로필 조회) 정상 작동 확인

📸 스크린샷 (선택)

마이페이지
Screenshot_20260429_041808

🚨 추가 이슈

@jeongkyueun jeongkyueun self-assigned this May 6, 2026
@jeongkyueun jeongkyueun added the enhancement New feature or request label May 6, 2026
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=b266d5ff6b90eada6dc3b20cb090e3731302e553a27c5d3e4df1f0d76beaff06
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 버전은 작동 잘 되나보네요! 굿굿

@@ -1,4 +1,4 @@
package com.example.week1
package com.example.week2
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

데이터 처리 로직을 ViewModel로 이동하는 방식이 깔끔하다

Comment on lines +1 to +21
package com.example.week2.di

import android.content.Context
import com.example.week2.DataStoreManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object DataModule {

@Provides
@Singleton
fun provideDataStoreManager(@ApplicationContext context: Context): DataStoreManager {
return DataStoreManager(context)
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구조 깔끔하게 정리 잘하시는거 같아요!

@kimdoyeon1234 kimdoyeon1234 changed the title refactor: 6주차 미션_제로 refactor: 6주차 제로 May 6, 2026
Copy link
Copy Markdown
Collaborator

@kimdoyeon1234 kimdoyeon1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!!

이번 코드는 화면별로 HomeViewModel, ProfileViewModel, AllProductsViewModel,
WishlistViewModel을 분리한 점, repository 패키지를 따로 만들어 ProductRepository와 UserRepository를 나눈 점, 그리고 FollowingAdapter에 DiffUtil을 적용한 점이 정말 좋았어요!

다만 이번 미션의 핵심은 패키지 분리입니다! 현재 Fragment, Model, DataStoreManager, ReqResService 등 대부분의 파일이 루트 패키지(com.example.week2)에 몰려있어요.
data/model/, data/repository/, domain/repository/, di/, ui/home/, ui/profile/, ui/purchase/, ui/wish/ 처럼 역할에 맞게 패키지를 나눠주세요 !

추가로 Hilt를 도입했는데 ApiClient object가 아직 남아있으니 삭제해주시고,
ProductAdapter도 notifyDataSetChanged() 대신 ListAdapter + DiffUtil로
교체해주시면 훨씬 완성도 있는 코드가 될 것 같아요!

전반적으로 ViewModel 분리와 Repository 구조는 잘 잡으셨으니
패키지 구조만 다듬어주시면 더욱 좋아질 것 같습니다. 고생 많으셨어요! 😊

Comment on lines +6 to +15
object ApiClient {
private const val BASE_URL = "https://reqres.in/"

private val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NetworkModule에서 이미 Retrofit을 Hilt로 제공하고 있는데 ApiClient object가 별도로 남아있어요!
Hilt를 도입했다면 ApiClient는 삭제하고 NetworkModule만 사용해주세요 !

Comment on lines +14 to +18
fun updateList(newProducts: List<Product>) {
this.products = newProducts
notifyDataSetChanged()
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notifyDataSetChanged()는 전체 목록을 다시 그려서 성능이 좋지 않아요! 이전에 말한것처럼 ListAdapter + DiffUtil을 사용하면 변경된 항목만 업데이트해서 훨씬 효율적으로 동작합니다

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번 미션의 핵심은 패키지 분리입니다! 모델 클래스들은 data/model/, DataStoreManager는 data/, ReqResService는 data/ 패키지로 이동시켜주세요! Models.kt, Product.kt, DataStoreManager.kt, ReqResService.kt 이것들!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repository 패키지를 만들어서 분리한 점 아주 좋아요!! 다만 domain/repository/에 interface를 선언하고 data/repository/에 구현체를 두는 구조로 분리하면 더 완성도 있는 코드가 됩니다!

Comment on lines +60 to +65

Glide.with(this@ProfileFragment)
.load(it.avatar)
.circleCrop()
.into(binding.ivProfileImg)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미지 로딩을 ProfileBindingAdapters.kt처럼 BindingAdapter로 분리하면 Fragment 코드가 더 깔끔해져요 !

Comment on lines +68 to +72
viewModel.followingList.observe(viewLifecycleOwner) { users ->
followingAdapter.submitList(users)
binding.tvFollowingTitle.text = "팔로잉 (${users.size})"
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"팔로잉 (${users.size})" 같은 팔로잉 수 계산은 비즈니스 로직에 가까운거 같습니다! ViewModel에서 처리하고 Fragment는 결과만 받아서 보여주는 방식으로 바꾸는것도 좋을거 같아요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 6주차 미션_제로

5 participants