MVC 패턴은 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 널리 사용되는 소프트웨어 디자인 패턴입니다. 이 패턴은 비즈니스 로직과 화면을 구분하여 관심사 분리하는 것에 중점을 두었습니다.
모델, 뷰, 컨트롤러로 구성되며, 모델은 데이터와 비즈니스 로직을 처리하고, 뷰는 사용자 인터페이스를 표시하고, 컨트롤러는 모델과 뷰를 연결하여 데이터의 흐름을 관리합니다.
관심사를 분리한다는 목적은 충분히 달성하였지만 문제는 상태(Model)에 있었습니다.
위의 그림과 같이 MVC에서는 Controller에서 View로 양방향 바인딩을 하는 경우가 있는데 상태가 많아지고, 뷰가 복잡해지는 경우 이를 추적하는 것은 쉽지 않았습니다.
특히 페이스북의 경우 Model을 View와 직접적으로 양방향 바인딩을 하였는데 이는 MVC 패턴이 데이터의 흐름보다는 관심사의 분리를 중심으로 생각하는 아키텍쳐였기 때문이라고 생각합니다.
이러한 관심사 분리 중심의 관점이 어떠한 문제점을 야기하였는지 예시를 통해 알아보도록 하겠습니다.
MVC는 패턴, 아키텍쳐이므로 여러 해석이 있을 수 있지만 여기에서는 페이스북에서 사용한 MVC를 가정하도록 하겠습니다
위 그림에서는 메시지가 왔다는 상태를 여러 뷰에서 사용하고 있습니다.
1번 뷰
에서는 각 사용자로부터 읽지 않은 메시지가 얼마나 있는지 보여주고 있고, 2번 뷰
에서는 읽지 않은 메시지가 전체 몇개인지 보여주고 있습니다. 3번 뷰
에서는 각 사용자에 대한 채팅 기록을 보여주고 있습니다.
메시지가 온다면 1번 뷰
와 2번 뷰
에서 읽지 않은 메시지 수가 증가해야하지만 3번 뷰
에서 해당 채팅방을 보고있다면 증가하지 않아야합니다.
다음과 같은 메시지 서비스에서 Jack
님이 저에게 메시지를 하나 날리는 경우를 생각해 봅시다 !
메시지가 오면 새로운 채팅 기록과 안읽은 메시지의 상태가 업데이트되고 이에따라 뷰가 바뀌게 됩니다.
하지만 Jack
님과의 채팅창이 3번 뷰
에서 열려있기 때문에 즉시 읽은 상태로 바뀌게 되고 읽지 않은 메시지가 감소해야합니다.
3번 뷰
가 모델을 변경하였고, 이에따라 1번 뷰
와 2번 뷰
도 변경 되었지만 데이터 흐름의 순서를 한눈에 파악하기는 쉽지 않습니다.
지금은 간단한 예시이기 때문에 눈으로 확인 할 수 있지만 실제 시스템은 이보다 훨씬 복잡할 것이고, 그러한 구조에서 기능을 추가하는 것은 해당 시스템을 완벽하게 이해하고 있는 몇몇 개발자를 제외하면 불가능 할 것입니다.
그래서 facebook은 MVC
는 확장성이 없다(unscalable)라고 표현했습니다.
해당 부분이 많은 분들이 페이스북이 MVC를 잘못 사용하고 있었다 라고 하는 부분입니다.
처음 MVC를 소개드렸던 것처럼 View가 Controller를 통해 Model을 업데이트 하지 않고, 직접적으로 Model을 업데이트 하고 있다는 것이죠 !!
전통적인 MVC ( Controller를 통해서만 Model을 업데이트 )의 경우 이러한 문제가 생기지 않을 수 있지만 MVC는 패턴, 아키텍쳐 일 뿐 코딩 스타일을 제한하는 Prettier, ESLint 같은 것이 아닙니다.
MVC는 관심사 분리를 중요하게 생각하였고, 이에 따라 전통적인 MVC와는 다른, 페이스북과 같은 다른 해석이 등장하였다고 생각합니다.
Flux
에서는 데이터의 흐름
에 집중하였습니다.
MVC
에서는 View
에서 Action
이 일어날 수 있다 정도로만 정의를 하였지만 Flux
에서는 View
에서 발생가능한 모든 Action
을 정의합니다. (정확히는 Dispatcher
를 호출할 수 있는 모든 Action
을 의미합니다.)Action
이 Store
로 흐르게 하는 역할을 합니다. 역할 자체가 특별한 것은 아니지만 그럼에도 불구하고 꼭 필요한 이유는 store의 의존성 관리
에 있습니다. store
는 다른 store
의 업데이트가 끝날 때까지 선언적으로 기다릴 수 있고 끝나는 순서에 따라 스스로 갱신됩니다.MVC
에서 Model
과 같은 역할을 합니다. Store
는 action
을 dispatch
하는 방식으로만 상태를 바꿀 수 있습니다.정리하자면 아래와 같습니다.
먼저 메시지가 오는 경우는 동일합니다. action
이 dispatcher
를 거쳐 store
의 상태를 바꾸게 되고 이에따라 view
가 바뀌게 됩니다.
차이점은 다음의 상황에서 확실하게 체감 할 수 있습니다.
3번 뷰
에서 action
이 일어났고 이에 따라 바뀐 store
와 view
가 정확하게 파악이 됩니다.
action
과 dispacher
가 정의되어 있기때문에 디버그도 훨씬 쉬워질 것입니다.
위의 예시처럼 데이터를 단방향으로만 흐르게 하는 것은 서비스를 이해하고, 디버그를 하는 관점에서 많은 도움이 됩니다.
제 생각에는 Flux 패턴
과 MVC 패턴
은 크게 다른 것 같지 않습니다.
기존의 전통적인 MVC 패턴
과 동일하게 Model
과 View
를 완전히 분리 시켜 Controller
에서만 Model
을 바꾸게 하고, View
에서는 바뀐 상태를 가지고 렌더링 한다면 지금의 Flux
와 거의 동일한 기능을 할 것입니다.
그럼에도 불구하고 Flux
가 탄생을 할 수 밖에 없었던 이유는 MVC
에서는 데이터의 흐름을 정확히 정의하지 않았기 때문인 것 같습니다.
누군가는 Flux 패턴
의 탄생이 Facebook이 MVC 패턴
을 잘못 이해하고 있었기 때문이고 실제로 MVC 패턴
으로도 충분하다고 말합니다.
하지만 기존의 모호했던 MVC 패턴
의 데이터 흐름을 명료하게 추상화하고 이해하기 쉽도록 했다는 점에서 충분히 의의가 있다고 생각합니다.
유익한 글 감사합니다 :)