멀티 모듈을 활용한 플러터 클린아키텍처 정리

원문: [2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_임태규.pdfarrow-up-right 발표일(게시일): 2022-07-02 (Slideshare 메타데이터 기준) 발표자: 임태규 (Taekyu Lim) 대상 독자: 경영진/PO/PM, 아키텍트, Flutter/모바일 개발팀 핵심 질문(So what?): Flutter 프로젝트에서 클린 아키텍처를 "레이어 분리" 수준이 아니라 "멀티모듈 경계"까지 밀어붙여야 하는 이유는 무엇인가?

Question

클린 아키텍처, 플러그인 아키텍처, 경계선 긋기를 하나의 설계 체계로 연결하면 Flutter 팀의 개발 속도와 변경 내성이 실제로 어떻게 좋아지는가?

Answer

한 줄 결론: 이 발표의 핵심은 "중요한 결정은 늦추고(Plugin), 변경 영향은 좁히며(Boundary), 이를 모듈 강제력으로 지킨다(Multi-module)"는 실행 프레임이다.

핵심 근거 3가지:

  • 좋은 아키텍처의 목적을 "인력 최소화"와 "변경 대응성"으로 정의하고, 추상/구체 분리를 통해 늦게 결정할 수 있는 것을 뒤로 미룬다.

  • 클린 아키텍처를 단순 Data/Domain/UI 레이어 규약으로 오해하지 않고, 도메인(정책)인프라(도구) 경계를 의존성으로 분리한다.

  • 코드리뷰/규칙만으로는 경계 침범을 막기 어려워, Flutter 패키지/멀티모듈로 "침범하기 어려운 구조"를 만든다.

Executive Summary

  • 발표는 클린 아키텍처를 "깨끗한 코드"가 아니라 "변경 비용을 낮추는 의사결정 체계"로 재정의한다.

  • 플러그인 아키텍처는 비즈니스 규칙(what)과 구현 도구(how)를 분리해, 기술 선택(DB/UI/플랫폼)을 늦게 확정하도록 돕는다.

  • 경계선 긋기의 본질은 "반대편을 모르게" 하여 변경 전파를 차단하는 것이다.

  • 실무에서는 정책/가이드만으로 한계가 있으므로, 패키지·모듈 분리로 아키텍처 오염을 구조적으로 예방해야 한다.

  • 멀티모듈 전환 시 캡슐화와 사용성은 trade-off이며, 팀 생산성 기준으로 공개 범위를 설계해야 한다.

비즈니스 임팩트:

  • 비용: 변경 영향 범위 축소로 유지보수 비용 하락

  • 속도: 인프라 결정 지연 + 도메인 선개발로 기능 실험 속도 상승

  • 리스크: 경계 강제(모듈)로 아키텍처 오염/회귀 결함 감소

  • 조직: 팀별 병렬 개발과 책임 분리 용이

문제 정의·배경

  • 소프트웨어는 시간이 갈수록 복잡도가 증가하고, 복잡도는 변경 비용을 올린다.

  • 발표는 좋은 아키텍처의 목적을 "필요 시스템을 만들고 유지하는 인력을 최소화"로 둔다.

  • Flutter 팀의 현실 문제는 기술 스택 자체보다, 무엇을 먼저 결정해야 하는가변경 파급을 어디서 끊을 것인가다.

핵심 개념 설명

1) 클린 아키텍처 (Clean Architecture)

  • 핵심: 정책(도메인)을 중심에 두고, 세부 구현(인프라)을 바깥으로 밀어낸다.

  • 포인트: "유일한 정답"이라기보다, 긴 시간 검증된 변경 대응 규칙의 집합.

2) 플러그인 아키텍처 (Plugin Architecture)

  • 핵심: 일찍 결정해야 하는 것(비즈니스 규칙)과 늦게 결정해도 되는 것(도구/기술)을 분리.

  • 예: "주문 저장"은 일찍, "MySQL/SQLite/Remote API"는 늦게.

3) 경계선 긋기 (Boundary)

  • 핵심: 경계 반대편 구현 세부를 모르게 하여 변경 영향 범위를 제한.

  • 수준: 소스 수준, 바이너리 수준, 실행 수준으로 분리 강도를 조절.

4) 멀티모듈 강제력

  • 핵심: "지키자"가 아니라 "침범이 어렵게" 구조를 만든다.

  • 발표 결론: Flutter package 기반 모듈화가 코드 레벨 경계를 실질적으로 강화.

Glossary

  • Policy: 비즈니스 정책/규칙

  • Plugin Architecture: 구현체를 나중에 끼워 넣는 의존성 역전 구조

  • Boundary: 컴포넌트 간 변경 전파 차단선

  • Robustness: 아키텍처 강건성(오염 저항성)

  • Encapsulation: 내부 구현 은닉

상세 내용·아키텍처/프로세스

핵심 인사이트 (MECE)

핵심 메시지
실무 의미

결정 시점

중요한 정책은 먼저, 도구는 나중

기술 변경 비용 절감

의존성 구조

도메인 무의존(Flutter X), 인프라가 도메인에 의존

테스트 용이성/이식성 상승

경계 강제

정책+리뷰만으론 부족, 모듈로 물리적 분리 필요

아키텍처 오염 방지

아키텍처 구조도

한 줄 메시지: 정책은 안쪽에 고정하고, 구현은 바깥에서 갈아끼우게 설계한다.

변경 대응 프로세스

한 줄 메시지: 변경을 정책/기술로 분류하면 영향 범위를 빠르게 제한할 수 있다.

잘못된 해석 vs 발표의 해석

항목
흔한 오해
발표의 해석

클린 아키텍처

Data/Domain/UI 레이어 이름 맞추기

정책-구현 분리와 변경 대응 구조

경계 관리

코드리뷰 규칙으로 통제 가능

모듈/패키지로 침범 자체를 어렵게 설계

테스트

UI 통합 테스트 중심

도메인 선개발 + 높은 테스트 커버리지

인사이트·시사점

우리 조직 적용 포인트:

  • "아키텍처 문서"보다 "의존성 그래프"를 먼저 정의해야 한다.

  • Domain을 순수 Dart 패키지로 두고 Flutter 의존성을 제거하면 테스트와 재사용이 크게 좋아진다.

  • 멀티모듈 도입 시 캡슐화 100%보다 "팀 생산성에 맞는 공개면" 설계가 현실적이다.

예상 효과 (KPI 예시):

  • 변경 리드타임: 기능 변경 요청부터 배포까지 시간

  • 변경 영향도: 변경 파일 수, 영향 모듈 수

  • 품질: 회귀 결함 밀도, 아키텍처 위반(PR) 건수

  • 생산성: 팀간 병렬 개발률, 빌드/테스트 소요시간

한계·주의사항:

  • 모듈 수를 무리하게 늘리면 빌드/관리 복잡도가 역으로 증가할 수 있다.

  • 캡슐화가 강할수록 사용성 저하가 생길 수 있어 API 표면 설계가 중요하다.

  • 규칙 자동화(정적 검사) 없이 모듈만 나누면 우회 의존이 다시 생긴다.

Action Plan (Now / Next / Later)

  1. Now (0-2주): 현재 코드베이스를 정책(도메인)과 구현(인프라)으로 분류해 의존성 맵을 만든다.

  2. Next (3-6주): Domain 패키지를 순수 Dart로 분리하고, Repository interface 경계를 명시한다.

  3. Later (7주+): 모듈 경계 위반을 CI 정적 검사로 자동화하고, 팀별 경계 소유권을 운영한다.

리스크와 대응

리스크
조기 신호
대응

모듈 과분할

모듈간 호출/설정 급증

도메인 기준 통합 재조정

캡슐화 과도

공용 API 부족으로 우회 코드 증가

공개 API 설계 가이드 정립

경계 무력화

domain에서 infra import 발생

lint/dep-rule로 CI 차단

Q&A

Q1. 클린 아키텍처를 레이어 분리만 잘하면 되는가? A1. 아니다. 발표 핵심은 변경 대응을 위한 "결정 시점"과 "경계 강제"다.

Q2. 왜 Domain을 Flutter 의존성 없이 분리하나? A2. 도메인 정책의 안정성과 테스트 속도를 확보하고 기술 교체 비용을 줄이기 위해서다.

Q3. 코드리뷰로 경계 위반을 막으면 충분하지 않나? A3. 휴먼 에러가 반복되므로, 모듈/패키지 + 정적 검사로 구조적 차단이 필요하다.

Q4. 캡슐화와 실용성 충돌은 어떻게 다루나? A4. 팀 생산성 기준으로 공개 API를 설계하고, 내부 구현은 지속적으로 은닉한다.

Q5. 플러그인 아키텍처의 실전 이점 한 줄? A5. "비즈니스 먼저 검증하고, 기술 선택은 나중에 바꿔도 된다"는 점이다.

Quiz

  1. OX: 클린 아키텍처의 목적은 레이어 개수를 늘리는 것이다. 정답: X 해설: 목적은 유지보수 인력/변경 비용 최소화다.

  2. 단답: 플러그인 아키텍처에서 일찍 결정해야 하는 것은? 정답: 비즈니스 규칙(what).

  3. OX: 경계 반대편 구현을 알수록 변경 대응이 쉬워진다. 정답: X 해설: 반대편을 모르게 해야 변경 전파가 줄어든다.

  4. 단답: 발표에서 "아키텍처 오염"을 줄이는 실질 해법은? 정답: Flutter 패키지/멀티모듈을 통한 경계 강제.

  5. OX: Domain 패키지는 Flutter 의존성이 있어도 무방하다고 발표가 강조한다. 정답: X 해설: Domain은 순수 Dart 의존성을 지향한다.

부록

A. 슬라이드별 핵심 메모 (1~62)

  • 01: 발표 주제 - 멀티 모듈을 활용한 Flutter 클린 아키텍처

  • 02: 발표자 이력 및 링크

  • 03: 소속(Presto Labs) 및 채용 안내

  • 04: 목차 - 클린/플러그인/경계선

  • 05: Part1 시작

  • 06: 클린 아키텍처 개념 질문 제기

  • 07: 클린 아키텍처 재질문

  • 08: Robert C Martin 관점 소개

  • 09: 보편적 규칙의 존재와 학습 필요성

  • 10: 올바른 구조가 인력 최소화로 연결

  • 11: 아키텍처 정의(구성요소 관계)

  • 12: 좋은 아키텍처 정의(유지 인력 최소)

  • 13: 아키텍처가 지원해야 할 4요소(유스케이스/운영/개발/배포)

  • 14: 개발비용 상승 요소 제거 필요

  • 15: 복잡도 증가와 변경비용 증가

  • 16: 목표 - 변경에 잘 대응

  • 17: 시간/범위 관점 대응 제시

  • 18: 시간=플러그인, 범위=경계선으로 연결

  • 19: Part2 시작

  • 20: what vs how 분리 원칙

  • 21: 클린 아키텍처 도식

  • 22: Data/Domain/UI 오해 지점

  • 23: 레이어 아키텍처 언급

  • 24: 도메인-인프라 분리 도식

  • 25: 모듈 배치 예시

  • 26: 플러그인 아키텍처 도식

  • 27: 도메인은 순수 Dart 의존성

  • 28: 인프라는 Flutter/플랫폼 의존성

  • 29: 높은 테스트 커버리지 지향

  • 30: Part3 시작

  • 31: 경계 도식

  • 32: 경계의 의미와 변경 전파 차단

  • 33: 소스/바이너리/실행 수준 분리 설명

  • 34: 분리 수준 반복 강조

  • 35: 선 긋기 실전 진입

  • 36: usecase 코드 예시

  • 37: bloc 코드 예시

  • 38: repository interface 예시

  • 39: view 코드 예시

  • 40: data/repository 구현 예시

  • 41: local datasource 예시

  • 42: remote datasource 예시

  • 43: 경계 침범(오염) 예시

  • 44: 코드리뷰/정적검사만으론 한계

  • 45: 더 강한 경계 필요성

  • 46: 강건성 향상 메시지

  • 47: 모듈 기반 선 긋기 제안

  • 48: 의존성 추가 단계

  • 49: 아키텍처 오염 방지 강조

  • 50: 모듈 추가 방법 질문

  • 51: Flutter 프로젝트 타입(Application/Plugin/Package/Module/Skeleton)

  • 52: 프로젝트 타입 재강조

  • 53: Package 중심 전략 강조

  • 54: 모듈/의존 구조 도식

  • 55: 순수 dart package IDE 제약

  • 56: 수동 추가 필요

  • 57: 명령어로 직접 생성

  • 58: 전체 패키지 구조

  • 59: 캡슐화 강한 domain 패키지 구조와 불편점

  • 60: 캡슐화 완화 구조와 편의성

  • 61: 전체 요약(결정 지연 + 경계 + 패키지)

  • 62: Q&A

B. 근거/출처

  • 사실: 발표는 3부 구성(클린 아키텍처, 플러그인 아키텍처, 경계선 긋기)이다.

    • 출처: Slides 4, 5, 19, 30

  • 사실: 발표는 what(비즈니스 규칙)과 how(도구) 분리를 강조한다.

    • 출처: Slide 20

  • 사실: Domain은 Flutter 의존성 없이 Dart 기반으로 두는 구조를 제시한다.

    • 출처: Slide 27

  • 사실: 코드리뷰/정적검사만으로는 아키텍처 오염 방지에 한계가 있음을 지적한다.

    • 출처: Slide 44

  • 사실: Flutter package/멀티모듈 활용을 경계 강제 수단으로 제시한다.

    • 출처: Slides 47-61

  • 해석: "멀티모듈은 아키텍처 문서보다 더 강한 실행 장치"라는 결론은 작성자 종합 판단.

C. 추가 참고(Flutter 공식 문서)

  • Packages & plugins: https://docs.flutter.dev/packages-and-plugins

  • Developing packages: https://docs.flutter.dev/packages-and-plugins/developing-packages

  • App architecture guide: https://docs.flutter.dev/app-architecture

  • Testing overview: https://docs.flutter.dev/testing

Last updated