[Team 박카스] 팀 프로젝트 2022.02.08 코드 리뷰 - 3

ErroredPasta·2022년 3월 29일
0

코드리뷰

목록 보기
4/4
post-custom-banner

이번에 기능 구현을 할 때 개선한 코드들에 대해서 살펴보겠습니다.

MainViewModel에 위치 정보 LiveData 다시 추가

class MainViewModel(
    private val mapRepository: MapRepository,
    private val resourcesProvider: ResourcesProvider
) : BaseViewModel() {
    
    private val _locationData = MutableLiveData<MainState>(MainState.Uninitialized)
    val locationData: LiveData<MainState> = _locationData

    ...
}

이전에 위치 정보를 MainViewModel에서 관리하였다가 다른 화면에서 위치 정보가 필요하지만 MainViewHolder에 접근할 수 없는 경우를 위해 따로 object를 생성하여 위치 정보를 관리하도록 변경했었습니다.
하지만 다시 생각해본 결과 위치 정보를 MainViewModel에서 관리하기로 하였습니다. 그 이유는 다른 화면에서 위치 정보가 필요한 경우 Intent 등으로 넘겨 줄 수 있고, MainActivity에서 위치 권한을 관리하기 때문에 MainViewModel에서 위치 정보를 관리하는 것이 옳다고 판단하였기 때문입니다.

Base 클래스 수정

Base 클래스들의 필요없는 type parameter, method, property를 삭제하였습니다.

BaseActivity

// 변경 전
// VM type parameter 삭제 예정
abstract class BaseActivity<VM : BaseViewModel, VB : ViewBinding> : AppCompatActivity() {
    abstract val viewModel: VM // viewModel을 가지지 않을 수도 있으므로 삭제 예정

    ...

    private lateinit var fetchJob: Job // 삭제 예정

    ...

    open fun initState() {
        initViews()
        fetchJob = viewModel.fetchData() // 삭제 예정
        observeData()
    }

    ...

	// fetchJob이 항상 있다는 보장이 없으므로 삭제 예정
    override fun onDestroy() {
        if (fetchJob.isActive) {
            fetchJob.cancel()
        }
        super.onDestroy()
    }
}

위는 변경전 BaseActivity로 강제적으로 ViewModel을 갖는 것을 볼 수 있습니다. 모든 Activity에서 ViewModel이 필요하다는 보장이 없으므로(단순 화면 출력 Activity 등) 필요한 경우에만 ViewModel을 가지도록 아래와 같이 수정하였습니다.

// 변경 후
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        initState()
    }

    open fun initState() {
        initViews()
        observeData()
    }

    ...
}

BaseFragment

abstract class BaseFragment<VB: ViewBinding> : Fragment() {

    protected lateinit var binding: VB

    abstract fun getViewBinding(): VB

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = getViewBinding()
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initState()
    }

    open fun initState() {
        initViews()
        observeData()
    }

    open fun initViews() = Unit

    open fun observeData() = Unit

}

BaseActivity와 마찬가지로 ViewModel을 강제적으로 갖지 않도록 수정하고, BaseFragment의 argument를 viewModel.storeState(it)으로 저장하는 method를 현재 사용하지 않아 삭제하였습니다.

HomeMainActivity의 click listener 코드 간소화

// 변경 전
private fun setCategoryButtonListener() = with(binding) {
    val navController = findNavController()

    foodCategoryListButton.setOnClickListener {
        navController.navigate(
            HomeMainFragmentDirections
                .actionHomeMainFragmentToHomeFragment(HomeListCategory.FOOD)
        )
    }

    martCategoryListButton.setOnClickListener {
        navController.navigate(
            HomeMainFragmentDirections
                .actionHomeMainFragmentToHomeFragment(HomeListCategory.MART)
        )
    }

    ... // 다른 버튼에 대해서도 유사한 코드 반복
}

버튼별로 click listener를 설정하여 클릭을 하면 navigation을 통해 HomeFragment로 이동하도록 하였습니다. 코드를 살펴보면 넘겨주는 parameter만 다르고 나머지 부분은 동일한 것을 볼 수 있습니다. 그래서 forEachIndexed와 List를 이용하여 중복되는 코드를 줄였습니다.

private fun setCategoryButtonListener() = with(binding) {
    val navController = findNavController()
    val buttonList = listOf(
        foodCategoryListButton, martCategoryListButton, serviceCategoryListButton,
        fashionCategoryListButton, accessoryCategoryListButton, etcCategoryListButton
    )

    categories.forEachIndexed { index, homeListCategory ->
        buttonList[index].setOnClickListener {
            navController.navigate(
                HomeMainFragmentDirections
                    .actionHomeMainFragmentToHomeFragment(homeListCategory)
            )
        }
    }
}
profile
Hola, Mundo
post-custom-banner

0개의 댓글