-
Design Pattern - MVC 패턴Programming/Design Pattern 2022. 3. 20. 16:33
안녕하세요 BeePeach입니다.
오늘 공부해볼 내용은 디자인 패턴 중에서 가장 기초적인 MVC 패턴입니다.
MVC 패턴은 UIKit 프레임워크를 사용할 때 Apple에서 기본적으로 사용하고 있는 패턴입니다.
Apple developer 사이트에서도 UIKit에 관한 document를 보면 core app object들이 MVC 패턴으로 되어있는 것을 확인할 수 있습니다.
그럼 MVC 패턴이란 무엇이고 어떤 특징이 있는지 같이 공부해보도록 해요!
MVC
MVC는 Model, View, Controller의 줄임말입니다.
각각의 객체를 이용해서 application을 개발하게 됩니다.
그럼 각각 어떤 역할을 하는지 보겠습니다.
Model은 application의 data를 관리합니다.
주로 struct, class로 만들게 됩니다.
View는 화면과 control를 스크린을 통해 보여주는 역할을 합니다.
주로 UIKit을 상속하게 됩니다.
Controller는 View와 Model을 조율하는 역할을 합니다.
View와 Model이 직접적으로 소통하는게 아니라 Controller를 통해서 소통하게 됩니다.
주로 UIViewController를 상속합니다.
클래스 다이어그램으로 표현해보면 아래와 같습니다.
그럼 각각 객체에 대해서 조금만 더 자세히 보도록 하겠습니다.
예시들을 보기전에 알아야 할 부분이 있습니다.
이 예시들은 Playground로 작성됐습니다.
그리고 우리가 실제로 앱을 개발할 때와 구현이 살짝 다를 수 있습니다!
이 예시는 각각 객체가 나름? 이상적으로 분배되어 있는 경우입니다.
Model
Model은 데이터만 관리합니다.
View에 대해서는 모르고 있죠.
그냥 데이터만 관리하는 객체입니다.
예시를 보도록 하겠습니다.
Person이라는 구조체를 정의했습니다.
이 코드에 View 또는 Controller에 관한 코드가 있나요??
전혀 없습니다.
Model은 그냥 데이터만 관리합니다.
View
View는 화면 표시에만 관심이 있습니다.
Model에 대해서는 모릅니다.
그냥 받은 데이터로 화면을 구성하는데에만 관심이 있습니다.
UIView를 상속하는 PersonView라는 CustomView를 정의했습니다.
여기서도 마찬가지로 Model 또는 Controller에 관한 코드는 전혀 없습니다.
Controller
Controller는 이 둘 사이를 관리합니다.
Model의 데이터를 이용해서 View가 알맞은 화면을 구성하도록 만들어줍니다.
그리고 Model의 데이터가 변경되면 이를 View에게 적용되도록 만들어줍니다.
또는 반대로 View를 통해서 어떠한 액션이 발생했다면 이를 Model에게 전해줘서 데이터를 변경하게 만듭니다.
Controller는 View와 Model을 참조를 통해 소유할 수 있습니다.
그리고 1개의 Controller는 여러 개의 View와 Model을 소유할 수 있습니다.
그리고 이 참조를 통해서 해당 View 또는 Model에 바로 접근할 수 있습니다.
예를 들어서 Model의 data가 변경됐으니까 View에게 이걸 바꿔야 해라고 할 수 있죠
Model에게도 Action이 발생했는데 그럼 이 data를 변경해야겠는데? 하고 바로 변경할 수도 있습니다.
이 로직이 모두 Controller안에 들어가 있습니다.
UIViewController를 상속하는 PersonViewController를 생성했습니다.
여기서는 각각 1개의 Model, View를 person, personView 프로퍼티로 소유하고 있습니다.
그리고 각각 직접 접근해서 person 데이터를 이용해서 View를 업데이트하거나 View로 액션을 받아서 person 데이터를 수정하고 있습니다.
View나 Model이 서로 직접 소통하는게 아니라 Controller를 통해서 소통하고 있습니다.
Model과 View가 Controller와 소통하기
그럼 이번에는 반대로 생각해보겠습니다.
View와 Model은 Controller를 소유하지 않았습니다.
그럼 Controller와 어떻게 소통할까요??
Model의 입장에서 생각해봅시다.
우리는 View나 Controller를 모릅니다.
그냥 데이터를 정의하고 저장하고 변경할 뿐이죠.
여기서 Controller 또는 View에 접근하는 코드는 없습니다.
그럼 데이터가 변경됐는데 Controller에게 이걸 어떻게 전달해줄까요??
몇 가지 방식이 있겠지만 기본적으로 Model은 Property Observer를 통해서 Controller와 소통할 수 있습니다.
Controller안에서 이런 코드가 있었습니다.
Controller에서 프로퍼티를 정의할 때 observer를 이용해서 데이터가 변화가 생겼다고 알려줄 수 있고 Controller에서 그 데이터를 가지고 View를 업데이트할 수 있게 됩니다.
그럼 이제 View의 입장을 볼까요?
View도 Model 또는 Controller에 접근할 방법이 없습니다.
그럼 어떻게 Controller에게 어떤 변화 또는 이벤트가 발생했다고 말해줄 수 있을까요??
바로 @IBAction을 이용해서 Controller와 소통합니다.
뭔가 터치가 발생했어!(touchUpInside) 등등 액션 여부를 Controller에게 전달할 수 있게 됩니다.
이렇게 어떤 액션이 발생했다면 Controller는 필요에 따라 Model의 데이터를 변경할 수 있도록 만들 수 있습니다.
이러한 구조로 인해서 Model과 View는 재사용성이 높아집니다.
서로를 모르고 Controller도 참조하지 않기 때문에 다른 Controller에서 사용해도 괜찮습니다.
어디서든 사용할 수 있는 거죠.
MVC 패턴의 문제점
그럼 MVC 패턴의 문제는 어디에 있을까요?
바로 Controller에 있습니다.
Controller의 로직은 특정됩니다.
말이 조금 어려운데..
우리가 앱을 만들 때를 생각해보면 명확해집니다.
Storyboard의 하나의 scene에 대부분 하나의 UIViewController를 상속한 class를 할당합니다.
다른 Scene에서 이전에 사용하던 UIViewController class를 사용하지 않습니다.
왜냐면 다른 곳에서 재사용할 수 없을 정도로 그 Scene에 특화되어 있거든요.
이렇게 MVC 패턴에서는 Controller를 재사용하지 않습니다.
하지만 이 안에 사용되는 View 또는 Model들은 다른 UIViewController에서 재사용하는 경우는 흔합니다.
또 다른 MVC패턴의 문제는 각 객체들이 각 카테고리에 딱 들어맞지 않는다는 겁니다.
그래서 구현을 하다 보면 Controller가 대부분을 담당하게 되면서 매우 커지게 됩니다.
심지어 iOS에서 사용하는 Controller의 이름이 ViewController이죠??
iOS에서 사용하는 MVC 패턴은 View와 ViewController의 경계가 모호해지면서 화면에 출력하는 것까지 Controller가 담당하게 됩니다.
심지어는 데이터까지 Controller에서 처리해버리는 상황도 발생합니다.
이렇게 되면서 Controller는 프로젝트가 진행될수록 매우 매우 커지게 됩니다.
이렇게 되면 Controller를 test 하는 것은 매우 힘든 작업이 됩니다.
테스트를 하려고 하면 대부분 View와 관련이 되어서 UnitTest를 해야 할지 UITest를 해야할지 헷갈리기까지 합니다.
그래서 이 문제를 해결하기 위해서 다른 디자인 패턴을 활용하게 됩니다.
여기서 나오는 게 바로 MVP와 MVVM 패턴입니다.
실제 프로젝트 예시
그럼 우리가 대부분 사용하는 MVC의 예시를 간단한 프로젝트를 통해서 알아보도록 하겠습니다.
참고 자료
https://www.raywenderlich.com/1941154-fundamental-ios-design-patterns
https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52
728x90