모듈레벨에서 개념을 정리
모놀리틱 구조에서 모듈화로 바꿧을때 장점은?
모노리틱 구조 특징
- 단일 타겟(모듈)
- 객체 간 무분별한 참조
더보기
- 서로 참조하는 순환 참조가 자주 발생하게됨 -> 단독으로 사용 불가능 하면 결국 여러 객체가 거대한 하나의 객체처럼 동작
- public과 internal 접근 제어를 구분할 수 없는게 가장 크다 > 복잡한 기능은 여러 객체로 이루어진 경우가 많지만 사용자에게는 하나의 객체만 노출하고 싶음 > 모든 연관 객체를 한 파일에 넣고 숨길 객체만 private class로 하지 않는이상 객체를 숨길 수 없음
- 코드 변경의 영향 범위 파악이 힘듦
더보기
- 작은 코드의 수정이 어디까지 영향을 미칠지 알 수 없음
- 작은 리펙토링, 기능 추가, 수정 등에서 컴파일 애러가 끝없이 나오거나 버그가 발생
- 빌드 시간에 따른 생산성 저하
더보기
- 아주 작은 변경도 프로젝트 컴파일을 모두 해야 함
- 성장하는 팀, 성장하는 앱에는 지속 가능한 구조가 아님
모듈화 구조 (계층화)
객체가 커지면 리펙토링을 해서 객체를 쪼개고 싶어하듯이 모듈화도 마찬가지이다. 모듈도 커지면 다시 나눠야 한다. 그리고 잘 나뉜 모듈은 계층화가 가능하다.
상위 모듈은 하위 모듈에 접근 가능하지만 그 반대는 불가능하도록 설계하는게 좋다. (단방향: 순환참조가 없다)
상위모듈과 하위모듈을 나누는 방식은 크게 두가지가 있다.
1. 로직 레벨에서 나눈다 (1부 실습 해오던 방식)
지난 실습의 데이터 방향은 항상 단방향 이었다. (반대로 흐를 수 없다)
리포지토리, 데이터 스트림 -> 인터렉터 (리포지토리는 직접적으로 인터렉터와 아무 연관이 없다, 단방향)
인터렉터 -> UI 업데이트 (UI 업데이트를 하는 뷰컨트롤러도 인터렉터와 직접 연관이 없다, 단방향)
ㄴ 대신 뷰 컨트롤러가 인터렉터에 데이터를 전달 할 때는 Listener를 통해 하기 때문에 인터렉터를 직접 호출하는것이 아니다.
마찬가지로 레포지토리는 보통 네트워킹을 이용하여 데이터에 접근한다. 네트워킹 코드가 리포지토리를 아는 경우는 없다.
인터렉터는 상위모듈
레포지토리나 UI는 중위 모듈
네트워킹 (URL Session, Alamofire), Sqlite는 하위모듈
2. UX적으로 화면의 플로우로 분리
최상위 AppDelegate
처음에 가장 가까운 화면은 상위모듈
첫번째 화면에서 다시 접근 가능한 화면은 중위 모듈
하위모듈은 중위 모듈에서 다시 접근 가능한 화면
예를들자면 AppRoot가 상위 모듈, AppHome, FinanceHome, ProfileHome는 중위모듈, 카드 충전 및 나머지 모듈은 하위모듈
어떤 측면에서 접근하던 데이터는 단방향을 유지해야 한다
모노리틱 구조에서 확인 한 문제들을 대부분 해결 가능하다. 노출하고 싶지 않은 객체는 Internal로 숨기고 무분별한 참조를 막는다.
외부 참조가 끊겨있으니 코드 변경의 영향이 모듈 내부만 발생한다.
모듈화 장점
- 관심사 분리
- 코드 파악이 빨라진다
지금까지 실습 내용은 모듈로 나뉘어 있지는 않지만 상위 리블렛과 하위 리블렛이 계층화 되어있고 레포지토리-인터렉터-UI 참조가 모두 단방향이다. 사실상 분리시켜두어서 모듈화 실습시에 비교적 간단하게 모듈로 만들어진다.
ribs를 사용한것만으로도 자연스럽게 이런 구조가 잡혔다.
ribs는 모듈화나 테스트 작성을 경험해본적 없는 개발자에게도 좋은 시작점이다.
모듈화가 빌드 시간에 미치는 영향은 아직 이야기 하지도 않았지만 지금까지의 장점만 보더라도 모듈화는 매우 필수적이다.