포스트

Tuist로 확장 가능한 모듈화 하기 Part 1 - 모듈화 이해하기

서론

iOS 개발 문화가 성숙해지고 인력이 늘어남에 따라 대부분의 팀에서 모듈화를 채택하고 있습니다.

많은 사람들이 협업하고, 앱의 기능이 늘어나면서 코드 양이 방대해지면 다양한 문제가 발생합니다. 이때 복잡성을 줄이고 개발 속도를 높이며 확장성을 개선하기 위해 모듈화를 진행합니다.

그러나 일반적으로 모듈화의 이유와 목적을 제대로 고민하지 않고 단순히 트렌드라고 여기며 진행하는 경우가 많습니다.

이제부터 4개의 파트를 통해 모듈과 모듈화에 대해 알아보고, Tuist로 모듈화를 제대로 하는 방법을 살펴보겠습니다.

먼저 InnoSquad 팀에서 모듈화를 어떻게 생각하고 있는지 소개하도록 하겠습니다.


Why) 왜 모듈화를 해야하는가

증가하는 코드의 양

코드가 증가함에 따라 확장성, 가독성 및 전반적인 코드 품질이 떨어지는 경우가 많습니다. 모듈화를 통해 관심사를 분리하고 코드를 논리적 단위로 나누면 복잡성을 줄일 수 있습니다.

기능 확장성 용이

모놀리식 구조에서는 새로운 기능을 추가하거나 수정할 때 전체 코드에 영향을 줍니다. 하지만 모듈화를 하면 특정 기능을 격리시켜 변경 사항의 범위를 제한할 수 있습니다.

팀 규모 증가

여러 명이 동일한 코드베이스에서 작업하면 코드 충돌과 병합 문제가 자주 발생합니다. 모듈화를 하면 이런 문제를 회피하며 병행 작업이 수월해집니다.


모듈화의 이점

  1. 코드 재사용성 향상

    특정 기능이나 컴포넌트를 다른 프로젝트에서도 쉽게 재사용할 수 있습니다.

    개발 시간을 줄이고, 코드의 일관성을 유지하는 데 도움이 됩니다.

  2. 협업 효율성 증대

    대규모 개발 팀에서는 여러 개발자가 동시에 다양한 기능을 작업할 수 있습니다.

    서로의 작업에 덜 의존하면서 효율적으로 협업할 수 있는 환경을 조성할 수 있습니다.

  3. 엄격한 접근제어 상태 제어

    모듈을 사용하면 다른 부분에 노출할 내용을 쉽게 제어할 수 있습니다.

    공개 인터페이스를 제외한 모든 항목을 internal 또는 private으로 표시하여 모듈 외부에서 사용하지 못하도록 할 수 있습니다.

  4. 확장성

    관심사 분리 원칙에 따라 결합도를 낮추어 변경 사항의 영향 범위를 최소화 할 수 있다.

  5. 소유권

    각 모듈에 대해 코드 유지관리, 버그 수정, 테스트 추가, 변경사항 검토 등을 담당하는 전용 소유자를 둘 수 있습니다.

  6. 캡슐화

    캡슐화는 코드의 각 부분이 다른 부분에 관한 지식을 최소한으로만 갖고 있어야 함을 의미합니다. 분리된 코드가 읽고 이해하기가 더 쉽습니다.

    각 모듈은 단일 책임에 초점을 맞추어 코드를 구성하고 이해하기 쉽게 만들 수 있습니다.

  7. 테스트 용이성

    각 모듈을 독립적으로 테스트할 수 있는 환경을 제공합니다.

  8. 유지보수 용이성

    앱을 모듈로 나누면 각 부분을 독립적으로 이해하고 수정할 수 있습니다. 전체 코드뭉치를 파악하지 않고도 특정 기능을 수정하거나 업데이트할 수 있게 해, 유지보수를 훨씬 쉽게 만듭니다.

    모듈화는 코드를 작은 조각으로 나누기 때문에 특정 모듈의 수정이 전체 시스템에 미치는 영향을 최소화 할 수 있습니다.

    모듈 간 의존성이 낮아져 특정 모듈 수정 시 다른 모듈에 미치는 영향을 최소화할 수 있습니다.

  9. 빌드 시간

    모듈화된 앱은 변경 사항이 있는 모듈만 재빌드하면 되기 때문에, 전체 앱을 재빌드하는 것보다 빌드 시간을 단축할 수 있습니다.

    병렬빌드의 장점을 살릴 수 있게 된다.

  10. 모듈 활용성

    무거운 모듈을 Mock으로 대체하여 개발할 수 있다.

    전체 프로젝트를 빌드하지 않고 특정 기능 모듈만으로 샘플앱을 만들어 활용할 수 있다. (카메라앱, MyPage 앱 등)


모듈화의 단점

  • 모듈의 세분화 수준 결정의 어려움

    너무 세분화하면 빌드 복잡성, 상용구 코드 증가로 오버헤드가 발생

    너무 대략적이면 모듈이 너무 커져 모듈화 이점을 놓칠 수 있음

    예를 들어 작은 프로젝트에서는 데이터 영역을 단일 모듈 내에 넣어도 괜찮습니다. 그러나 크기가 커지면 저장소와 데이터 소스를 독립형 모듈로 분리해야 할 수 있습니다.

  • 오버엔지니어링

    불필요하게 모든 것을 모듈화하려 하면 지나치게 복잡한 시스템이 될 수 있음 (실제로는 모듈화 하지 않는게 더 단순한 해결책일 수 있음)

    프로젝트가 특정 기준점 이상으로 확장될 것 같지 않으면 확장성 및 빌드 시간 면의 이점은 누릴 수 없습니다.

  • 의존성 관리

    모듈 간 의존성이 많아지면 상호작용 이해와 조정이 어려워짐

  • 성능 저하

    모듈화는 때때로 성능 저하를 초래할 수 있습니다. 모듈 간의 통신이나 데이터 교환으로 인해 추가적인 오버헤드가 발생할 수 있음.

  • 학습 곡선

    모듈화된 시스템은 종종 더 복잡한 구조를 가지고 있기 때문에, 새로운 개발자가 프로젝트에 참여할 때 학습 곡선이 더 가팔라질 수 있습니다


What) 모듈화란 무엇인가

모듈형 프로그래밍은 프로그램의 기능을 독립적이고 교체 가능한 모듈로 분리하는 것을 강조하는 소프트웨어 설계 기법

iOS 모듈화

  • 모듈 : 소프트웨어 설계에서 기능단위로 분해하고 추상화 되어 재사용 및 공유 가능한 수준으로 만들어진 단위
    • 통상, 그 자체로 하나의 완전한 기능을 수행할 수 있는 독립된 실체
    • 앱에서 재사용하기 위한 코드 덩어리
      • iOS에서는 Library, Framework, Package 를 의미
  • 모듈화 : 소프트웨어의 성능을 향상시키고 시스템의 디버깅 / 테스트 / 통합 / 수정을 용이하도록 하는 소프트웨어 설계 기법
    • 거대한 문제를 작은 조각의 문제로 나누어 다루기 쉽도록 하는 과정


How) 그럼 어떻게 모듈을 나누어야 할까

원칙

  1. 낮은 결합력 (Loose Coupling)

    모듈이 최대한 서로 독립적이어야 한다는 의미

    한 모듈의 변경사항이 다른 모듈에 미치는 영향이 없거나 최소화되어야 합니다.

    모듈은 다른 모듈의 내부 작동 방식을 알 필요가 없습니다.

    낮은 결합도를 유지하면 모듈 간의 의존성을 줄일 수 있습니다.

    이를 통해 변경 사항을 더 쉽게 관리할 수 있고, 유지보수성과 확장성이 향상됩니다

  2. 높은 응집력 (High Cohesion)

    모듈은 맡은 일이 명확히 규정되어 있고 특정 도메인 지식의 범위를 벗어나지 않아야 합니다

    (eBook 애플리케이션에서 도서 관련 코드와 결제 관련 코드는 서로 다른 기능 도메인이므로 별도의 모듈로 분리되어야 합니다.)

    높은 응집력을 유지하면 모듈의 역할과 책임이 명확해지고, 코드의 가독성과 이해도가 높아집니다.

일반적인 모듈화 패턴

일반적으로 모듈화를 진행할 때는 아래의 세가지 방식을 적절히 활용하여 구현합니다.

  • 계층형 아키텍쳐

    데이터, 비즈니스 로직 및 프레젠테이션과 같은 별개의 계층으로 관심사를 분리합니다.

  • Feature 모듈

    관련 기능을 Feature-Specific Module로 그룹화합니다

  • Core 모듈

    애플리케이션 전반에서 사용되는 공유 유틸리티 및 구성 요소를 제공하는 중앙 모듈입니다.

하나하나 조금더 자세히 알아보도록 하겠습니다.

Data Module

일반적으로 repository, datasource, model 이 포함되어있습니다.

데이터 모듈의 주된 역할은 다음과 같습니다.

  1. 특정 도메인의 모든 데이터 및 비즈니스 로직 캡슐화

    각 데이터 모듈은 특정 도메인을 나타내는 데이터를 처리해야 합니다. 관련이 있는 데이터라면 다양한 유형의 데이터를 처리할 수 있습니다.

  2. 저장소를 외부 API로 노출

    데이터 모듈의 공개 API는 데이터를 앱의 나머지 부분에 노출하는 일을 담당하기 때문에 repository여야 합니다.

  3. 외부로부터 모든 구현 세부정보 및 데이터 소스 숨기기

    데이터 소스는 같은 모듈의 repository에서만 액세스 가능해야 합니다. 외부에는 공개되지 않습니다.

Feature Module

기능은 일반적으로 화면 또는 밀접하게 관련된 일련의 화면(예: 가입 또는 결제 흐름)에 해당하는 독립적인 앱 기능을 의미합니다.

기능은 앱의 화면 또는 대상과 연결됩니다. 따라서 로직과 상태를 처리하기 위한 UI와 ViewModel이 연결될 가능성이 높습니다. 단일 기능이 단일 보기나 단일 탐색 대상으로 제한될 필요는 없습니다. 

기능 모듈은 데이터 모듈에 종속됩니다.

App Module

앱 모듈은 애플리케이션의 진입점입니다.

앱 모듈은 기능 모듈에 종속되며 일반적으로 루트 탐색을 제공합니다. 

Build Configuration을 통해 단일 앱 모듈을 다양한 바이너리로 컴파일할 수 있습니다.

Core Module

다른 모듈에서 자주 사용하는 코드가 포함됩니다.

중복성을 줄이는 역할을 하며, 앱 아키텍처의 특정 레이어를 나타내지는 않습니다.

  • UI 모듈

    앱에서 맞춤 UI 요소를 사용하거나 정교한 브랜딩을 사용하는 경우 모든 기능을 재사용할 수 있도록 위젯 컬렉션을 하나의 모듈로 캡슐화하는 것이 좋습니다. 이렇게 하면 서로 다른 기능에서 UI를 일관되게 만들 수 있습니다. 예를 들어 테마 설정이 일원화되어 있다면 리브랜딩이 발생할 때 골치 아픈 리팩터링 작업을 피할 수 있습니다.

  • 애널리틱스 모듈

    일반적으로 추적은 소프트웨어 아키텍처에 대한 고려 없이 비즈니스 요구사항에 따라 정해집니다. 애널리틱스 추적기를 서로 관련 없는 여러 구성요소에 사용하는 경우가 많으며, 이 경우 전용 애널리틱스 모듈을 사용하는 것이 좋습니다.

  • 네트워크 모듈

    많은 모듈에 네트워크 연결이 필요한 경우 http 클라이언트 제공 전용 모듈을 사용하는 것이 좋습니다. 이는 클라이언트에 맞춤 구성이 필요할 때 특히 유용합니다.

  • 유틸리티 모듈

    도우미라고도 하는 유틸리티는 일반적으로 애플리케이션 전체에서 재사용되는 작은 코드입니다. 유틸리티의 예로는 테스트 도우미, 통화 형식 지정 함수, 이메일 검사기 또는 맞춤 연산자가 있습니다.


결론

왜 모듈화를 해야하는지.

모듈화 라는게 무엇인지.

어떤방식으로 모듈화를 해야하는지.

InnoSquad iOS 팀에서 다시 한번 정리하고 갈 수 있는 소중한 시간이었습니다.

다음에는 Tuist를 통해서 기본적이고 기초적인 모듈화 방식에 대해 알아보겠습니다.


참고링크

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.