Skip to content

UI Data 패키지 구조 변경

토마스 edited this page Sep 14, 2023 · 5 revisions

프로젝트 구조 변경에 대한 문서입니다.

UI / Data 패키지 구조 변경 논의에 기반하여 부나에 의해 작성되었습니다.

Data 패키지

이후 API 통신 구현시 참고해주세요!

도메인형 구조에서 계층형 구조로 변경하였습니다.

  • 깊이가 깊어지고 프로젝트 규모가 커지면서 통일성이 없어지는 문제를 해결하였습니다.
// Before : 도메인형 구조
- data
  - comment
    - dto
      - CommentUpdateRequestBody.kt
      - CommentDeleteRequestBody.kt
      - CommentCreateRequestBody.kt
      ...
    - mapper
      - CommentMapper.kt
    - CommentService.kt
    - CommentRepository.kt
    - CommentRepositoryImpl.kt
  ...
  - recruitment
  - member
  ...

// After : 계층형 구조
- data
  - apiModel
    - request
      - FooRequest.kt (FooService에서 다루는 Requests)
      - BooRequest.kt
      ...
    - response
      - FooResponse.kt (FooService에서 다루는 Responses)
      - BooResponse.kt
      ...
  - model
  - service
  - dataSource
    - remote
    - local

Request/Response API 클래스 끝에 Body suffix를 제거하였습니다.

// Before
class FooCreateRequestBody(...)

// After
class FooCreateRequest(...)

관련된 Request/Response끼리 한 파일에서 관리하도록 변경하였습니다.

// Before
class FooCreateRequest.kt
class FooDeleteRequest.kt
class FooUpdateRequest.kt

// After
FooRequest.kt
- data class FooCreateRequest(...) // in FooRequest.kt
- data class FooDeleteRequest(...) // in FooRequest.kt
- data class FooUpdateRequest(...) // in FooRequest.kt

CRUD에 따라 Request 클래스에 이름을 붙이도록 통일하였습니다.

  • CREATE : XxxCreateRequest
  • READ : XxxGetRequest
  • UPDATE : XxxUpdateRequest
  • DELETE : XxxDeleteRequest

통일성을 위해 호스트 뒤에 이어지는 경로가 /로 시작하도록 변경하였습니다.

// Before
@POST("reports")
suspend fun reportComment(...)

// After
@POST("/reports")
suspend fun reportComment(...)

가독성을 높이기 위해 요청에 필요한 파라미터를 한 줄에 표현하지 않고, 한 줄씩 띄도록 변경하였습니다.

// Before
@DELETE("/comments/{commentId}")
suspend fun deleteComment(@Path("commentId") commentId: Long): Response<Unit>

// After
@DELETE("/comments/{commentId}")
suspend fun deleteComment(
    @Path("commentId") commentId: Long,
): Response<Unit>

분업을 하면서 발생한 여러개의 중복 Service, Repository를 하나로 통합하였습니다.

e.g.EventServiceDetail.kt의 메서드를 EventService.kt로 통합

// Before
// EventServiceDetail.kt
interface EventDetailService {
    @GET("/events/{eventId}")
    suspend fun getEventDetail(
        @Path("eventId") eventId: Long,
    ): ApiResponse<EventDetailResponse>
}

// After (EventDetailService에 있던 메서드를 EventService로 이동)
// EventService.kt
interface EventService {
    @GET("/events/{eventId}")
    suspend fun getEventDetail(
        @Path("eventId") eventId: Long,
    ): ApiResponse<EventDetailResponse>
   
    ...

    @GET("/events")
    suspend fun getConferences(
        @Query("category") category: String,
        @Query("statuses") statuses: List<String> = emptyList(),
        @Query("tags") tags: List<String> = emptyList(),
        @Query("start_date") startDate: String? = null,
        @Query("end_date") endDate: String? = null,
    ): Response<List<ConferenceResponse>> 
}


Presentation 패키지

깊은 Depth를 피하고자 최대 2 Detph까지 허용하는 구조로 변경하였습니다.

  • 부모의 ViewModel을 공유하는 자식 화면만 2 Depth를 허용합니다.
    • ex) OnboardingActivity의 OnboardingJobFragment, OnboardingNameFragment, OnboardingClubFragment
  • 그 외에는 1 Depth를 유지합니다.
  • 깊이가 깊어지면서 프로젝트를 파악하기 어려운 문제를 해결하였습니다.
// Before : 관련 있는 화면을 패키지 안에 중첩해서 추가하다보니, 원하는 화면 클래스를 찾기 어려운 문제 발생!
- ui
  - main (1 depth)
    + eventList (2 depth)
      * conference (3 depth) 😡
        - conferenceListActivity.kt
        - conferenceListViewModel.kt
      * conferenceFilter
        - conferenceFilterActivity.kt
        - conferenceFilterViewModel.kt
      * competition
        - ...
      * competitionFilter
        - ...
      ...
    - 

// After
- ui
  - main
  - profile
  - eventList
  - setting
  - conferenceFilter
  - onboarding (1 depth)
    + OnboardingActivity.kt
    + OnboardingViewModel.kt
    + NameOnboarding (2 depth) 👍 // OnboardingActivity와 ViewModel 공유
    + JobOnboarding (2 depth) 👍 // OnboardingActivity와 ViewModel 공유
    + ActivityOnboarding (2 depth) 👍 // OnboardingActivity와 ViewModel 공유
  ...


목록을 보여주는 화면은 s(영어의 복수형) 대신에 List를 붙여 명명하도록 변경하였습니다.

  • 패키지 글자 크기가 작아 s까지 자세히 보지 않고도 파악할 수 있습니다.

ex) events 패키지 -> eventList 패키지

여러 화면을 담기만 하는 화면의 이름은 xxxPageList로 명명하도록 했습니다.

  • 더 나은 이름이 떠오르면 추후에 변경하겠습니다.

이후 수정이 필요란 경우 Discussion 또는 Slack을 통해 의견을 남겨주세요 😀

Clone this wiki locally