- Base부분에 data binding을 위한 부분이 있다고 하였을 때, 이를 이용할 경우 binding을 정의하는 부분의 코드가 줄어들고, 가독성도 높아진다.
하지만 이는 극단적인 예로 splash나 혹은 정말 간단하게 특정 요소만 보여주는 액티비티에는 필요하지 않다.
( 그 외에도 몇개가 만들어질지 모르는 변수들(ex : viewmodel)은 base 부분에 넣지 않는 것을 추천한다.)
- 또한 공통적인 코드라고 무조건 Base에 넣는 것은 좋은 코드라고 할 수 없다. 이럴 경우 차라리 Util 관련 클래스를 만들어 따로 빼서 쓰는 것이 더 이상적일 것이다.
- 상속받는 Base가 너무 뚱뚱해질(?) 경우, 모든 activity에는 필요하지 않는 것들이 추가될 가능성이 높고, 이것들은 결국 추후 수정될 가능성이 매우 높다. 하지만 어느 정도 구현이된 프로젝트에서 base를 수정하는 것은 너무 부담이 크다.
- 요는 처음부터 반드시 필요한 부분만 잘 설계하는 것이 베스트라는 것이다.
+)) lifecycle을 꼭 지키도록 설계하자. 어설프게 설계할 경우 당장은 잘 돌아가러다도 나중에 문제가 생길 수도 있고, 혹은 메모리가 누수되는 나쁜 코드일 수 있다...
아래는 내가 작성한 코드이다. 이는 data binding만을 위한 클래스이다.
+) data binding만을 위한 클래스인데 BaseActivity라는 이름이 좋을까라는 의견을 들었다. 클래스의 이름을 명확하게 하기 위해 BindActivity로 이름을 명명하는 것도 좋을 것 같다.
BaseActivity.kt
abstract class BaseActivity<T : ViewDataBinding>(@LayoutRes private val layoutResId: Int) : AppCompatActivity() {
lateinit var binding : T
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutResId)
}
}
BaseFragment.kt
abstract class BaseFragment<T : ViewDataBinding>(@LayoutRes private val layoutResId : Int) : Fragment() {
private var _binding : T? = null
val binding get() = _binding ?: error("View를 참조하기 위해 binding이 초기화되지 않았습니다.")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
++ baseActivity, baseFragment 외에도 baseViewmodel이라는 것도 있는 듯...? 추가로 알아보기로 하자.
뭐든 그렇지만, 적절한 곳에 잘 사용하는 것이 가장 좋은 방법이다.
나열하다보니 장점에 비해 주의할 점을 꽤 길게 쓴 것 같지만, 코드의 중복이 줄어드는 것은 매우 매력적이라고 생각한다.
잘 판단해서 쓰자!