[iOS] MVVM과 Clean Architecture의 결합: iOS 앱 개발에서의 구조적 접근

iosMVVMClean Architecture
avatar
2025.03.03
·
6 min read

iOS 앱 개발에서 유지보수성과 확장성을 고려할 때, MVVM과 클린 아키텍처를 결합하는 방식은 아주 효과적이다. 이 글에서는 MVVM과 클린 아키텍처의 개념을 정리하고, 이 둘을 어떻게 조합할 수 있는지에 대해 자세히 알아보겠다.

MVVM (Model-View-ViewModel)

MVVN은 iOS에서 많이 사용하는 아키텍처 패턴으로, 코드의 모듈화와 UI 로직 분리를 강조한다.

MVVM의 구조

컴포넌트

역할

Model

데이터 및 비즈니스 로직을 관리 (Core Data, API 응답 등)

View

사용자 인터페이스(UI) 및 화면 요소 (UIView, SwiftUI View)

ViewModel

View와 Model을 연결하는 중간 계층, UI 로직을 처리

MVVM의 가장 큰 장점은 View와 Model을 완전히 분리하여 UI 변경이 Model에 영향을 주지 않고, 반대로 Model 변경이 UI에 직접적인 영향을 주지 않도록 하는 것이다.

클린 아키텍처 (Clean Architecture)

클린 아키텍처는 소프트웨어를 레이어(layer)로 분리하여 유지보수성과 확장성을 높이는 패턴이다.

클린 아키텍처의 4계층

계층

설명

Entity (Entities)

핵심 비즈니스 로직 및 도메인 모델

Use Case (Interactor)

애플리케이션의 주요 동작을 수행하는 계층

Interface Adapter (ViewModel, Presenter)

Use Case와 UI를 연결하는 역할

Framework & Drivers (UI, API, Database)

외부 시스템 (UIKit, SwiftUI, API, DB)

클린 아키텍처는 비즈니스 로직을 명확하게 분리하여 UI나 외부 데이터 소스와 독립적으로 유지될 수 있도록 한다.

MVVM과 클린 아키텍처의 결합

MVVM은 View와 Model을 분리하는 데 초점을 맞추지만, 비즈니스 로직과 데이터 처리를 더 구조화하려면 클린 아키텍처와 결합하는 것이 효과적이다.

MVVM + 클린 아키텍처 계층 구조

Presentation Layer
  ├── View (SwiftUI, UIKit)
  ├── ViewModel (Interface Adapter)  <-- UI 로직 관리
Domain Layer
  ├── Use Case (Interactor)          <-- 비즈니스 로직 수행
Data Layer
  ├── Repository                     <-- 데이터 처리
  ├── Data Source (API, Database)    <-- 외부 시스템과 연결

MVVM + 클린 아키텍처 적용 예제

Use Case 레이어 (비즈니스 로직 담당)

protocol FetchUserUseCase {
    func execute() -> User
}

class FetchUserInteractor: FetchUserUseCase {
    private let repository: UserRepository
    
    init(repository: UserRepository) {
        self.repository = repository
    }
    
    func execute() -> User {
        return repository.getUser()
    }
}

ViewModel 레이어 (UI 로직 담당)

class UserViewModel: ObservableObject {
    @Published var userName: String = ""
    private let fetchUserUseCase: FetchUserUseCase
    
    init(fetchUserUseCase: FetchUserUseCase) {
        self.fetchUserUseCase = fetchUserUseCase
    }
    
    func fetchUser() {
        let user = fetchUserUseCase.execute()
        self.userName = user.name
    }
}

Repository 레이어 (데이터 관리)

protocol UserRepository {
    func getUser() -> User
}

class UserRepositoryImpl: UserRepository {
    func getUser() -> User {
        // API 또는 Database에서 데이터 가져오기
        return User(id: 1, name: "Alice")
    }
}

View 레이어 (UIKit 또는 SwiftUI)

struct UserView: View {
    @ObservedObject var viewModel: UserViewModel
    
    var body: some View {
        VStack {
            Text(viewModel.userName)
            Button("Fetch User") {
                viewModel.fetchUser()
            }
        }
    }
}

MVVM과 클린 아키텍처 결합의 장점

  • 비즈니스 로직과 UI 코드의 완벽한 분리 → 유지보수성이 뛰어남

  • 의존성 역전 원칙(DIP) 적용 → 테스트하기 쉬운 구조

  • 모듈화된 코드 구조 → 기능 확장이 용이

  • 데이터 처리와 UI 관리의 역할 분리 → 역할별 코드가 명확해짐

결론적으로 MVVM과 클린 아키텍처를 결합하면 View와 Model을 분리하면서도, 비즈니스 로직을 체계적으로 관리할 수 있는 강력한 구조를 만들 수 있다.

  • MVVM은 UI 로직을 분리하고, 클린 아키텍처는 비즈니스 로직을 구조화하는 역할을 함

  • Use Case를 활용하면 ViewModel이 UI 상태 관리만 담당하고, 비즈니스 로직은 독립적으로 유지할 수 있음

  • Repository를 사용하여 데이터 계층을 분리하고, 유연한 데이터 관리 가능

이 패턴을 적용하면 유지보수성과 확장성이 뛰어난 iOS 앱을 개발할 수 있다.







- 컬렉션 아티클