반응형
이 게시글은 공부한 내용을 정리한 것으로 수익창출을 하지않습니다.
역할이 명확히 구분된다면 좋겠지만 실상은 그렇지 못하다.
1. Apple의 MVC는 View와 Controller가 너무 밀접하다.
Apple의 MVC에서는 ViewController
라는 이름에서도 볼 수 있듯이 View와 Controller가 굉장히 밀접하게 연결되어있다. ViewController는 Controller의 역할뿐만 아니라 View의 life cycle에도 관여하고 있는 것이 현실이다.
이때문에 Model은 분리하여 테스트를 할 수 있어도 View와 Controller는 서로 강하게 연결되어있어 테스트가 어렵다.
2. 뷰, 모델에 맞지 않는 모든 비즈니스 로직들은 Controller에 들어가게 된다.
모델이나 뷰에 넣기 애매한 코드들은 모두 Controller에 들어가게 되는데 이렇다보니 Controller가 비대해질 수 있다.
이를테면 서버에서 받아온 데이터를 가공(포매팅)해서 뷰에 넘겨주는 로직이나 사용자로부터 들어온 interaction을 처리하여 모델/뷰에 넘기는 로직 등, 화면에 보이는 것과 데이터 이외에는 모두 ViewController가 처리하게 된다.
- Clint Jang블로그에서 설명하는 MVC의 한계
- MVC에서 View는 Controller에 연결되어 화면을 구성하는 단위요소이므로 다수의 View들을 가질 수 있다. 그리고 Model은 Controller를 통해서 View와 연결되어지지만, 이렇게 Controller를 통해서 하나의 View에 연결될 수 있는 Model도 여러개가 될 수 있다.
- → 뷰와 모델이 서로 의존성을 띄게 된다.
- 즉, 화면에 복잡한 화면과 데이터의 구성 필요한 구성이라면, Controller에 다수의 Model과 View가 복잡하게 연결되어 있는 상황이 생길 수 있다.
- View와 Model이 많아지는 상황에서 발생할 수 있는 문제는 2번 맥락에서도 이해해볼 수 있다.
Controller
는View
에서 들어오는 사용자 입력을 처리하고,Model
의 데이터 업데이트를 알아차린 뒤 이를View
에 넘기는 작업들도 수행한다고 했었다. 당연히Controller
에 연결된View
와Model
들이 많아지면 해당 작업들에 대한 코드들이 늘어나는 것이 당연하고Controller
가 커지는 것은 어찌보면 피할 수 없다.
💡 위와 같은 이유들때문에 MVC를 Massive View Controller라고 말하곤 한다. 하지만 MVC가 항상 그런 것은 아니다. MVC도 충분히 클린하게 코드를 짤 수 있다고 한다.
Questions
- "MVC에서 View는 다른 컴포넌트를 알면 안되는데, Apple의 MVC에서는 이벤트 처리를 위해 View가 Controller를 아는 형태로 구현되지 않나요??"→ (
View
는Controller
를 직접적으로 알지 못하고 오직Protocol
만을 알고 있다) - → 날카로운 질문이다. 하지만 Apple은 이 문제를
Delegate 디자인 패턴
이라고 하는 아주 우아한(?) 방식으로 해결하였다.Protocol
을 선언하고View
는 해당Protocol
만을 아는 형태로 만든 뒤,Controller
로 처리할 책임을 위임하였다. 즉, 의존성 역전 원칙(DIP)을 이용하여View
와Controller
간 의존성을 떨어뜨렸다. - "Controller 또한 View를 알고 있는 형태로 만들어지는데, View도 Controller를 알고 있다면 reference cycle이 생기지 않나요?"(단, 직접 delegate pattern을 구현하여 적용하는 경우, cycle이 생기지 않도록 우리가 만들어줘야 한다)
- → 결론부터 말하자면 발생하지 않는다.
UIKit
내에 있는 여러View
요소들이Controller
를 참조하는 방식은weak reference
이다. - "Delegate Pattern이 아닌 Target-Action으로 View가 Controller를 알도록 하는 것은요? reference cycle 문제가 없나요?"→ UIControl - addTarget(_:action:for:) 문서에 이 질문에 대한 해답이 나와있다.
- "Model도 다른 컴포넌트를 몰라야 한다고 하는데, 그럼 Controller는 Model의 변화를 어떻게 감지하나요??"
- → 여기에는
KVO
,NotificationCenter
같은Observer Pattern
이나,Delegate Pattern
등 여러가지 방법이 있겠지만 나는 클로저를 이용한completionHandler
를 주로 쓴다.(callback) 특별히 뭔가를 별도로 구현해 줄 필요가 없다는 점에서 굉장히 편리하다. 👍 (물론 capture에 따른 reference cycle은 별도로 고려해주어야 한다!)
다른 패턴에서도 같은 문제가 발생할 수 있다.
위에서 말한 MVC의 이러한 문제들 때문에 다른 패턴을 쓰는 것만이 유일한 해결책인 것처럼 보일 수 있다.하지만 나는 그렇게 생각하지 않는다. 다른 패턴을 쓴다고 하더라도 비슷한 문제는 발생할 수 있다.
- 이를테면 MVVM을 쓴다고 하더라도 ViewModel이 비대해질 수 있다.
- VIPER패턴이 무엇인지는 아직 잘 모르지만 해당 패턴을 쓴다고 하더라도 Interactor가 비대해지는 문제가 생길 수 있다고 한다.
최선 → 비대해지는 객체를 적절히 분리
MVC 패턴을 적용했을 때 ViewController
가 너무 비대해진다면 해당 ViewController
를 단일책임원칙(SRP)에 따라 여러개의 ViewController
로 나누어보자!
반응형
'모바일앱 > iOS' 카테고리의 다른 글
얼럿 addAction 한번에 추가하기 (0) | 2022.04.04 |
---|---|
네비게이션 컨트롤러 NavigationController 사용하기 (0) | 2022.03.26 |
[Gesture Recognizer] Long Press (3) | 2022.03.25 |
URLSession에 대하여 알아보기 (0) | 2022.03.23 |
비즈니스 로직 (0) | 2022.03.21 |
TIL 로컬라이징, 써드파티 (0) | 2022.03.19 |
로그를 출력할 때 사용하는 함수들 (0) | 2022.03.18 |
error - Command CompileSwiftSources failed with a nonzero exit code (0) | 2022.03.18 |