----------
코드에서 두 클래스간의 연결 혹은 관계를 말합니다.
클래스 A가 다른 클래스 B를 이용할 때 A가 B에 의존한다고 말할 수 있죠.
위 사진을 보면 LoginActivity가 LogInViewModel에 의존하는 화살표의 모습을 보실 수 있습니다.
우리는 이렇게 계층을 분리하고 유지보수나 메모리 누수 방지 등을 위해 의존성을 활용합니다.
----------
좀 더 쉽게 알아볼까요?
저희는 김치찌개, 김치전을 만들기 위해 김치를 활용합니다!
김치찌개와 김치전은 김치에 의존한다고 볼 수 있죠?
하지만 된장찌개의 경우는 어떨까요? 의존이 불가능하죠?
이렇게 의존이 어려운데, 이미 김치가 들어가버린다면?
저희는 그걸 하나하나 건져야합니다~~
만약 고추에 의존한다면?
훨씬 범용적으로 변했죠?! 이런식으로 의존하는 모습을 볼 수 있습니다.
이에 대해 좀 더 깊게 다뤄볼까 하는데요~~
----------
Activity에서 Binding과 같이 중복되는 코드가 꽤 있습니다.
이러한 부분들을 편하게 사용하기 위해 확장 액티비티를 두는 방식입니다.
사용하는 방법부터 알아볼까요?
우선 아래와 같이 BaseActivity를 작성해 줍시다.
늘 사용하는 binding을 자연스럽게 붙여줍니다.
abstract class BaseActivity<B : ViewDataBinding>(
@LayoutRes private val layoutResId: Int,
) : AppCompatActivity() {
private var _binding: B? = null
val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = DataBindingUtil.setContentView(this, layoutResId)
}
}
저는 거의 binding의 역할만 한다고 생각해서
추상 클래스명을 BaseActivity로 명명하였습니다.
평상시에 사용하는 MainActivity를 보면 AppCompatActivity를 볼 수 있죠?
평상시와 같이 binding도 늘 하던 것처럼 자연스럽게 초기화를 진행해줍니다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setBottomNavigationView()
}
하지만 BaseActivity를 사용하는 이유가 뭐라고 했는지 기억 나시나요?
바로 중복되는 코드를 줄여주기 위해서입니다.
아래와 같이 BaseActivity로 선언해주시고 <>안에 바인딩을 대신 넣어줍니다.
괄호 안에 레이아웃이 가진 id를 함께 기입합니다.
class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setBottomNavigationView()
}
이런식으로 코드가 짧아진 모습을 볼 수 있습니다.
BindingFragment또한 아래와 같이 간단히 사용할 수 있습니다.
abstract class BindingFragment<B : ViewDataBinding>(
@LayoutRes private val layoutResId: Int,
) : Fragment() {
private var _binding: B? = null
val binding get() = _binding ?: error("error: binding is null")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
----------
하지만 저희가 사용하는 Activity는 BaseActivity를 활용함으로써 의존이란 것을 하게 됩니다.
만약 BaseActivity에 추가되었으면 하는 공통 코드가 많아진다면,
이렇게 많은 기능을 하는 만능(?) BaseActivity가 만들어지겠죠?
이는 과연 좋을 것인지 생각해봐야 합니다.
이러한 문제들이 있음에도~
실제로 Boilerplate Code가 될 수 있으니 BindingActivity 정도는 충분히 쓸만합니다!!
대신 다른 기능을 추가할 때는? 무작정 추가하지 않고 경계를 할 필요가 있다고 볼 수 있습니다.
----------
그렇다면 어떻게 해야 하느냐?
이럴 때는 확장함수를 이용할 수도 있습니다.
확장함수를 통해 재사용되는 코드를 줄이는 것입니다.
But, 이 또한 의존도를 증가시키는 일이기에 다시 한 번 생각해볼 필요가 있습니다~~
이에 대해 정리된 글이 있으니 읽어보셔도 좋을듯합니다 🤭