Swift

Swift - 소프트웨어 아키텍처(MVC, MVVM)

iosos 2023. 7. 2. 18:36

* Swift 소프트웨어 아키텍처

- Swift 언어로 애플리케이션을 구조화하는 방법과 관련된 원칙과 패턴 모음

- 소프트웨어 아키텍처를 적용함으로써 모듈성, 유지보수성, 확장성을 개선할 수 있음 

- MVC, MVVM, MVP, VIPER 

 

 


● MVC (Model View Controller)

- 소프트웨어 아키텍처의 가장 기본적인 형태로 모델(Model), 뷰(View), 컨트롤러(Controller)로 구분

 

 

1. 모델(Model)

- 데이터와 비즈니스 로직을 관리

- 애플리케이션의 상태와 동작을 나타냄

- 데이터의 변경을 감지하고, 변경 사항을 컨트롤러에게 알림

 


2. 뷰(View)

- 사용자 인터페이스를 표시 및 관리 

- 모델의 상태를 표시하고, 사용자의 입력을 받음

- 모델의 변경 사항을 감지하고, 변경된 데이터 표시 

 

 

3. 컨트롤러(Controller)

- 모델과 뷰 간의 상호작용을 관리

- 사용자의 입력을 처리하고, 해당 입력에 따라 모델을 업데이트하거나 뷰를 업데이트 

- 모델의 변경 사항을 감지하여 뷰에 알리고 필요한 경우 뷰를 업데이트 

 

 

 

* 애플의 MVC 패턴

 

- 컨트롤러가 뷰의 LifeCycle에 관여하게 되면서 M-VC 패턴이 됨 

- 뷰의 코드와 컨트롤러의 코드가 겹치면서 결과적으로 뷰 컨트롤러가 비대해지고 역할이 커짐

- 이에 코드를 적게쓰고 개발 속도가 빨라졌으며 모델과 뷰의 상호의존성을 없앴지만, 테스트가 용이하지 않고 유지보수가 힘들어짐 

 

 

 

예)

 

 

 

 

1. 모델 (Model) - MVC_User

import Foundation

// 모델 (Model)
struct MVC_User{
    let name : String
    let age : Int
}

- 모델은 애플리케이션의 데이터를 추상화하고, 다른 컴포넌트인 뷰(View)와 Controller에서 필요한 데이터를 제공 

 

 

 

 

 

2. 뷰(View) - MVC_UserProfileViewController

import UIKit


// 뷰 (View)
class MVC_UserProfileViewController: UIViewController {
    
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var ageLabel: UILabel!

    
    
    override func viewDidLoad() {
        
        let user = MVC_User(name: "이길동", age: 28)
        let userProfileController = MVC_UserProfileController(user: user, view: self)
        
        userProfileController.updateUserProfile()
    }
}

 

 

 

 

 

 

3. 컨트롤러 (Controller) - MVC_UserProfileController

import Foundation

// 컨트롤러(Controller)
class MVC_UserProfileController {
    let user: MVC_User
    let userProfileView : MVC_UserProfileViewController
    
    init(user: MVC_User, view: MVC_UserProfileViewController) {
        self.user = user
        self.userProfileView = view
    }
    
    func updateUserProfile(){
        userProfileView.nameLabel.text = user.name
        userProfileView.ageLabel.text = "\(user.age)"
    }
    
}

- 컨트롤러는 모델과 뷰 간의 상호작용을 관리하고, 필요한 데이터를 모델로부터 가져와 뷰에 전달하여 화면에 적절한 정보 표시하는 역할 

 

 

 

 

 

 

 


 

 

 

 

 

● MVVM (Model-View-ViewModel)

- GUI 코드로 구현하는 그래픽 사용자 인터페이스(뷰)의 개발을 비지니스 로직 또는 백엔드 로직(모델)로부터 분리시켜서 뷰가 어느 특정한 모델 플랫폼에 종속되지 않도록 함

- MVC 와 다르게 Controller가 아닌 ViewModel 계층을 가지고 있음

- ViewModel 또한 Controller 처럼 View와 Model의 중간 계측 역할을 함

- 데이터 바인딩을 활용하여 뷰와 뷰모델을 자동으로 동기화시킴.

- 뷰모델의 상태가 변경되면 자동으로 뷰에 반영, 뷰의 입력 변화동 자동으로 뷰모델에 전달  -> 코드의 양 줄이고, UI 업데이트 쉽게 처리

- 테스트 용이성과 모델 분리에 강점을 가지며, 복잡한 사용자 인터페이스와 비지니스 로직을 다루는 데 적합

- SwiftUI에서는 MVVM을 기본 아키텍처로 채택하여 개발을 진행 함 

 

 

1. 모델(Model)

- MVVM에서의 모델은 MVC 패턴과 유사한 역할 수행

 

 

2. 뷰 (View)

- MVVM에서는 뷰는 데이터를 직접적으로 변경하지 않으며, 뷰모델과의 상호작용을 통해 데이터 업데이트 

 

 

3. 뷰모델(ViewModel)

- 뷰와 모델 간의 중간 매개체 역할 수행

- 뷰에 표시할 데이터와 명령을 제공하고 뷰에서 발생한 이벤트 처리

- 뷰와 독립적으로 테스트 가능하며, 비지니스 로직을 캡슐화하여 재사용성을 높임

- 뷰와 모델 간의 종속성을 낮추고, 단방향 데이터 바인딩을 통해 자동으로 뷰를 업데이트 함 

 

 

 

 

 

예)

 

 

 

 

1. 모델 (Model) - User

import Foundation

// 모델(User)
struct User{
    let name : String
    let age : Int
}

- 'User' : 데이터를 담는 모델

 

 

 

 

2. 뷰(View) - UserProfileViewController

import UIKit

// 뷰 (View)
class UserProfileViewController: UIViewController {

    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var ageLabel: UILabel!
    
    var user = User(name: "홍길동", age: 24)
    var viewModel : UserViewModel!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel = UserViewModel(user: user)

        updateUI()
    }
    
    func updateUI(){
        nameLabel.text = viewModel.name
        ageLabel.text = viewModel.age
    }

}

- 'UserProfileView' : 사용자 프로필을 표시하는 뷰 

- 'viewModel' 프로퍼티를 가지고 있으며, 뷰모델 객체가 주입 됨 

- 'updateUI' 함수를 호출하여 뷰의 요소들을 뷰모델의 데이터로 업데이트 

 

 

 

 

3. 뷰모델(ViewModel) - UserViewModel

// 뷰모델 (ViewModel)
class UserViewModel {
    private var user : User
    
    init(user: User){
        self.user = user
    }
    
    var name : String{
        return user.name
    }
    
    var age: String{
        return "\(user.age)"
    }
}

- 'UserViewModel' : 뷰와 모델 간의 중간 매개체로서, 모델 데이터를 처리하고 뷰에 표시할 데이터 제공 

 

 

 

 

 

 


참고) 

MVC 패턴
 https://fomaios.tistory.com/entry/Architecture-MVVM-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80 

 

[Design Pattern] Apple의 MVC 패턴이란?

안녕하세요 Foma 👟 입니다! 저번 글에 MVC 패턴에 대해서 다뤘었는데 iOS에서 다루는 것과는 조금 다르게 커스텀뷰를 직접 만들어서 뭔가 더 정석적인 MVC 패턴을 구현했어요. (혹시 안보셨거나 궁

fomaios.tistory.com

 

https://labs.brandi.co.kr/2018/02/21/kimjh.html 

 

iOS 아키텍처 패턴(MVC, MVVM, VIPER)

Overview“글 한 번 써보실래요?” 입사하고 일주일이 지나 기술 블로그에 글을 써 보라는 제안을 받았습니다. 여러 고민 끝에, 아이폰 앱(이하 ‘iOS’) 주니어 개발자로서 프로젝트 경험과, 공부

labs.brandi.co.kr