[Swift] 메모 앱 만들기 심화 (5) : MVC 구조

Oni·2023년 9월 4일
0

TIL

목록 보기
35/47
post-thumbnail

원문 포스팅 🔗

MVC(Model-View-Controller)

MVC는 소프트웨어 디자인 패턴으로, 앱의 구성 요소들을 세가지 주요 컴포넌트로 분리하여 코드의 유지보수성과 재사용성을 높여준다.

Model(모델)

  • 앱의 데이터와 비즈니스 로직 담당
  • 데이터 모델링, 유효성 검사, 데이터 저장 및 관리 등의 역할
  • 화면과 상호작용하지 않으며, 화면 표현을 위한 정보가 없음
  • 변경 사항이 있을 때 컨트롤러에게 알리는 역할
struct Todo {
    var title: String
    var category: String
    var isCompleted: Bool
}

View(뷰)

  • 사용자 인터페이스와 데이터의 시각적 표현 담당
  • 사용자가 보는 화면 요소들을 구성하고 표시
  • 모델의 데이터를 보여주고, 데이터 변경사항을 반영
  • 컨트롤러에게 사용자의 입력과 이벤트를 알리는 역할
class TodoTableViewCell: UITableViewCell {
    // 테이블 뷰 셀을 커스텀하여 배치 - 사용자 인터페이스 및 시각적 표현
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var categoryLabel: UILabel!
    @IBOutlet weak var completionCheckmark: UIImageView!
}

Controller(컨트롤러)

  • 모델과 뷰 간의 중개자 역할
  • 사용자 입력을 받아 모델을 업데이트하거나 뷰를 갱신하는 역할
  • 모델의 변경사항을 감지하고 뷰에 반영하거나 뷰의 이벤트를 처리하여 모델을 업데이트
  • 뷰와 모델의 결합도를 낮춰 유연성을 높임
class TableViewController: UITableViewController {
    var todoList: [Todo] = []  // 모델 데이터
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // todoList 초기화 등의 로직
    }
    
    // 테이블 뷰 데이터 소스 및 델리게이트 메서드 구현
    // ...
    
    // 할 일 추가 버튼을 눌렀을 때 호출되는 메서드
    @IBAction func addTodoButtonTapped(_ sender: UIButton) {
        // TodoManager를 사용하여 할 일 추가
        TodoManager.shared.addTodo(title: "새 할 일", content: "", category: "일반", isCompleted: false)
        tableView.reloadData()
    }
}

MVC 구조는 상기와 같으나, 내가 개발한 코드는 View와 Controller가 거의 밀접하게 연관되어 대체적으로 ViewController에서 모든 로직을 수행하는 구조로 되어있다.
스토리보드로 앵간한 UI는 다 구현하다보니, View로 분류할 코드가 다 VC에 작성되어버렸다.
그리고 TodoManager 같은 경우에는 컨트롤러라고 볼 수 있지만, 데이터를 다루는 역할을 하기 때문에 모델로 분류했다.


MVC 장단점

장점

  • 분리된 역할: 각 컴포넌트인 모델, 뷰, 컨트롤러는 서로 다른 역할을 수행하기 때문에 코드의 가독성이 높으며, 이해하기 쉬움. 또한, 데이터 로직, UI, 비즈니스 로직이 분리되어 개발과 유지보수 용이
  • 유연상과 재사용성: 각 컴포넌트가 독립적으로 작동하므로 변경 사항을 다른 컴포넌트에게 영향을 주지 않고 쉽게 구현 및 교체 가능
  • 협업 용이: 역할 및 책임이 분명히 나누어져 있어 여러 개발자가 협업 시 코드의 충돌을 줄이고 독립적인 작업 가능
  • 테스트 용이: 개별 테스트 가능

단점

  • 복잡성: 프로젝트의 규모가 커지면 각 컴포넌트 간의 상호작용이 복잡해질 수 있음
  • 컨트롤러 부담: 컨트롤러는 뷰와 모델을 중재하고 로직을 처리하는 역할을 하므로 코드의 양이 많아질 수 있음
  • 유지보수 어려움: 어떤 경우에는 모델과 뷰 간의 의존성이 발생할 수 있음
  • 복잡성 처리 어려움: 크고 복잡한 앱에서는 MVC 패턴만으로는 모든 구조를 처리하기 어려울 수 있어 다른 아키텍처 패턴이나 구조를 고려해야 함

그외 소프트웨어 아키텍처 패턴

MVVM(Model-View-ViewModel)

  • MVC 패턴을 확장한 형태로 뷰와 모델 사이에 뷰모델이 추가됨
  • 뷰모델은 데이터 바인딩을 통해 연결되며, 뷰와 모델 사이의 중개자 역할을 하며 UI 로직을 처리
  • 데이터 바인딩을 통해 뷰와 모델이 동기화되므로 코드의 양을 줄이고 유연한 UI 구성이 가능

MVP(Model-View-Presenter)

  • MVP는 컨트롤러 대신에 프리젠터가 사용되는 패턴
  • 프리젠터는 뷰와 모델 사이의 중개자 역할을 하며, 뷰에서 사용자의 입력을 받아 모델을 업데이트하고 뷰를 갱신
  • 뷰와 프리젠터는 인터페이스로 연결되어 UI와 로직이 분리됨

VIPER

  • 뷰, 인터프리터(Interactor), 프리젠터, 엔티티(Entity), 라우터(Router)로 구성된 아키텍처 패턴
  • 모듈화와 각 역할의 분리를 강조하여 복잡한 앱에서의 유지보수와 확장성을 항상시킴
  • 각 구성 요소는 역할에 따라 엄격하게 구분되어 코드의 의존성을 최소화함

Clean Architecture

  • 클린 아키텍처는 내부부터 외부까지의 계층을 갖는 구조로, 비즈니스 로직과 데이터가 가장 안쪽에 위치하고 외부로 갈수록 추상화됨
  • 비즈니스 로직의 재사용성과 유지보수성이 높음

Flux, Redux

  • Flux와 Redux는 상태 관라 패턴으로, 어플리케이션의 상태를 중앙 저장소에서 관리하는 방식
  • 상태 변경을 예측 가능한 방식으로 처리하여 상태 관리의 복잡성을 줄임

이때까지 실습을 대체적으로 스토리보드로 UI를 구현하고 그에 따른 로직을 ViewController에서 작업하다보니 뷰와 컨트롤러의 경게가 모호해지는 일이 있었다.
하지만 복잡도나 어려움의 정도가 적어서 그대로 유지할 수 있었지만, 향후 프로젝트 규모가 커지면 스파게티 코드가 될 것 같아 벌써 아득해진다.
MVC 구조 외에도 여러가지 소프트웨어 아키텍처 패턴이 있으므로, 각 패턴(구조)의 장단점을 알아보고 최적의 구조를 선택해서 개발을 하면 될 것 같다!!

profile
하지만 나는 끝까지 살아남을 거야!

0개의 댓글