Web/techTalk

[React] Atomic, Container Presenter 어떤 디자인패턴을 써야할까?

레에몽 2022. 3. 18. 14:32

패턴에서는 세부 사항은 해당 글에서 자세하게 다루지 않을 예정입니다. 편의를 위해서 Container Presenter패턴은 PC라고 불러 얘기할 예정입니다. 추가적으로 리액트에서는 커스텀 훅이라는 마법이 있어 모든 단점을 보완할 수 있다고 생각하나, 두 패턴의 장단점을 비교하기 위해 커스텀 훅의 존재는 잠시 배제할 예정입니다.

 

Container Presenter

 React의 대가인 Dan Abramov가 2015년에 제시했던 디자인 패턴입니다. Container에서 논리적인 연산, Presenter에서 렌더링되는 뷰를 담당하고 있습니다. 

 

Atomic

 디자이너 Brad frost가 2013년 즈음에 창시해낸 방법으로 Atom -> Molecules -> Organisms -> Templates -> Pages 의 컴포넌트 구조로 점점 커가면서 코드의 재사용성을 높이기 위한 방법입니다.

 

해당 두 패턴을 다음과 같은 기준으로 비교하면서, 어떤 프로젝트에는 어떤 디자인 패턴이 어울리는지에 대해서 글을 작성해보려고 합니다.

1. 개발 시간적 효율 측면

2. 코드의 재사용성 측면

3. 코드의 가독성 측면

4. 협업 측면

5. 코드의 안정성(테스트코드) 측면

 


1. 개발의 시간적 효율 측면

 개발자에게 있어서 마일스톤을 다루는 일을 허다합니다. 그것이 회사에서 일을 한 지표이고, 프로젝트를 얼마나 참여하고 있는지 나타낼 수 있기 때문입니다. 개발의 시간적인 측면에서 어떤 디자인 패턴이 더 어울릴까요?

 

 시간적인 측면은 우선적으로 처음 시작하는 부분, 해당 패턴이 정착화되어있는 상황에서 기능을 추가하는 부분에 대해서 설명드릴려고합니다.

 

감자(필자)의 생각 🥔

 PC패턴은 논리적인 부분과 마크업이 명확하게 나누어져있고, 상대적으로 Top-Down방식으로 기능을 구성하는 경우가 많습니다. Atomic은 반대로 컴포넌트가 단위로 명확하게 나와있으면서 Bottom-Up방식으로 사용합니다.

 

 Atomic패턴은 회사에서 디자이너, 실무에서도 컴포넌트에 대한 개념을 명확하게 이해하고 있어야 합니다. 상대적으로 러닝커브가 높다보니까 처음에 도입하기 위해서는 많은 노력이 필요합니다. 대신에, 문서화가 잘 되어있고 Atoms, Molecules, Organisms 단위가 재사용성이 높게 설계가 되어있다면 갑작스러운 이벤트를 기획하고 실무에 녹여내야 할 때에는 큰 이점이 있을 것이 분명합니다. 기능의 단위가 명확하다 보니까 폴더에서 해당 파일을 찾아내는 것도 쉬울 것입니다.

 

 PC패턴은 반대로 러닝커브가 낮습니다. 설계에 대한 부담이 Atomic 패턴보다 부담이 덜 되는 것은 자명하다고 생각합니다. 따라서 실제로 개발을 시작할 수 있는 부분에 대해서는 훨씬 이점이 있을 것으로 판단됩니다. 문서화가 잘 되있으면서 논리적인 연산 자체를 담당하는 Container가 간단하게 구성이 되어있다면 다른 곳에서도 재사용하기 편할 것입니다. 그러나, 해당 컴포넌트를 찾기 위해서는 어느 폴더로 가야하는지에 대해서 생각을 해야 합니다. 어떤 기능을 하고 있고, 어떤식으로 작동이 되는지를 컴포넌트가 들어있는 파일의 레벨로는 추측하기 어렵습니다.

 

 따라서, 두 패턴 모두 이상적으로 패턴이 정착이 되는 거라면 초반의 구성은 Atomic이 조금 더 느릴 수 있으나 후반에는 훨씬 빠르게 개발을 하는데 도움이 될 것이라고 생각합니다.

 

 

 

2. 코드의 재사용성 측면

 코드의 재사용성이 좋다는 것은 설계가 잘 되어있음을 의미합니다. 코드의 재사용성이 높을수록 구성을 알아보기 쉽고, 코드의 라인 수 자체가 현저히 적을 것입니다.

 

감자(필자)의 생각 🥔

 Atomic 패턴이 당연히 좋지 않을까? 라고 생각하는 사람이 많을 것으로 생각됩니다. 저 역시 이상적인 상황에서는 Atomic 패턴이 좋다라고 얘기를 드리고 싶습니다. 그러나, 실무에서도 과연 코드의 재사용성을 확실히 줄일 수 있을까? 라는 생각을 해봐야 합니다.

 

 Atoms, Molecules 단위의 컴포넌트들은 애초에 재사용성을 위한 컴포넌트들입니다. 그러나, Page를 구성하기 위해 같은 Atom 컴포넌트더라도 정말 조금만 다른 기능을 작동해야 할 때에는 어떨까요? 정말 쉽게 Atom 컴포넌트를 재사용할 수 있을까요? 설계가 정확하고 추상화와 확장성에 대해 대응이 잘 되어있다면 재사용하기는 쉬울 것입니다.

 

 그러나 재사용하기 쉬운 코드는, 다시 말하면 추상화가 잘 되어있는 코드를 읽는 것은 생각보다 어려울 것입니다. 한 사람이 모든 컴포넌트를 만들고, 사용하는 거라면 Atomic 패턴이 재사용이 좋을 것이라고 말할 수 있지만 다른 사람의 컴포넌트를 가져다 쓰는 것은 쉬운일이 아닙니다. 그러다보면 비슷한 기능을 하는 컴포넌트들이 여럿 존재할 수도 있습니다.

 

 그러면 비슷해보이는 컴포넌트들의 문서를 읽으면서 시간을 많이 할애해야 할 수도 있습니다. 아니면, 새로운 기능을 도입하기 위해 컴포넌트를 새로 만드는 경우도 있을 것입니다.

 

 PC 패턴도 재사용하기가 생각보다도 쉬울 수 있습니다. Container를 중첩적으로 만드는 방법을 통해서 재사용성을 높일 수 있습니다. 그러나 해당 패턴도 역시 중첩적으로 만들다보면 코드의 가독성이 좋지만은 않습니다.

 

 그렇다면 어떤 패턴이 재사용하기 좋을까요? 개인적으로 해당 컴포넌트를 직접 구성한 사람들과, 컴포넌트를 명확하게 이해한 사람들에게는 Atomic의 재사용성이 정말로 뛰어날 것으로 생각됩니다.

 

 

 

3. 코드의 가독성 측면

 코드의 가독성은 혼자 개발할 때에도 중요하겠지만, 협업을 하고 있다면 더더욱 중요할 것으로 생각됩니다. 어떤 코드가 가독성이 더 좋을까요?

 

감자(필자)의 생각 🥔

 PC 패턴은 논리적인 연산과, 마크업 부분을 명확하게 나누었습니다. 세부적으로 보았을 때에도 어떤 기능을 하고 있는지, 어떤 데이터를 Presenter로 주고 있는지 파일 내에서 명확하게 보일 것입니다. 

 

 Atomic 패턴은 커스텀 훅을 사용하지 않는 한, 로직과 뷰가 같은 곳에 존재합니다. 그렇다면 한 코드 내에서 헷갈리는 코드들이 있을 수도 있습니다. 또한, Atomic 패턴 자체가 재사용성을 위해서 추상화를 해야 하는 컴포넌트가 많다 보니까 가독성 자체는 떨어질 수도 있습니다.

 

 문서화가 잘 되어있지 않다고 가정하면, Atomic은 추상화가 되어 있어 상대적으로 가독성이 좋지 않아서 해당 패턴의 장점을 가져오긴 어려울 것으로 생각됩니다.

 

 

 

4. 협업 측면

 협업을 하는 입장에서는 어떤 패턴이 더 좋을까요? 개인이 사용할 때 쓰기 좋은 디자인 패턴과, 협업을 할 때 쓰기 좋은 디자인 패턴은 서로 다르다고 생각합니다. 각각의 패턴이 어디에 더 좋을지에 대해 생각해 봅시다.

 

감자(필자)의 생각 🥔

 해당 패턴도 어느정도 회사에 상황, 프로젝트의 상황에 따라서 다를 것이라고 생각합니다.

 

 저는 혼자만 개발할 때에는 Atomic 패턴이 더 좋을 것이라고 생각합니다. 어떤 컴포넌트가 어디까지 작동하고, 문서화를 해야 하는 부분도 적다보니까 개발의 시간적인 측면이나 코드의 재사용성 측면이 좋아서 Atomic 패턴의 장점을 극대화 할 수 있을 것이라고 생각합니다.

 

 여럿이서 개발을 해야 할 때에는 위에서 언급했듯이, 비슷한 기능을 한 모호한 컴포넌트들이 많이 존재할 것입니다. 그런 컴포넌트를 분별하기 위해서 문서를 읽어야 하는 상황은 배보다 배꼽이 더 클 수도 있겠다라는 생각을 합니다.

 

 협업에서는 또 중요한 부분은 유지보수를 다른사람이 할 수 있는가에 대한 측면이라고 생각합니다. 해당 컴포넌트를 만든 사람이 아니더라도, 구성하고 있는 코드를 바꾸어야 하는 상황도 있을 것입니다. 따라서 협업에서는 가독성이 더 좋은 Container가 유리할 수도 있겠다라는 생각을 합니다.

 

 

 

5. 코드의 안정성 측면

 안정적인 배포를 위해서는 코드의 안정성이 중요합니다. 안정성을 측정하기 위해서는 여러 측면이 있을 수 있을텐데, 해당 부분에서는 테스트 코드 위주로 다룰 예정입니다.

 

감자(필자)의 생각 🥔

 Atomic 패턴에 대해서 먼저 생각해보겠습니다. 해당 패턴은 정말로 테스트 코드를 작성하기가 쉽지 않을 것입니다. 통합 테스트를 하기 위해서 하위 컴포넌트가 상위 컴포넌트에 끼치는 영향까지 고려해야 합니다. Mocking 테스트 코드를 작성하기 위해서도 코드와 데이터를 가져오기에는 어떤 역할을 하고 있는지 확실하게 알아야 합니다.

 

 PC 패턴은 반대로 Container의 역할과 Presenter의 역할이 구분화 되어있어서 편합니다. Mocking 테스트 코드를 작성하기 위한 코드와 데이터를 가져올 때에도 어디서 찾아야 할 지 명확합니다. 시각화를 다루는 상황에서도 어디서 찾아야 할 지 명확합니다.

 

 따라서 테스트 코드만을 작성하는 것을 기준으로 둔다면, 테스트 코드를 작성하기 쉬운 PC 패턴이 더 안정성을 가져올 수 있지 않을까라고 생각합니다.

 

 

추가로 생각해볼 수 있는 생각? 🙋‍♂️

Atomic 의 개념은 쪼개진 것을 합치는 느낌인데, PC 구조에서 Container 입장에서 봤을 때에도 쪼개진 Presenter 를 합친다라고 생각합니다. Atomic과 PC를 구분짓는 핵심적인 차이는 무엇인가요?

 Atomic과 PC를 사실 명확하게 구분하기는 어렵습니다. PC자체를 Atomic스럽게 만들 수도 있기 때문입니다. 따라서, 핵심적인 차이를 묻는다면 컴포넌트를 구성하는 단위를 어느정도로 쪼갤 것인가? 정도라고 생각합니다.

 

 코드의 가독성은 수많은 로직을 어떻게 분리하는가에 따라 좌지우지 된다고 생각합니다. 극단적인 예를들어 2만개의 이벤트를 갖는 페이지를 구성해야한다고 했을 때 PC 구조가 유리한가요? Atomic이 유리한가요? 

 React에서 만큼은 해당 생각을 타개할 수 있는 마법이 존재합니다. 바로 커스텀 훅입니다. 해당 글에서는 다루지 않았지만, 서로의 장단점을 보완할 수 있는 방법은 바로 커스텀 훅을 사용해야 하는 부분이라고 생각합니다. 로직이 복잡해져서 코드의 가독성이 떨어진다면 두 패턴 모두 커스텀 훅을 사용합시다.

 

테스트 코드의 변경 가능성을 생각하면 atomic 이 더 유리할까요? PC 에서는 P 따로 C 따로 수정해야하는데 atomic 은 한번만 수정하면 되지 않을까요?

 Container와 View가 같이 바뀌어야 한다면 Atomic은 하나의 테스트 코드 내에서 다룰 수도 있다고 생각합니다. 테스트 코드의 변경 가능성만을 따진다면 Atomic이 유리할 수도 있다고 생각합니다.

 

컴포넌트에 대한 단위 테스트부터 테스트 코드를 작성한다고 가정하겠습니다. 동일한 부모를 가진 컴포넌트가 서로 연계되어야하는 통합 테스트 코드까지 짠다고 가정하였을 때, Atomic 구조가 유리한가요? PC 구조가 유리한가요? 

 해당 부분은 Atomic이 단위 테스트 자체는 유리하더라도, Container Presenter가 통합 테스트에서 더 유리할 것이라고 생각합니다. Atomic은 애초에 재사용성을 위한 컴포넌트(단위)를 나누어 사용하는 개념이고, Container Presenter는 상대적으로 논리적인 부분을 뭉쳐놓은 Container가 있기 때문입니다.