 Apple Lover Developer & Artist

영속적인 디자인에 현대의 공감을 채워넣는 공방입니다

 Apple/Stanford iOS Programming (UIKit)

Lecture 2 Review: MVC

singularis7 2021. 12. 2. 14:17
반응형

Overview

객체지향 디자인 패턴 중 MVC 를 다뤄본다. 컨셉에 대해서 배워보자!

Model View Controller 역할

  • 시스템 내부에 있는 객체들을 3가지의 캠프로 나눈 것이다.
  • 파란색으로 표시된 Model 캠프는 UI와 독립적인 객체들의 집합이다.
  • What your application is (but not how it is displayed)
  • Concentration 게임의 예시로 어떻게 게임이 진행되는지 알고 있는 영역이다.
  • 어떻게 카드를 math 시키고 제거하는가?, 언제 카드를 뒤집어야하는가?
  • 다만 어떻게 화면에 보여져야 하는지에 관한 내용은 없어야한다.

  • 어떻게 화면에서 보여주는지에 관한 책임은 Controller 캠프에 있다.
  • How it shows up on screen.

  • View 캠프는 Controller 의 미니언 같은 존재이다.
  • 이것들은 매우 제네릭한 UI 요소이다. 
  • 예를들어 UIButton, UIViewController, UILabel 이 존재한다.
  • 컨트롤러가 모델과 대화해서 데이터를 받아온 후에 UI로 담아줍니다.
  • 따라서 View 는 Controller 의 제네릭 미니언이다.

MVC 캠프 간의 소통 방법

  • MVC 는 Model, View, Controller 사이에서 커뮤니케이션을 관리해주는 모든 것에 관한 내용이다.
  • 위에서 보이는 3가지 캠프에 들어간 객체들은 서로 소통할 때 특정한 Rule 을 따라야 한다.
  • 위 그림에서는 도로에서 사용되는 신호가 사용되었다.
  • 위 캠프 사아에 어떤 종류의 커뮤니케이션이 허용되는지 표현하기 위해서이다.

Controller -> Model

  • 컨트롤러는 언제나 모델에게 말을 걸어줄 수 있으며 이 작업은 반드시 가능해야 한다.
  • 컨트롤러의 역할이 모델에 존재하는 무언가 모델로 부터 받아와서 View 에 보여주는 것이기 때문이다.
  • 위 그림에서 초록색 큰 화살표로 표현되어있다.

Controller -> View

  • 컨트롤러는 자신의 미니언을 통제할 수 있어야 한다.
  • 위 그림에서 초록색 큰 화살표로 표현된 개념이 InterfaceBuilder 에서 설정해준 Outlet 이다.
  • UI에게 원하는 것에 대하여 전달할 수 있는 방법이다.
  • 컨트롤러는  Model과 View 모두와 소통할 수 있는 존재이다.

Model 과 View 는 서로 소통할 수 있는가?

  • 정답은 불가능하다.
  • Model 은 UI와 독립적인 친구이다.
  • 반대로 UI는 자신과 독립적인 관계에 타입과 소통할 수 있는 방법은 존재하지않는다.
  • 다른 이유로, 버튼과 슬라이더 같은 View 는 Generic 객체이기 때문이다.
  • 어떻게 버튼이 Concentration 게임에 관한 어떤 아이디어를 가질 수 있겠는가?
  • 제네릭이기 때문에 방법 없다.
  • 따라서 Model과 View 사이에는 어떠한 소통 관계도 있으면 안된다.
  • 그림에서도 절때 건너지 말라는 의미에 도로 표시 중앙선이 그려져있다.

View -> Controller

  • View 가 Controller 에게 말을 걸 수 있는 방법은 무엇이 존재하는가?
  • 우선 View 는 Controller 에게 말을 걸 수 있어야 한다.
  • 버튼이 클릭될 때 무슨 일을 해야할지 정의할 수 있어야하기 때문이다.
  • 하지만 View 가 Controller 에게 메시지를 날리는 방법은 Blind 된 방식의 구조를 갖고 있다.
  • blind 여야 하는 이유는 View 가 Generic view 객체이기 때문이다.
  • UIButton 은 Concentration 에 관한 어떠한 내용도 알지 못한다.
  • 같은 논리로 ViewController 에 관한 어떠한 내용도 알지 못하는 구조이다.
  • Generic 객체가 Controller 객체와 통신하는 방법에 대해서 좀더 생각해보아야 한다.

  • 우리는 그 방법 중 하나를 이미 알고 있는데 target - action 이 해당된다.
  • 스토리보드에서 UI 객체를 클릭해서 컨트롤 키를 누르고 드래그하여 생성한 메서드가 예시이다.
  • 컨트롤러가 해야할 일은 자신에게 target 을 정의해둔 후에 View에서의 action 을 전달한다.
  • 따라서 버튼을 누를 때마다 target 을 호출한다.

  • 때로는 좀더 복잡한 통신을 하는 경우가 있을 수 있다.
  • 스크롤 뷰와 같은 복잡한 뷰를 사용할 때에는 더 복잡한 통신 방법이 필요할 수 있습니다.
  • 스크롤 뷰는 일부 이미지나 이와 유사한 것들을 스크롤하고 있으며 이 사실을 컨트롤러에게 알려야 할 수 있다.
컨트롤러야! View인 나는 끝까지 Scroll 했는데 여기서 더 스크롤해도 되는거야?
컨틀롤러야! 세로 혹은 가로로 스크롤해도 되는거야?
  • 위 과정이 동작하는 원리는 ScrollView에 delegate로 사전에 메서드를 정의하는 방식을 통해 이뤄진다. 
  • delegate 는 ScrollView의 변수일 뿐이며 일부 개체가 존재한다.
  • 우리가 이 개체에 대해 알고 있는 사실은 특정 수의 메시지에 응답한다는 점이며 Will, Should, did 로 시작된다.
  • 고전적인 delegate 메서드 들이다.
여기로 스크롤 할 것입니다. 
여기로 스크롤 해야합니까?
여기까지 스크롤을 내렸습니다.

  • 프로토콜이라는 메커니즘을 사용하는 컨트롤러를 통해 스크롤 뷰에게 말하는 방법도 있다.
  • ScrollView는 아무것도 모르지만컨트롤러가 delegate 를 통해 어떤 것을 구현하고 있는가에 관한 것만 알고 있다.
ScrollView 야 Controller 인 나는 너의 delegate 야! 너가 요구하는 모든 것을 내가 구현하고 있어!

MVC 를 사용할 때 주의해야할 점!

  • Generic 타입인 View는 자신이 소유하는 데이터를 소유할 수 없다는 것이다.
  • 즉, 인스턴스 변수의 일부로 표시하는 데이터를 갖지 않을 것이다.
  • 왜? 이딴 짓을 하는가? -> 5,000 만 곡의 iPod 음악 데이터를 담는 List 를 상상해보아라!
  • 모든 노래를 불러오기 위해 뷰를 나열하는 것은 이치에 알맞지 않는다.
  • 따라서 delegate 와 같은 프로토콜 메커니즘을 사용하여 데이터를 요청하는 메시지 집합을 사용한다.
  • 이 방식으로 모델과 소통하여 뷰에 대한 데이터를 가져올 수 있다.
컨트롤러에게 특정 데이터를 요청하거나
들어가야할 항목이 몇개가 있는지 물어본다!

  • 대표적인 예시로 테이블 뷰가 있는데, Scrolling 할 수 있는 List 의 일종이다.
  • 테이블 뷰는 현재  화면에 표시되는 항목만을 불러오도록  설계되어있다!
  • 예를들어 5,000만곡의 노래에서 10곡 정도만 표시되도록 스크롤 한다.
  • View 는 다음에 와야하는 10개의 데이터를 컨트롤러에게 요청하고
  • 컨트롤러는 모델로 돌아가서 (아마도 훌륭한 SQL 데이터베이스일 것이다.) 데이터를 받아 뷰에게 전달한다.
  • 테이블 뷰가 iPod 음악앱인 것에 대해 알지 못하는 것과 같은 이치이다.
  • 데이터를 제공해주는 것만 알고 있으며 이런 종류의 대리자를 data source 라고 부른다.
  • 데이터 소스와 delegate 는 매우 유사하지만 일종의 다른 메서드 집합이다.
  • 메서드의 세부 종류는 UI 요소의 종류에 따라 다르다.
  • View가 Controller 와 소통할 수 있는 사전에 정의된 방식이다.

Controller 의 역할?

  • MVC에서 컨트롤러가 하는 작업은 다음과 같다.
  • 뷰에 대한 모델의 정보를 해석(Interpret)하고 형식(format)을 지정하는 것 <- 주요한 목적이다
  • 뷰에 대한 사용자의 상호작용을 해석합니다.
  • 앞뒤로 해석해주며 모든 커뮤니케이션의 중심이다.

Model -> Controller ?

  • 모델이 컨트롤러에 직접 말을 걸어줄 수 있을까? -> 직접적으로 소통하는 방법은 존재하지 않는다.
  • 모델은 UI 독립적인 요소여야만 하는데 컨트롤러가 이미 UIdependent 하기 때문이다.
  • 일부 데이터가 변경되었을 때 관심있는 UI가 갱신되도록 통신할 수 있는 메커니즘이 존재한다.
  • iOS 에서 Notification, KVO 로 불리는 도구를 사용한다.
  • Radio-Station broadcast 메커니즘을 사용하는 방법이며 자세한 동작 방법은 다음과 같다.
  1. 특정 라디오 방송국에서 방송을 시작한다.
  2. 컨트롤러는 Model 에 주파수를 고정하고있다.
  3. Model 방송국에서 뭔가 변경되었다는 메시지가 들리면 Controller -> Model 화살표를 활용해 모델과 대화할 수 있다.
  4. 변경된 데이터를 받아서 뷰에 반영한다.
  • 그렇다면 View 도 방송국의 주파수를 잡고 있을 수 있는가?
  • 뷰는 컨트롤러나 다른 방송국의 주파수를 잡을 수 밖에 없다.
  • 뷰는 UI 의 기본이기 때문이지만 흔하지는 않다.
  • 방송국 모델은 모델이 데이터에서 발생한 일을 전달하는 방식이기 때문이다.

  • 이와 같은 MVC 는 일반적으로  iPhone 또는 iPad 에서 하나의 화면만 제어하기 위해 사용됩니다.
  • 물론 iPad 에서는 화면의 부분마다 서로 다른 MVC 가 제어하는 경우가 존재한다.
  • 하지만 단일 MVC로 제어되는 iPhone의 한 화면에서 두개 이상의 화면을 만들 수는 없다.
  • 따라서 MVC 의 종류는 UI 그룹화와 함께 진행된다.
  • 대부분의 앱에는 수많은 화면이 존재하는데, 여러가지 MVC가 존재하는 화면을 만드려면 어떻게 해야하는가?

  • 서로 다른 MVC가 상호작용하기 원한다면 항상 다른 MVC를 View의 일부로 취급한다.
  • 따라서 위 화면에 초록색 화살표로 연결된 3개의 MVC는 View 의 일부이다.
  • 따라서 상위 컨트롤러와 View 처럼 Blind 되고 구조화된 방식으로 소통해야하며
  • View 처럼 일반적이고 재사용 가능한 구성요소로 작동한다.

  • 아무렇게 막 설계하면 디버그하고 내부에서 어떤 동작이 발생하는지 알아내기 어렵기 때문이다.
  • 처음에 보여준 방식으로 그룹화하면 전화기의 각 화면이 잘 포함되며 이해하기 쉽고 디버깅이 가능하며 관리하기 쉽다.
반응형