클린 아키텍쳐 2편 - Data Layer, Domain Layer 원리 이해하기
Data Layer
- Data Layer 에서 흔히 하는 작업은 Network request와 관련된 CRUD작업인데, 이를 위해서 Data Source를 Repository의 생성자로 받아서 Data Source의 CRUD 관련 함수를 사용한다.
Repository
- Repository class는 Data Layer의 진입점으로 생각하면 된다. 즉, UI Layer에서 바로 Data Source에 접근할 수 없도록 막아주는 것이다. 이유는 여러 가지가 있으나 UI에서는 UI와 관련된 데이터를 다루는 데 집중하도록 하는 것이다.
- 그리고 UI Layer에서 봤던 단방향 데이터 흐름에 의해 App Data가 변경되면 이를 UI Layer 즉, ViewModel에 알려 변경된 데이터가 UI에 반영되도록 하는 역할을 한다.
- 하나의 Repository는 하나의 데이터 유형을 다뤄야 한다. 예시) MovieRepository
- 하나의 Repositoy에서는 0 ~ 여러 개의 Data Source를 사용할 수 있다.
Data Source
- Remote나 Local으로 부터 app data를 받아오는 역할을 한다.
- 하나의 Data Source는 하나의 data를 다뤄야 한다.
Domain Layer
- Domain Layer는 UI Layer에서 반복되는 1) 복잡하거나 2) 간단한 비즈니스 로직이 있다면 이를 Use Case class에 담아 사용한다.
- Use Case는 하나의 action을 의미한다. 예) GetLatestNewsWithAuthorsUseCase
클린 아키텍쳐를 적용하기
요구사항 표현하기
먼저 구조를 잡기 위해 사용자 요구사항을 다음과 같이 분석해 표현했다.
- MealPageController
- 페이지컨트롤러로써, 나는 유저가 내일 또는 어제 날짜 식단 페이지로 이동시키기를 원한다.
- 페이지컨트롤러로써, 나는 유저가 캘린더에서 선택한 날짜의 식단 페이지로 이동시키기를 원한다.
- 페이지컨트롤러로써, 나는 유저가 진입한 날짜에 맞는 식단을 보여주기를 원한다.
- MealPageIndexProvider
- PageIndexProvider로써, 나는 유저가 진입한 날짜에 맞는 식단을 보여주기 위해 MealViewModel의 List
객체를 순회하며 유저가 진입한 날짜와 맞는 List 요소의 index를 반환. - PageIndexProvider로써, 나는 유저가 선택한 날짜에 맞는 식단을 보여주기 위해 MealViewModel의 List
객체를 순회하며 유저가 선택 날짜와 맞는 List 요소의 index를 반환.
- PageIndexProvider로써, 나는 유저가 진입한 날짜에 맞는 식단을 보여주기 위해 MealViewModel의 List
- PushAlarm
- 유저로써, 나는 원하는 푸시 알림을 받기 위해 알림 설정을 할 수 있기를 원한다.
- XX로써, 나는 유저에게 푸시 알림을 보내기 위해 간식 신청일과 수령일을 알기를 원한다.
- PushAlarmPreferrenceService로써,나는 유저의 푸시 알림 설정 값을 전달하기 위해 DB에서 값을 읽어오기를 원한다.
- PushAlarmPreferrenceService로써, 나는 유저의 변경된 푸시 알림 설정 값을 반영하기 위해 DB의 값을 업데이트하기를 원한다.
- PushAlarmPreferrenceLocalSource로써, 나는 유저의 푸시 알림 설정 값을 전달하기 위해 Service를 통해 값을 읽어오기를 원한다.
- PushAlarmPreferrenceLocalSource로써, 나는 변경된 유저의 푸시 알림 설정 값을 전달하기 위해 Service를 통해 값을 반영하기를 원한다.
- Meal
- 식단ViewModel로써, 나는 식단 페이지에 제공할 식단 UI 객체를 MealFragment에 넘겨주기를 원한다.
- 식단ViewModel로써, 나는 MealRepository로부터 식단 페이지에 제공할 식단 객체를 받기를 원한다.
- MealRepository로서, 나는 MealViewModel에 식단 객체를 전달하기 위해 MealRemoteSource로 부터 홈페이지에 API 요청을 하기를 원한다.
- MealRemoteSource로써, 나는 MealRepository에 식단 객체를 넘겨주기 위해 MealApi의 fetch 메서드를 호출하기를 원한다.
- MealTicket
- MealTicketUI로써, 나는 유저의 남은 식권 개수를 계산하기 위해 유저가 아침, 점심, 저녁 중 식권을 사용한 식사 시간을 알기를 원한다.
- MealTicketUI로써, 나는 이번 달 남은 식수를 계산하기 위해 유저가 오늘 사용한 식수를 MealTicketViewModel로 전달하기를 원한다.
- MealTicketUI로써, 나는 유저에게 이번 달 남은 식수를 보여주기 위해 MealTicketViewModel로 부터 남은 개수 데이터를 받기를 원한다.
- MealTicketUI로써, 나는 유저가 놓친 식수를 기입할 수 있도록 식수를 기입한 날짜와 그렇지 않은 날짜를 표시할 수 있기를 원한다.
- MealTicketUI로써, 나는 유저가 놓친 식수를 기입할 수 있도록 식수 기입을 원하는 날짜를 선택할 수 있도록 하기를 원한다.
- MealTicketViewModel로써, 나는 MealTicketUI에 이번 달 남은 식권 개수를 보내주기 위해 MealTicketRepository로부터 데이터를 받기를 원한다.
- MealTicketViewModel로써, 나는 이번 달 남은 식수를 계산하기 위해 입력한 날짜, 사용한 식사 시간 데이터를 MealTicketRepository로 보내기를 원한다.
- MealTicketRepository로써, 이번 달 남은 식수를 갱신하기 위해 현재 남은 식수와 입력한 날짜, 사용한 식사 시간 데이터를 받기를 원한다.
- MealTicket의 기본 값은 식수 유형에 따라 개수가 달라짐을 반영해야 함.
객체를 클래스, 책임, 상호작용하는 클래스로 표현하기
이런 식으로 표현해 다음과 같은 1차 결과가 나왔다.
위에서 표현된 것들을 UML Diagram의 Class로 변환하기 (진행중)
즉, class 이름과 property, method를 표현하고 접근 제한 여부를 작성할 예정이다! 이렇게 표현한 Class들을 아키텍쳐에 맞게 디렉토리 > 파일로 생성하고 원래 구현되어 있던 코드들을 수정할 예정이다!
댓글남기기