iOS/Swift

[Swift] 아키텍처 Architecture(1) - MVC 패턴

YEN_ 2024. 1. 27. 00:42

 

 

🩵 아키텍처란?

아키텍처는 시스템 전체를 이해하고 설계하기 위한 체계적인 방법이며, 기본적으로 시스템의 구조와 조직을 결정하는 과정입니다.

다양한 측면에서 시스템을 분석하고 설계함으로써 특정 문제나 요구사항에 대한 효과적인 해결책을 찾아냅니다.

 

✔️ 구조 설계

  • 아키텍처는 기본적으로 컴포넌트와 모듈의 구조를 결정합니다.
  • 이는 각각의 역할과 책임을 명확히 정의하고, 이들이 어떻게 상호 작용하는지를 결정하는 과정을 포함합니다.

 

✔️ 상호 작용 및 데이터 흐름

  • 컴포넌트 간의 상호 작용과 데이터의 흐름을 명확히 정리합니다.
  • 이는 시스템의 효율성과 일관성을 유지하는 데 중요한 역할을 합니다.

 

✔️ 기능, 성능, 보안, 확장성, 유지보수성 고려

  • 아키텍처는 시스템이 수행해야 하는 기능을 충족시키는 것뿐만 아니라,
  • 성능, 보안, 확장성, 유지보수성 등과 같은 다양한 측면에서도 최적의 해결책을 제시합니다.

 

✔️ 시스템의 유연성과 확장성 고려

  • 미래에 대비하여 시스템이 쉽게 변화하고 확장될 수 있도록 아키텍처를 설계합니다.
  • 이는 기술의 변화나 추가적인 요구사항에 대응할 수 있도록 하는 것을 의미합니다.

 

✔️ 시스템 생명 주기 고려

  • 아키텍처는 시스템의 전체 생명 주기를 고려하여 설계됩니다.
  • 초기 개발 단계부터 유지보수 및 업그레이드 단계까지의 효과적인 관리가 가능하도록 구성됩니다.

 

아키텍처의 목적은 시스템을 효과적으로 구축하고 유지보수할 수 있는 설계도를 제공하는 것이며,

이를 통해 안정성과 성능을 극대화하며 시스템을 지속적으로 향상시킬 수 있도록 합니다.

 

 

 

 

 

 

 

 

 

🩵 MVC

 

 

MVC(Model-View-Controller) 디자인 패턴은 애플리케이션의 객체에 모델, 또는 컨트롤러의 세 가지 역할 중 하나를 할당합니다. 

패턴은 애플리케이션에서 개체가 수행하는 역할을 정의할 뿐만 아니라 개체가 서로 통신하는 방식도 정의합니다. 

세 가지 유형의 객체는 각각 추상적인 경계로 서로 분리되어 있으며, 이러한 경계를 넘어 다른 유형의 객체와 통신합니다. 

 

MVC는 Cocoa 애플리케이션 디자인 패턴의 기본이라고 보는 사람들이 많습니다.

쉽게 확장할 수 있고, 재사용이 용이하므로 인터페이스를 잘 정의할 수 있습니다.

 

 

 

✔️ Model

모델 객체는 애플리케이션에 관련된 데이터를 캡슐화하고 해당 데이터를 처리하는 로직을 정의합니다.

예를 들면 게임 캐릭터의 기본적인 정보같은 것들 말이죠.

struct GameUser {
    var name: String
    var job: String
    var hp: Int
    var mp: Int
}

 

다른 모델 객체와 관계를 가질 수 있으므로 애플리케이션의 모델 계층이 하나 이상일 수 있습니다.

struct Pet {
    var name: String
    var type: String
    var level: Int
    var hp: Int
    var owner: GameUser?

    // 펫이 사용자에게 특별한 스킬을 제공하는 기능이 있다면?
    func provideSpecialSkill(to user: GameUser) {
       
    }
}

 

이 예시에서는 GameUser라는 사용자 정보를 정의하고, Pet이라는 펫 정보를 정의하고 있습니다.

Pet에서는 owner를 통해 GameUser와 관계를 맺고 있죠. 

 

var player: GameUser = GameUser(name: "Yen", job: "Developer", hp: 100, mp: 50)

var pet: Pet = Pet(name: "Gamza", type: "Dog", level: 5, health: 80, owner: player)

 

이런 식으로 Pet 객체는 owner로 GameUser를 할당받을 수 있게됩니다.

 

또한, 일대다(One-to-Many) 관계를 가질 수 있습니다.

  • GameUser는 여러 마리의 반려동물을 소유할 수 있습니다.
  • Pet은 단 하나의 주인(GameUser)만을 가질 수 있습니다.

 

모델 객체는 특정 문제 영역과 관련된 지식과 전문 지식을 나타내기 때문에 유사한 문제 영역에서 재사용할 수 있습니다. 

이상적으로 모델 객체는 데이터를 표시하고 사용자가 해당 데이터를 편집할 수 있도록 하는 뷰 객체에 대한 명시적인 연결이 없어야 합니다.

 

즉, UI 문제에 관여하면 안 됩니다.

 

데이터를 생성하거나 수정하는 뷰 계층의 사용자 작업은

ViewController 객체를 통해 전달되어서 모델 객체가 생성되거나 업데이트됩니다. 

모델 객체가 변경되면(예: 네트워크 연결을 통해 새 데이터가 수신됨) 적절한 뷰 객체를 업데이트하는 컨트롤러 객체에 알려주기만 합니다.

 

 

 

 

✔️ View

뷰(View) 객체는 사용자가 애플리케이션과 상호작용할 때 보이는 부분을 담당하는 객체입니다.

주로 화면에 UI 요소를 표시하고 사용자 입력에 응답합니다.

 

 

  1. UI 구현
    • 뷰 객체는 자체적으로 화면에 그려지며, 사용자 인터페이스의 일부를 표현합니다.
    • 이는 주로 UI 요소들을 렌더링하고 배치하는 역할을 수행합니다.
  2. 모델 데이터 표시 및 편집
    • 주된 목적 중 하나는 애플리케이션의 모델 객체의 데이터를 사용자에게 표시하는 것입니다.
    • 예를 들어, 데이터베이스의 정보를 목록이나 테이블 형태로 보여주는 역할을 합니다.
    • 또한 사용자가 편집 가능한 UI 요소(텍스트 필드, 버튼 등)를 통해 모델의 데이터를 수정할 수 있도록 합니다.
    • 하지만 컨트롤러 객체와는 분리되어 있습니다.
  3. 컨트롤러 객체와의 상호작용:
    • 뷰 객체는 애플리케이션의 컨트롤러 객체와 상호작용하여 모델 데이터의 변경을 감지하고, 사용자 입력에 대한 응답을 처리합니다.
    • 변경된 데이터는 컨트롤러를 통해 모델로 전달되어야 하며, 사용자가 시작한 변경 사항(예: 텍스트 필드에 입력된 텍스트)도 마찬가지로 컨트롤러를 통해 처리됩니다.
  4. 작업 수행 X
    • 뷰 객체는 주로 화면의 표현과 사용자 입력을 다루는데 중점을 둡니다.
    • 따라서 뷰 객체 자체에서 실제로 어떤 작업을 수행하는 것은 아니며, 이러한 작업은 주로 모델과 컨트롤러에게 위임됩니다.

 

 

 

✔️ ViewController

컨트롤러 객체는 애플리케이션 내의 뷰 객체와 모델 객체 간의 중개자 역할을 수행합니다.

이를 통해 사용자 인터페이스와 데이터 처리 간의 효율적인 상호작용을 담당합니다.

 

import UIKit

class GameUser {
    var name: String
    var score: Int

    init(name: String, score: Int) {
        self.name = name
        self.score = score
    }
}

class GameViewController: UIViewController {

    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var increaseScoreButton: UIButton!

    var currentUser: GameUser = GameUser(name: "Player1", score: 0)

    override func viewDidLoad() {
        super.viewDidLoad()

        // 초기화면 설정
        updateUI()
    }

    @IBAction func increaseScoreButtonTapped(_ sender: UIButton) {
        // 버튼이 눌렸을 때의 동작
        currentUser.score += 10
        updateUI()
    }

    func updateUI() {
        // UI 업데이트
        nameLabel.text = "Player: \(currentUser.name)"
        scoreLabel.text = "Score: \(currentUser.score)"
    }
}

 

위의 코드에서 GameViewController는 게임 사용자(GameUser)와 관련된 데이터를 표시하고 수정하는 역할을 합니다. 

 

  1. GameUser 클래스는 게임 사용자의 이름과 점수를 나타내는 간단한 모델입니다.
  2. GameViewController는 사용자 인터페이스의 요소들을 정의한 IBOutlet들과 사용자의 상호작용에 대응하는 IBAction 메서드를 가지고 있습니다.
  3. increaseScoreButtonTapped 메서드는 버튼이 눌렸을 때 호출되며, 현재 사용자의 점수를 증가시키고 UI를 업데이트합니다.
  4. updateUI 메서드는 UI를 현재 상태에 맞게 업데이트합니다.

 

 

위의 예시로 알 수 있듯이,

뷰 컨트롤러 객체는 사용자 인터페이스와 데이터 모델 간의 상호작용을 다루는 것이 주 역할입니다.

 

 

  1. 중개자
    • 컨트롤러는 뷰 객체와 모델 객체 사이에서 중개자 역할을 수행합니다.
    • 사용자의 입력이 발생하면 컨트롤러가 이를 해석하고 그에 따른 작업을 수행합니다.
  2. 뷰에서 모델로의 변경 사항 전달
    • 사용자가 뷰에서 어떤 동작을 수행하면, 컨트롤러는 이 동작을 해석하고 모델에 대한 변경을 수행합니다.
    • 즉, 뷰에서 발생한 이벤트나 사용자 입력을 해석하여 모델 데이터를 갱신합니다.
  3. 모델에서 뷰로의 데이터 전달
    • 모델 객체의 상태가 변경되면, 컨트롤러는 이를 감지하고 새로운 데이터를 뷰에 전달합니다.
    • 이를 통해 뷰는 최신의 데이터로 업데이트되어 사용자에게 정확한 정보를 제공할 수 있습니다.
  4. 응용 프로그램 설정 및 조정
    • 컨트롤러는 응용 프로그램의 초기 설정 및 환경 조정과 관련된 작업을 담당합니다.
    • 예를 들어, 사용자 환경 설정, 테마 변경, 뷰 전환 등의 작업을 처리할 수 있습니다.
  5. 수명 주기 관리:
    • 다른 객체들의 수명 주기를 관리하고 필요에 따라 생성, 소멸을 조절합니다.
    • 특히, 뷰나 모델이 새로 생성되거나 해제될 때, 이러한 작업을 컨트롤러가 처리합니다.
override func viewDidLoad() {
    super.viewDidLoad()
    // 뷰가 로드된 후의 초기화 작업 수행
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // 뷰가 나타나기 전에 수행할 작업 처리
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // 뷰가 사라지기 전에 수행할 정리 작업 처리
}

deinit {
    // 뷰 컨트롤러가 메모리에서 해제될 때 수행할 작업 처리
}

 

 

🤫 정리 - MVC 

MVC는 애플리케이션의 아키텍처를 세 가지 주요 부분으로 나누어 설계하는 디자인 패턴입니다.

  • Model: 애플리케이션의 데이터와 비즈니스 로직을 담당
  • View: 사용자에게 보여지는 UI를 표현하며, Model의 상태를 표시
  • Controller: 모델과 뷰 간의 상호 작용을 관리하고 사용자 입력을 처리하여 Model을 업데이트하거나 뷰를 업데이트

MVC는 각 컴포넌트 간의 역할을 명확히 구분하여 코드의 재사용성과 유지보수성을 향상시키는 데 기여합니다.

그러나 너무 많은 로직이 컨트롤러에 집중되는 경우 오히려 복잡해지는 문제점이 발생할 수 있습니다.

 

 


 

 

 

MVC는 컨트롤러 객체에 많은 책임이 부과될 수 있다는 단점을 가지고 있습니다.

모델 관련 로직도 컨트롤러에서 작업되기 때문에 유지보수성도 떨어질 수 있구요.

 

MVVM(Model-View-View Model)은 이러한 MVC의 한계를 극복하고,

데이터 바인딩을 활용하여 뷰와 뷰모델 간의 강력한 연결을 제공합니다.

(뷰 모델에서 비지니스 로직을 전부 처리하게 되어 더 명확한 역할 분리가 가능해져요)

 

다음 게시글에서는 MVVM 패턴의 상세한 구성과 장점에 대해 더 자세히 살펴보겠습니다!

 

 

 

 

 

https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html

 

Model-View-Controller

Retired Document Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid. Model-View-Controller The Model-View-Controller (MVC) design pattern assigns objects in an ap

developer.apple.com