Flux 카툰가이드

원문
https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207#.9nbhrj3of

Flux 카툰가이드

플럭스는 현재 웹개발에 대한 토픽들중에 가장 유명하지만 이것을 이해하고 있는 사람은 매우 적다. 본 가이드는 모두가 이해할 수 있도록 도움을 주려 작성되었다.


문제

첫번째로 플럭스가 해결하는 기초적인 문제부터 설명하려고 한다. 플럭스는 어플리케이션에서 데이터를 다루는 패턴으로 리액트와 함께 페이스북에서 성장해왔다. 각각 독립적으로 사용이 가능하지만 많은 사람들이 둘을 함께 사용한다. 플럭스와 리액트는 페이스북에서 보여졌던 몇가지 문제점들을 해결하기위해 개발되었다.

가장 잘 알려진 그 문제들중 하나는 노티피케이션 버그이다. 페이스북에 로그인을 하게 되면 메세지 아이콘 위에 노티피케이션 카운트를 볼수있다.메세지 아이콘을 클릭해도 새로운 메세지는 없을것이다. 그후 노티피케이션은 사라진다. 사이트안에서 인터렉션이 조금 이루어지고 얼마 지나지 않아 다시 노티피케이션이 나타나게 된다. 다시 메세지 아이콘을 클릭하면 그대로 메세지는 없고 이런 현상이 반복해서 일어난다.

이미지1

이런 사이클은 사이트를 이용하는 유저한테만 발생하지 않았다. 페이스북 개발팀에서도 반복되는 사이클이 있었는데 그들이 이 버그를 고치면 잠시동안 모든게 괜찮아 보였다가도 또 다시 버그가 발생하였다. 이슈가 해결되고 다시 발생하기를 반복했다.

이미지2

페이스북은 이 사이클에서 벗어날 방법을 찾기 시작했다. 그들은 그냥 한번만 고치는것을 원하지 않았고 시스템을 예측 가능하게 만들어 이런류의 문제가 새로운 형태로 다시 나타나지 않길 원했다.


잠재적인 문제

페이스북팀이 찾은 잠재적인 문제는 어플리케이션안에서 데이터가 흐르는 방법이었다.

note: 이것은 내가 대화를 통해 얻어는 정보로 간단하게 구현한 것이다. 실제 아키텍처는 다를것이다.

Models pass data to the view layer

데이터를 들고 있어 뷰레이어에 데이터를 전달해 데이터를 그리도록 하는 모델들이 있다. 유저 인터렉션은 뷰를 통해서 일어나게 되기 때문에 뷰는 유저의 입력에 따라 모델을 업데이트해야 될때도 있다. 그리고 모델 역시 다른 모델을 업데이트 하기도 한다.

게다가, 가끔 이런 액션들은 연쇄적으로 변화를 일으키게 된다. 나는 이것을 흥미진진한 퐁 게임으로 상상했다.(공이 어디로 튈지 알기가 참 힘들다)

Views update models. Models update other models. This starts to look like a really edge-of-your-seat game of Pong.

심지어 이런 변화들은 비동기 적으로 일어날 수도 있다. 한가지의 변화가 여러개의 다른 변화를 발생시킬 수 있다. 나는 퐁 게임안에서 한꺼번에 던저져 여기저기 날라다니며 교차하는 핑퐁 공들로 상상해 봤다. 이런 상황에서는 데이터 플로우를 디버깅하기 힘들것이다.


해결책: 단방향 데이터 흐름

그래서 페이스북은 다른 종류의 아키텍처를 시도했다. 데이터를 한 방향으로만 흐르게 해서 만약 새로운 데이터를 추가해야 한다면 제일 처음부터 데이터가 다시 흘러가게 하는 것이다. 이런 아키텍처를 플럭스라고 이름지었다.

The diagram you’ll find in Facebook’s Flux docs. It is way cooler than it looks.

위의 다이어그램 만으로는 알수 없겠지만 사실 이건 매우 쿨한것이다.

플럭스를 이해하게 되면 이 다이어그램은 꽤 명확해질것이다. 완전히 플럭스에 대해 처음 접하게 되는 사람들에겐 이 다이어그램이 플럭스를 이해하는데 도움을 줄거라고 생각하지 않는다. 다이어그램은 상세한 것들을 알아가기전에 시스템의 큰 그림을 이해하는데 도움을 줄뿐이다.

내가 플럭스를 잘 이해하다록 도와준것도 이런류의 다이어그램이 아니라 각각 다른 캐릭터들이 목표를 이루기위해 팀으로 일을 하고 있다고 상상해 보는 것이었다. 그래서 내 머리속에 가지고 있는 각 캐릭터들을 설명해주고자 한다.


캐릭터들을 만나다

캐릭터들이 어떻게 서로 상호작용 하는지 알려주기 전에 각 캐릭터 소개를 먼저 하겠다.

액션 크리에이터(The action creator)

첫번째 캐릭터는 액션 크리에이터이다. 모든 변화와 인터렉션이 거쳐가는 통로의 시작이 되는 액션을 만드는 일을 담당한다. 앱의 스테이트를 변경하거나 뷰를 다르게 그리려면 액션을 만들어야 한다.

The action creator is like a telegraph operator. It formats your message for you.

액션 크리에이터는 일종의 telegraph operator이다. 액션 크리에이터로 하여금 기본적으로 어떤 메세지를 보내야 하는지를 알게하면 액션 크레이이터가 다른 시스템이 이해 할수 있는 방법으로 형식을 맞춘다.

액션 크리에이터는 타입과 페이로드(전달될 데이터)로 액션을 만든다. 타입은 시스템안에서 미리 정의된 액션(보통 상수 리스트로 정의)의 종류 인데 예를들면 MESSAGE_CREATE이나 MESSAGE_READ와 같은것 들이다.

시스템에서 가능한 모든 액션을 따로 모아서 관리하는 것은 추가적인 이점도 있다. 새로운 개발자가 프로젝트에 참여하게 되었을때 액션 크리에이터 파일들을 열어서 시스템이 제공하는 모든 API(모든 가능한 스테이트 변화들)를 볼 수 있다.

액션 메세지가 만들어지게 되면 액션 크리에이터는 그 액션을 디스패처에게 전달한다.

디스패처(The dispatcher)

디스패처는 간단히 말해 거대한 콜백 등록기이다. 일종의 전화 교환기 앞의 전화 교환수와 같다. 액션을 전달되어야 하는 스토어의 목록을 가지고 있으며 액션 크리에이터가 액션을 보내오면 액션을 각각의 스토어들에게 전달한다.

The dispatcher is like a switchboard operator. It knows all the callbacks for the different stores.

이런 작업은 동기로 이루어지는데 아까 말했던 멀티 볼 퐁 게임 효과 같은데 도움이 된다. 만약 스토어간에 디펜던시가 있어 업데이트가 되기전에 먼저 업데이트가 되어야 하는 관계가 있다면 디스패처의 waitFor()를 이용하면된다.

플럭스의 디스패처는 다른 많은 아키텍처에서 볼수있는 디스패처와 다르다. 액션이 모든 등록된 스토어들에게 액션 타입에 상관없이 전달 된다. 이 말은 스토어가 특정 액션만을 subcribe 하고 있는게 아니라는 뜻이다. 우선 모든 종류의 액션을 감지 하고있다가 관심을 갖는 액션에만 반응을 하는것이다.

스토어(The store)

다음은 스토어다. 스토어는 어플리케이션의 모든 스테이트를 가지고 있고 모든 스테이트는 스토어안에서 실시간으로 로직을 변경 한다.

The store is an over-controlling bureaucrat. All changes must go through it.

나는 스토어를 독단적인 관리자라고 생각했다. 모든 스테이트의 변화는 스토어에 의해 독자적으로 만들어져야한다. 그리고 직접적으로 스테이트를 변경하도록 요청할 수도 없다. 스토어에는 세터(setter)들이 없으며 스테이트를 변경하도록 요청하려면 정확한 절차를 따라야한다. 액션 크리에이터 디스패처 파이프라인을 통해 액션을 전달해야 한다.

위에서 언급한대로 스토어가 디스패처에 등록이 되어지면 모든 액션이 스토어로 전달된다. 스토어 안에는 보통 액션을 확인해 스토어가 관심 갖는 액션인지 아닌지를 결정하는 스위치문이 있다. 스토어가 관심을 갖고있는 액션이라면 해당 액션이 어떤 변화를 주어야하는지를 확인하고 스테이트를 업데이트 한다.

스토어가 스테이트에 변화를 주게되면 change이벤트를 발생하게 되고 컨트롤려 뷰에게 스테이트가 변경되었다고 알려준다.

컨트롤러뷰와 뷰(The controller view and view)

뷰들은 스테이트를 전달 받아 화면에 그려 유저들에게 보여주고 유저의 입력을 받는 역할을 한다.

The controller view is like a middle manager who gets notifications from the store and passes the data onto the views under it. The view presents that data to the user.

뷰는 프리젠터이다. 애플리케이션에서 벌어지는 일들은 어떠한것도 알지 못하고 오로지 다뤄야할 데이터에만 관심이 있고 이것을 사람들이 이해할 수 있는 형태로 보여주는 방법을 알고있다.(HTML을 통해)

컨트롤러뷰는 스토어와 뷰사이의 중간 관리자와 같다. 스테이트가 변경되면 스토어는 컨트롤러뷰에게 알려주고 컨트롤러뷰는 새로운 스테이트를 수집해 업데이트된 스테이트를 관련된 뷰들에게 전달하는 역할을 한다.


그들이 협업하는 방법

셋업

어플리케이션을 초기화하는 셋업작업을한다.(이 작업은 단한번만 이루어진다.)

1) 대스패처에게 액션이 들어올때 마다 스토어들에게 알려주게 한다.

2) 그리고 컨트롤러뷰가 스토어에게 최근 스테이트를 요청한다. 3) 스토어가 컨트롤러뷰에게 스테이트를 전달하면 각 차일트 뷰들에게 전달해 화면에 그리도록 한다.

4) 그리고 컨트롤러뷰는 스토어에게 스테이트가 변경되면 계속 알려달라고 요청한다.

데이터 흐름

셋업이 끝나면 어플리케이션은 유저의 입력을 받을준비가 된것이고 유저가 무언가 변경을 하면 액션을 발생 시킨다.

유저 인터렉션과 함께 데이터 플로우가 시작 될것이다.

1) 뷰는 액션 크리에이터에게 액션을 준비하라고 말해준다.

2) 액션 크리에이터가 액션을 구성하고 디스패처에게 보낸다.

3) 디스패처는 스토어에게 순서에 맞춰 액션을 전달한다. 각 스토어는 모든 액션을 전달 받고 스토어가 관심 갖고 있는 액션을 받게 되면 스테이트를 알맞게 바꾼다.

4) 스테이트가 변경이 되면 스토어는 자신을 subscribe하고 있는 뷰 컨트롤러에게 알려준다. 5) 뷰 컨트롤러는 스토어에게 업데이트된 스테이트를 요청한다.

6) 스토어에게 스토어를 전달받은 뷰 컨트롤러는 차일드 뷰들에게 알려줘 새로운 스테이트에 맞게 다시 그리라고 알려준다.

이것이 내가 생각하는 플럭스이다. 도움이 되었길 바란다.