SlideShare une entreprise Scribd logo
1  sur  75
Télécharger pour lire hors ligne
모듈화 시대 시작 with Tuist
개발 관점의 변화
안정민
목차
• 모듈화 개발 시작 with Tuist

• 어떻게 기능을 개발해야할까?

• 응집도와 결합도

• View(Controller)

• 리소스

• Interactor, Router

• Repository

• Builder
모듈화 개발 시작(with Tuist)
• Tuist 적용 이후

• 프로젝트 파일을 매번 생성하여 프로젝트 파일의 머지 충돌이 없어졌음

• 프로젝트에서 다른 모듈을 의존성 가지더라도 Tuist에서 의존성 추적으로 프로젝
트 파일에 의존성을 자동으로 추가해주기 때문에 별도로 작업할 필요가 없음

• 따라서 프로젝트 관리가 쉬워짐
모듈화 개발 시작(with Tuist)
• 새로운 프로젝트를 만들기 쉬워졌음

• Application 프로젝트에 있는 코드를 새로운 프로젝트로 분리하기 쉬워짐

• 의존성 그래프를 보면서 어디에 프로젝트를 생성하고 배치할지 알 수 있음

• 각 프로젝트마다 필요에 따라 쉽고 빠르게(기존에 비해) 새로운 프로젝트로 분리하
여 개발될 수 있음.
어떻게 프로젝트를 분리하고


개발해야할 것인가


논의가 필요한 시기
어떻게 기능을 개발해야할까?
응집도와 결합도
• Application프로젝트에서는 모든 소스가 한 프로젝트에 있었음.

• 이는 파일 단위로 폴더 구조로 보면 응집도가 높다고 할 순 있음.

• 해당 소스은 역할별로 분리되어 있음.

• 하지만 프로젝트, 모듈 단위로 보면 응집도가 아닌 결합도가 높은 것임

• 유용하게 구현된 코드가 있으면 바로 접근하여 사용이 가능하기 때문
Application
Interactor
Router
ViewController
인증
Builder
Interactor
Router
ViewController
여신
Builder
Interactor
Router
ViewController
수신
Builder
소스


가시화
Application
Interactor
Router
ViewController
여신
Builder
Interactor
Router
ViewController
수신
Builder
• 수신과 여신은 서로 코드 접근이 가능

• 자기 도메인 및 역할에 필요한 값만 접근이 가능해야함.

• 모듈로 분리 및 격리하여 수신과 여신간의 결합도를 감소
및 응집도를 증가할 수 있음.
Application
Interactor
Router
ViewController
인증
Builder
Interactor
Router
ViewController
여신
Builder
Interactor
Router
ViewController
수신
Builder
Interactor
Router
View(Controller)
Builder
Interactor
Router
View(Controller)
Builder
View(Controller)
• 역할

• View 컴포넌트가 잘 배치되었는지

• 넘겨받은 상태를 잘 표시하는지

• View에서 발생한 이벤트를 잘 넘겨주는지

• 필요요소

• View 컴포넌트

• Resource - Image, Color, Storyboard, Xib
View(Controller)
• 상태를 받아서 잘 보여주고, 이벤트를 잘 넘겨줄 수 있다면 Preview로 화면을 볼 수
있음.

• 즉, 외부 의존성 없이 View(Controller)만을 가지게 됨.
UI / LoanGoodsViewController.swift
View(Controller)
• View를 그리는 주체도 View에 넘겨준다면 Preview 기능을 더욱 활용할 수 있음.

• ViewController의 view를 Custom View로 교체

• ViewController는 View에 출력하기 좋게 상태를 가공해서 넘겨줄 수 있음.
UI / LoanGoodsViewController.swift
UI / LoanGoodsView.swift
View ViewController
리소스
• Image, Color, Storyboard, Xib는 리소스

• Image, Color는 각 기능마다 동일한 값을 반환해야함.

• 별도의 모듈로 관리해야 기능의 UI모듈에서 가져다 사용할때 동일하게 반영됨.

• ex) X 버튼의 이미지 색상이 바뀌었을 때 모든 모듈의 화면이 동일하게 반영되
어야 함.

• Storyboard, Xib에서 이미지 사용시 같은 번들에 있어야 사용이 가능함.

• Storyboard, Xib를 위해 해당 번들에 이미지가 중복해서 존재하면 안됨.
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Preview
Preview
• SwiftUI를 Wrapping해서 UIKit으로 Preview 가능

• 화면 작업시 Preview 기능만으로 화면 구성

• 유지보수 작업시 컴포넌트 변경 또는 추가에 빠른 대응 가능
UI / LoanGoodsViewPreview.swift
Interactor
Router
View(Controller)
Builder
Interactor
Router
모듈
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Interactor
• 비즈니스 로직을 처리하는 곳

• (Optional)View로 부터 Action을 전달받고, State를 넘겨줌.

• 기존에는 Presentable이라는 프로토콜을 정의하고 ViewController는 해당 프로토
콜을 따르도록 사용하였음.

• 이는 ViewController가 Interactor 역할을 알게되는 상태임.

• ViewController와 Interactor간의 커플링 발생
UI / ViewController.swift
Domain / Interactor.swift
UI / ViewController.swift
Domain / Interactor.swift
ViewController
Interactor


Presentable
UI 모듈 모듈
ViewController
Interactor


Presentable
UI 모듈 모듈
ViewController
Interactor


Presentable
UI 모듈 모듈
Router
• Routing을 처리하는 곳

• Child RIB을 생성하고 관리함.

• (Optional)ViewController에 ViewableRouter의 ViewController를 Present,
Dismiss 요청을 하는 곳. 

• ViewControllable 프로토콜로 인한 UI 모듈과 의존관계가 형성됨.
UI / ViewController.swift
Domain / Router.swift
UI / ViewController.swift
Domain / Router.swift
ViewController
Router


ViewControllable
UI 모듈 모듈
ViewController
Router


ViewControllable
UI 모듈 모듈
ViewController
Router


ViewControllable
UI 모듈 모듈
Interactor
Router
모듈
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Interactor
Router
수신 Domain 모듈
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
코드와 개발자 간의 관점의 차이
• 개발시 관점 차이

• 개발자의 관점

• 전지적으로 모든 코드를 알고 접근 가능

• 모듈로 나누더라도 연결된 것이기 때문에 같은 것으로 보게 됨

• 모듈(코드)의 관점

• 내 영역에서 정의되거나 의존성을 가진 코드만 접근 가능
UI
Interactor


Router
UI
Interactor


Router
Dependency
Delegate
개발자의 전지적 시점 + 모듈 격리화
코드와 개발자 간의 관점의 차이
• 코드의 시점

• UI는 상태를 받아서 보여주고, 이벤트를 넘겨줌

• Interactor는 상태를 만들어서 넘겨주고, 이벤트를 받음

• Interactor는 UI를 직접적으로는 몰라야함

• 이는 Interactor가 UI에 의존적이지 않도록 하기 위함
코드와 개발자 간의 관점의 차이
• 전지적 시점

• UI와 Interactor, Router 둘의 코드를 알고 있음.

• 하지만 Interactor는 UI에 대한 직접적인 의존 관계는 형성되면 안됨.

• Interactor를 검증하기 위해 UI 의존 관계가 추가됨.

• Interactor는 넘겨줄 상태와 받을 이벤트를 정의함.

• 사실상 UI와 동일하게 정의한 상태와 이벤트임.(중복이지만 중복이 아닌)

• UI와 Interactor간의 직접적인 의존 관계를 깨트리고 간접적인 의존 관계가 형성됨
UI
Interactor


Router
Dependency
Delegate
Adapter


(Presentation)
Domain / Presentation.swift
UI / Presentation.swift
UI
Interactor


Router
UI.State
UI.Action
Adapter


(Presentation)
Action
State
Domain / Presentation.swift
Domain / Presentation.swift
Interactor
Router
Service
수신 Domain 모듈
수신
View
ViewController
수신 UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Repository
• Service는 Interactor에서 복잡한 로직을 대신 처리해주는 역할을 담당함.

• 현재 네트워크 요청, 앱로그, Property 호출은 Interactor가 아닌 Service에서 호출
하고 있음.

• Service는 네트워크, 앱로그, 환경설정 등의 의존성을 가지고 있음.
Interactor
Router
Service
수신 Domain 모듈
네트워크 모듈
로그 모듈
환경설정 모듈
Interactor
Router
Service
수신 Domain 모듈
네트워크 모듈
로그 모듈
환경설정 모듈
Repository
• 현재 구조로는 도메인 모듈은 네트워크 요청, 앱 로그, 환경 설정 모듈을 의존성 가짐.

• Service는 비지니스 로직을 처리하는데, 외부 모듈이 필요할때 의존성 주입을 받을 수
있다면?

• 해당 의존성 주입을 받게 되면 도메인 모듈은 직접적인 외부 모듈과의 의존관계가
없어짐.
Interactor


Router
Service
Repository


Protocol
Domain 모듈 Repository 모듈
Repository


Impl
Network
AppLog
Environment


Properties
Repository / Repository.swift
Domain / Service.swift
Repository / Repository.swift
Domain / Service.swift
Builder
• Repository 모듈은 Domain 모듈을 의존성 가지는데, Domain 모듈은 Repository
모듈을 모릅니다.

• Domain 모듈에는 Service가 있고, Service는 Repository Protocol을 받도록 합
니다.

• 그러면 Service에는 Repository 모듈의 구현체를 어떻게 넣어줘야 할까요?
Domain


Service
Repository
?
Builder
• Builder가 UI, Domain, Repository 모듈을 의존합니다.

• UI, Interactor, Router, Service, Repository를 생성하여 조립하여 각 모듈간의
연결을 도와줍니다.
Interactor
Router
Service
Domain 모듈
수신
View
ViewController
UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Repository
Impl
Repository모듈
API
Network 모듈
Builder
Builder 모듈
Builder / Builder.swift
Domain / Builder.swift
Builder / Builder.swift
Domain / Builder.swift
Buildable
Routing
Listener
Domain 모듈
수신
Builder
Builder 모듈
Buildable
Routing
Interactable
Domain 모듈
인증
Builder
Builder 모듈
Buildable
Routing
Listener
Domain 모듈
수신
Builder
Builder 모듈
Buildable
Routing
Interactable
Domain 모듈
인증
Builder
Builder 모듈
Buildable
Routing
Listener
Domain 모듈
수신
Builder
Builder 모듈
Buildable
Routing
Interactable
Domain 모듈
인증
Builder
Builder 모듈
수신 인증
Domain 모듈
Interactor
Router
Service
View
ViewController
UI 모듈
Image, Asset
Storyboard
공통 UI 리소스 모듈
Repository
Impl
Repository모듈
API
Network 모듈
Builder
Builder 모듈
Domain 모듈
Interactor
Router
Service
View
ViewController
UI 모듈
Repository
Impl
Repository모듈
Builder
Builder 모듈
• 모듈 수가 많아짐에 따라 프로젝트 수가 많아질 수는 있음.

• 같은 도메인에 해당하는 모듈을 모아 한 프로젝트에서 작업도 가능
정리
• 모듈화는 격리화를 통해 지금까지 못했던 독립적인 기능을 구현할 수 있음

• 모듈이 계층으로 묶여서 계층 단위의 추상화를 제공하며, 직교적 시스템을 설계가 가능함

• 다른 코드에 영향을 끼치지 않으면서 기반 구현을 구현할 수 있으므로 유연성이 높아짐

• 모듈 단위의 개발로 빠른 피드백을 받을 수 있음

• 각 모듈을 검증하는데 비용이 줄어들며, 모듈을 연결해 통합 검증하는 비용도 줄어듬

• 설계를 통해 코드 유지보수 비용을 일정 수준에서 관리가 가능한 지속 가능한 코드가 됨
Reference
• Cookpad - 코드 생성을 이용한 iOS 앱 멀티 모듈화를 위한 종속 솔루션

• Modular iOS Architecture @ Just Eat

• App Modularization at Wayfair

• iOS-Clean-Architecture-MVVM

• Android Clean Architecture

• Blog - Clean Architecture is not Domain-Data-Presentation

• Youtube - Micro/feature frameworks

• iOS Architecture at Lyft
끝
One more thing…
진짜 끝

Contenu connexe

Tendances

버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
버전관리를 들어본적 없는 사람들을 위한 DVCS - Git버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
민태 김
 
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
devCAT Studio, NEXON
 
이승재, 실시간 HTTP 양방향 통신, NDC2012
이승재, 실시간 HTTP 양방향 통신, NDC2012이승재, 실시간 HTTP 양방향 통신, NDC2012
이승재, 실시간 HTTP 양방향 통신, NDC2012
devCAT Studio, NEXON
 

Tendances (20)

fastlane을 이용하여 iOS/Mac 앱 관리하기
fastlane을 이용하여 iOS/Mac 앱 관리하기fastlane을 이용하여 iOS/Mac 앱 관리하기
fastlane을 이용하여 iOS/Mac 앱 관리하기
 
객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)
 
[LetSwift 2023] 객체지향-함수형 아키텍처 직접 만들기
[LetSwift 2023] 객체지향-함수형 아키텍처 직접 만들기[LetSwift 2023] 객체지향-함수형 아키텍처 직접 만들기
[LetSwift 2023] 객체지향-함수형 아키텍처 직접 만들기
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질
 
ReactorKit으로 단방향 반응형 앱 만들기
ReactorKit으로 단방향 반응형 앱 만들기ReactorKit으로 단방향 반응형 앱 만들기
ReactorKit으로 단방향 반응형 앱 만들기
 
Let'Swift 2023 Swift Macro, 어디다 쓰죠?
Let'Swift 2023 Swift Macro, 어디다 쓰죠?Let'Swift 2023 Swift Macro, 어디다 쓰죠?
Let'Swift 2023 Swift Macro, 어디다 쓰죠?
 
DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스
 
이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정
 
SwiftUI와 TCA로 GitHub Search앱 만들기
SwiftUI와 TCA로 GitHub Search앱 만들기SwiftUI와 TCA로 GitHub Search앱 만들기
SwiftUI와 TCA로 GitHub Search앱 만들기
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
버전관리를 들어본적 없는 사람들을 위한 DVCS - Git버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
버전관리를 들어본적 없는 사람들을 위한 DVCS - Git
 
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
 
로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법
 
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
 
RxSwift Testing 같이 시작하기 feat. RxBlocking, RxTest
RxSwift Testing 같이 시작하기 feat. RxBlocking, RxTestRxSwift Testing 같이 시작하기 feat. RxBlocking, RxTest
RxSwift Testing 같이 시작하기 feat. RxBlocking, RxTest
 
Jenkins使ってみた~Windows編~
Jenkins使ってみた~Windows編~Jenkins使ってみた~Windows編~
Jenkins使ってみた~Windows編~
 
이승재, 실시간 HTTP 양방향 통신, NDC2012
이승재, 실시간 HTTP 양방향 통신, NDC2012이승재, 실시간 HTTP 양방향 통신, NDC2012
이승재, 실시간 HTTP 양방향 통신, NDC2012
 

Similaire à iOS Modular Architecture with Tuist

Component configurator
Component configuratorComponent configurator
Component configurator
scor7910
 
스토리북(Storybook, Kitworks Team Study 우아라 발표)
스토리북(Storybook, Kitworks Team Study 우아라 발표)스토리북(Storybook, Kitworks Team Study 우아라 발표)
스토리북(Storybook, Kitworks Team Study 우아라 발표)
Wonjun Hwang
 
Bootstrap 살펴보기
Bootstrap 살펴보기Bootstrap 살펴보기
Bootstrap 살펴보기
영배 현
 

Similaire à iOS Modular Architecture with Tuist (20)

Android Developer JeongJaeyun
Android Developer JeongJaeyunAndroid Developer JeongJaeyun
Android Developer JeongJaeyun
 
React native development
React native developmentReact native development
React native development
 
[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계
 
Droid knights 2019 - (Large-scale App을 위한) Android Architecture 총정리
Droid knights 2019 - (Large-scale App을 위한) Android Architecture 총정리Droid knights 2019 - (Large-scale App을 위한) Android Architecture 총정리
Droid knights 2019 - (Large-scale App을 위한) Android Architecture 총정리
 
iOS Architecture.pdf
iOS Architecture.pdfiOS Architecture.pdf
iOS Architecture.pdf
 
Angularcdk
AngularcdkAngularcdk
Angularcdk
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJS
 
Spring Framework - Inversion of Control Container
Spring Framework - Inversion of Control ContainerSpring Framework - Inversion of Control Container
Spring Framework - Inversion of Control Container
 
Rx for iOS App. RxMVVM-DataCenter!
Rx for iOS App. RxMVVM-DataCenter!Rx for iOS App. RxMVVM-DataCenter!
Rx for iOS App. RxMVVM-DataCenter!
 
Component configurator
Component configuratorComponent configurator
Component configurator
 
6. nexcore alopex runtime
6. nexcore alopex runtime6. nexcore alopex runtime
6. nexcore alopex runtime
 
개발 방식을 바꾸는 15가지 기술
개발 방식을 바꾸는 15가지 기술개발 방식을 바꾸는 15가지 기술
개발 방식을 바꾸는 15가지 기술
 
스토리북(Storybook, Kitworks Team Study 우아라 발표)
스토리북(Storybook, Kitworks Team Study 우아라 발표)스토리북(Storybook, Kitworks Team Study 우아라 발표)
스토리북(Storybook, Kitworks Team Study 우아라 발표)
 
DDD 그게 뭔데 (개념 찍먹편)
DDD 그게 뭔데 (개념 찍먹편)DDD 그게 뭔데 (개념 찍먹편)
DDD 그게 뭔데 (개념 찍먹편)
 
K8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_postK8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_post
 
Bootstrap 살펴보기
Bootstrap 살펴보기Bootstrap 살펴보기
Bootstrap 살펴보기
 
Create App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @SeoulCreate App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @Seoul
 
my activities before getting a job
my activities before getting a jobmy activities before getting a job
my activities before getting a job
 
I os 1
I os 1I os 1
I os 1
 
Dagger with multi modules
Dagger with multi modulesDagger with multi modules
Dagger with multi modules
 

Plus de 정민 안 (7)

20240516_동적_데이터을_대응하는_코드_작성하기.pdf
20240516_동적_데이터을_대응하는_코드_작성하기.pdf20240516_동적_데이터을_대응하는_코드_작성하기.pdf
20240516_동적_데이터을_대응하는_코드_작성하기.pdf
 
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
20240325 TuistNight 모듈로 나누면 알아두면 좋을 3가지 팁
 
Letusgo 2019 Summer - StringInterpolation and SwiftUI
Letusgo 2019 Summer - StringInterpolation and SwiftUILetusgo 2019 Summer - StringInterpolation and SwiftUI
Letusgo 2019 Summer - StringInterpolation and SwiftUI
 
Debugging with xcode, lldb and chisel
Debugging with xcode, lldb and chiselDebugging with xcode, lldb and chisel
Debugging with xcode, lldb and chisel
 
Introduce fastlane
Introduce fastlaneIntroduce fastlane
Introduce fastlane
 
Git lecture
Git lectureGit lecture
Git lecture
 
형상관리 발표자료 안정민
형상관리 발표자료 안정민형상관리 발표자료 안정민
형상관리 발표자료 안정민
 

iOS Modular Architecture with Tuist