iOS/Swift

MVC 패턴 (Model - View - Controller)

밤새는 탐험가89 2024. 5. 25. 22:41

 

🟥 MVC 패턴이란?

Model, View, Controller의 줄임말이다. 

  • Model: 애플리케이션의 Data를 관리한다. 주로 구조체 또는 클래스로 생성된다. 
  • View: 화면과 Controller을 스크린을 통해 보여주는 역할을 한다. 
  • Controller: Model과 View 사이에서 연결하는 역할을 한다

✅ Model과 View는 직접 소통이 되지 않는다. 

 

 

 

1️⃣ Model

  • 데이터만 관리한다. 
  • View와 직접적인 연결은 없다. 
// MARK: - Model
struct Person {
    var name: String
    var age: Int
    var address: String
}

 

 

2️⃣ View

  • 화면 표시만 관리한다. 
  • Model과는 직접적인 연결은 없다.
// MARK: - View
class PersonView: UIView {
    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var ageField: UITextField!
    @IBOutlet weak var addressField: UITextField!
}

 

 

3️⃣ Controller

  • Model과 View 사이를 조율한다. 
  • Model의 데이터 모델에 따라 View에서 정한 화면에 맞게 구성한다. 
  • Model의 변경사항이 있을 경우, View에 전달하고, 반대인 경우도 마찬가지다. 

⭐ 1개의 Controller는 여러 개의 View와 Model을 소유할 수 있다. 

class PersonViewController: UIViewController {
    // MARK: Properties
    var person: Person? {
        didSet {
            updatePersonViewFromPerson()
        }
    }
    var personView: PersonView! {
        guard isViewLoaded else {
            return nil
        }
        
        return (view as! PersonView)
    }
    
    
    // MARK: ViewLifeCycle
    override func viewDidLoad() {
        super.viewDidLoad()
        updatePersonViewFromPerson()
    }
    
    private func updatePersonViewFromPerson() {
        guard let person = person,
              let personView = personView else {
            return
        }
        
        personView.nameField.text = person.name
        personView.ageField.text = "\(person.age)"
        personView.addressField.text = person.address
    }
    
    // MARK: @IBAction
    @IBAction func updatePersonFromPersonView(_ sender: Any) {
        guard let name = personView.nameField.text,
              let age = Int(personView.ageField.text ?? "0"),
              let address = personView.addressField.text else {
            return
        }
        
        person = Person(name: name, age: age, address: address)
    }
}

 

 

Model과 View가 Controller와의 소통

View와 Model은 Controller 관련된 코드가 없다. 

그럼 어떻게 Controller와 소통할 수 있는가?

 

몇 가지 방식 중에서 기본적으로 Model은 "Property Observer"를 통해 Controller과 소통할 수 있다. 

 

Controller 코드 내부에서 property를 정의할 때, observer를 이용하여 데이터 변화를 감지한다. 

이를 통해 Controller에서 해당 데이터를 가지고 View를 업데이트한다. 

var person: Person? {
    didSet {
        updatePersonViewFromPerson()
    }
}

private func updatePersonViewFromPerson() {
    guard let person = person,
          let personView = personView else {
        return
    }
    
    personView.nameField.text = person.name
    personView.ageField.text = "\(person.age)"
    personView.addressField.text = person.address
}

 

 

View는 어떤가?

View도 Model 이나 Controller에 접근할 방법이 @IBAction을 이용한다. 

@IBAction func updatePersonFromPersonView(_ sender: Any) {
    guard let name = personView.nameField.text,
          let age = Int(personView.ageField.text ?? "0"),
          let address = personView.addressField.text else {
        return
    }
    
    person = Person(name: name, age: age, address: address)
}

 

 

 

🟥 MVC 패턴의 문제점

  • View와 ViewController의 모호한 경계
  • 비대해지는 Controller 크기에 따른 test 어려움 

 

하나의 Scene에는 하나의 UIViewController를 할당한 클래스가 담당한다.

다른 Scene에서 사용하던 걸 재사용하지 않을 정도로 정해진 Scene에만 사용한다. 

 

각 객체들이 각 영역 안에서만 사용된다는게 아니다. 

구현을 하다보면 의외로 화면 출력, 데이터 처리를 Controller에서 하게 되면서 

사이즈가 커지고, 테스트 어려움으로 이어진다. 

 

 

🟥 MVC 패턴의 문제점 해결방안 

⭐ MVVM 패턴을 사용한다.⭐

 

 

✔ MVC 패턴

  • Model, View, Controller 구성
  • Model - 데이터 / View - 화면 표시 / Controller - 데이터 & 화면 표시 관리
  • Model, View는 각각 소통 안됨 / Controller 통해서만 가능 

'iOS > Swift' 카테고리의 다른 글

MVVM 패턴 (Model - View - ViewModel)  (0) 2024.05.30
고차함수 (Map, Filter, Reduce)  (0) 2024.05.26
확장 (Extension)  (0) 2024.05.24
클로저 6편  (1) 2024.02.17
클로저 5편  (1) 2024.02.13