Android MVP를 작성하는데 있어서 Package 구조를 어떻게 가져가면 좋을지 고민을 할 수밖에 없습니다.

딱히 정해지거나, 어떤게 좋은지 사실 저도 알지는 못합니다.

하지만 지금까지 MVP를 작성하면서 가장 괜찮은 방식의 패키지 구조를 사용하고 있다고 생각되어 이를 정리해보려고 합니다.


가장 초기에 많이 하던 구조

다음과 같은 구조를 지금까지 가장 많이 본 것 같습니다.

  • com.example.appname
    • activity
      • 액티비티 들을 모두 모아 둠
    • fragment
      • 프래그먼트 들을 모두 모아 둠
    • adapter
      • Adapter와 관련한 모든 class 모음
    • util
      • Util과 관련한 class 모음

위를 도식화하면 다음과 같습니다.

package_structure_01

위와 같은 것들인대 직접 생성하면 아래와 같을 것 같습니다.

임의로 추가하여 아래와 같습니다.

default_package_structure

위에서 정의한 그대로 한번 정리해보았습니다.

HomeActivity와 관련한 HomeFragment/HomeDetailFragment를 찾고, MainAdapter를 찾기 위해서는 패키지를 3곳을 열어야 이를 모두 확인 가능하고, 거기에서도 한번 더 찾아야 합니다.

클래스 이름을 잘 만들었다면 찾기는 더 쉽겠지만 그렇지 않고

HomeActivity안에 포함해야 할 클래스가 AFragment/BFragment와 같은 경우에는 또 찾기 힘듭니다.


저는 위와 같은 구조를 가장 많이 보았고, 장/단점을 정리해보면

장점

  • 초기에는 구조 파악이 쉽다
  • 누구나 알 수 있는 구조(activity/fragment 등의 집합)


단점

  • 초기를 지나는 순간 파악하기 힘들어진다.
    • 파일의 양 증가로 인해 발생
    • 최소 2곳, 많게는 3곳 이상의 패키지를 열거나 이동해야 한다
  • 컴퍼넌트 구조라서 모아두는 장점은 있으나, 화면 단위로 파악하기 힘들다


빠르게 이동하려면

  • Android Studio에서는 double shift를 통해 빠르게 검색하는게 더 빠르다
    • 이는 장점은 아니지만 패키지를 열어서 찾는 것보다는 이게 빠릅니다.


MVP/MVVM을 추가하면서

우선 위에서 정의한 구조에서 MVP/MVVM을 넘어간다면 다음과 같은 형태로 만들 수 있을 것 같습니다.

  • com.example.appname
    • presenter
      • Presenter를 모아두기 위한 패키지를 추가
    • activity
      • 액티비티 들을 모두 모아 둠
    • fragment
      • 프래그먼트 들을 모두 모아 둠
    • adapter
      • Adapter와 관련한 모든 class 모음
    • util
      • Util과 관련한 class 모음

위를 도식화하면 다음과 같습니다.

package_structure_02

우선 가장 쉽게 접근하려면 presenter 패키지를 추가합니다.

이를 추가하지만 이렇게 한다고 해서 기존에 제가 생각했던 장/단점은 그대로 유지 상태입니다.

그래서 크게 차이가 없죠.


더 나은 구조는?

이런 구조화 방식은 개발 방법론과도 엮일 수 있습니다.

우선은 저의 경우 다음과 같은 구조를 사용하고 있습니다.

  • com.example.appname
    • adapter
      • 공용으로 사용할 adapter 정의
    • data
    • view
      • 여기에서의 View에는 adapter/presenter(view_model)/Activity/Fragment 등을 모두 모아둔다
    • util
      • 기존과 동일

위를 도식화하면 다음과 같습니다.

package_structure_03

Android Studio에서 아래와 같이 확인 가능합니다.

mvp_package_structure

제가 가장 중요하다고 생각되는 부분이고, 추천하고 싶은 접근 방법입니다.

해당하는 View(화면 단위) 안에 동일한 Activity/Fragment/Presenter/Adapter 등을 모두 모아둡니다.

그리고 공용으로 사용하는 경우는 외부에 따로 두고요.

  • view
    • 여기에서의 View에는 adapter/presenter(view_model)/Activity/Fragment 등을 모두 모아둔다

mvp_package_structure_view

바로 위와 같은 방법입니다. adapter도 필요하면 한 번에 모아둡니다.


View 들을 모아 둠으로써 얻는 장/단점

장점

  • View 안에 해당 화면의 이름으로 Package 생성하면, 해당 화면 관련 내용을 한눈에 파악 가능
  • 패키지 이동을 하지 않고도, 필요한 class를 빠르게 접근 가능
    • double shift를 이용할 수도 있지만…
  • 그만큼 개발 속도가 빨라집니다.


단점

  • 생각을 좀 많이 해야 합니다.
    • 해당 패키지 안에 있지만 다른 화면에서도 쓰일 수 있는지를 고민해야 합니다.
      • 나중에 이동이 가능하긴 하지만 손이 가니깐 귀찮을 수 있습니다.
  • 폴더가 많아진다
    • 동일한 이름의 폴더들이 증가합니다.


마무리

MVP/MVVM을 하면서 위와 같은 패키지 구조를 생각해보았습니다.

하지만 이는 MVC를 한다고 해서 달라질 건 없습니다.

저는 오히려 이런 방법으로 Package를 정리하고, 이를 통해 얻는 이득이 더 많았습니다.

동일한 컴포넌트의 묶음을 해두더라도 단점은 없지만. 초기 이후에는 찾기도 힘들고, 검색하거나, 해당 클래스에서 미리 파악하는 형태를 취하는게 더 빠릅니다.

처음 보는 사람도 components는 이해하기 쉽지만 실제 화면을 찾아가기란 쉽지 않으니깐요.

또한 나중에 클래스 삭제할 때도 위와 같이 해두면 Package를 한 번에 날리는 장점이 있지만 기존은 각각을 다 찾아서 사용하는지 하지 않는지를 체크하거나, lint를 돌려서 이를 해결할 수 있습니다.

저는 근 8개월 정도를 이러한 구조로 사용하고 있지만 기존 보다 파악하기 쉽고, 필요한 클래스와 불필요한 클래스를 빠르게 정리할 수 있는 장점을 모두 가진 괜찮은 방법이라고 생각됩니다.

감사합니다.


Tae-hwan

Android, Kotlin .. Create a content development.