[Android] BaseActivity와 BaseFragment

이유정·2021년 8월 20일
1
post-thumbnail

1. BaseActivity & BaseFragment...?! _ 장단점 정리

  • 간단히 말하자면, "코드의 중복을 줄이고 가독성을 높이기 위해"서 프로젝트의 뼈대로 사용되는 클래스이다.
  • 보통 binding이나 그 외 여러 activity/fragment 걸처 공통적으로 수행하는 코드에 대하여 초기화나 이벤트 등을 정리해둠으로서 나중에 다른 activity/fragment에서 이를 상속하여 사용한다.

  • 단점 / 주의할 점 : 반드시 필요한 부분만, 최소한으로, 잘 생각해서 설계하자.
    • Base부분에 data binding을 위한 부분이 있다고 하였을 때, 이를 이용할 경우 binding을 정의하는 부분의 코드가 줄어들고, 가독성도 높아진다.
      하지만 이는 극단적인 예로 splash나 혹은 정말 간단하게 특정 요소만 보여주는 액티비티에는 필요하지 않다.
      ( 그 외에도 몇개가 만들어질지 모르는 변수들(ex : viewmodel)은 base 부분에 넣지 않는 것을 추천한다.)

    • 또한 공통적인 코드라고 무조건 Base에 넣는 것은 좋은 코드라고 할 수 없다. 이럴 경우 차라리 Util 관련 클래스를 만들어 따로 빼서 쓰는 것이 더 이상적일 것이다.
    • 상속받는 Base가 너무 뚱뚱해질(?) 경우, 모든 activity에는 필요하지 않는 것들이 추가될 가능성이 높고, 이것들은 결국 추후 수정될 가능성이 매우 높다. 하지만 어느 정도 구현이된 프로젝트에서 base를 수정하는 것은 너무 부담이 크다.

    • 요는 처음부터 반드시 필요한 부분만 잘 설계하는 것이 베스트라는 것이다.

      +)) lifecycle을 꼭 지키도록 설계하자. 어설프게 설계할 경우 당장은 잘 돌아가러다도 나중에 문제가 생길 수도 있고, 혹은 메모리가 누수되는 나쁜 코드일 수 있다...

2. 예시 코드

아래는 내가 작성한 코드이다. 이는 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이라는 것도 있는 듯...? 추가로 알아보기로 하자.

3. 마무리

뭐든 그렇지만, 적절한 곳에 잘 사용하는 것이 가장 좋은 방법이다.
나열하다보니 장점에 비해 주의할 점을 꽤 길게 쓴 것 같지만, 코드의 중복이 줄어드는 것은 매우 매력적이라고 생각한다.
잘 판단해서 쓰자!

profile
개인 공부 블로그

0개의 댓글