Frontend

Atomic Design Pattern 사용기

코구리 2024. 1. 5. 16:20

올해의 첫 게시물을 어떤 것으로 할까 하다가 개인프로젝트에 도입해봤던 Atomic Design Pattern(아토믹 디자인 패턴)에 대한 얘기를 해보기로 했다.

아토믹 패턴은 많이 들어봤을 법한 디자인 패턴이지만 혹시 아토믹 패턴에 대해 잘 모르거나 도입을 고민중인 사람들이 있다면 이 글을 읽어보시길 추천합니다! 실제로 개발하면서 느낀 점을 담았기에 도움이 될 것 같습니다.

 

1. 아토믹 디자인 패턴이 뭔데? 👀

atomic은 '원자의' 라는 뜻으로, 컴포넌트를 최소한의 단위로 나눠 개발하는 패턴을 말한다.

편하게 아토믹 패턴으로 부르도록 하겠다😀

다음 사진처럼 atoms,  molecules, organisms, templates 들이 모여 하나의 페이지를 완성한다.

아토믹 패턴의 구조, 출처 https://atomicdesign.bradfrost.com/chapter-2/

 

 

atoms

atoms는 원자 단위, 즉 더이상 나눌 수 없는 가장 작은 단위의 컴포넌트이다. 버튼, 아이콘, 인풋, 레이아웃 등이 해당된다. 참고로 실제 개발 해보니 레이아웃 컴포넌트가 생각보다 많이 생긴다.

 

 

molecules

 

molecules는 분자 단위, atoms들이 모여 이루는 단위이고 하나의 기능을 할 수 있다. 예를 들어 버튼과 인풋이 모여서 하나의 검색 창을 만들 수 있겠다.

 

 

organisms

 

organisms는 유기체 , atoms와 molecules가 모여 이루는 단위이다. 하나의 form이나 header 등을 만들 수 있다.

 

templates

 

templates는 템플릿, 즉 atoms와 molecules와 organisms이 모여 하나의 템플릿을 이룬다. 여기서 레이아웃과 데이터가 주입되면 페이지 하나가 완성이 되는 것이다.

 

아토믹 패턴의 주된 목적은 컴포넌트의 재사용성 향상이다. 컴포넌트를 최소한의 단위로 쪼개서 개발하기 때문에 중복되는 컴포넌트를 재사용하기 용이한 것이다.

 

내가 이것을 도입하려고 한 이유는 기존에 했던 팀프로젝트에서 중구난방의 폴더구조로 되어있어 어떤 컴포넌트가 어디에 있는지 찾기 힘들었다. 폴더구조를 나누는 기준이 명확하게 정해져 있지 않아서 각자 알아서 만들었었다.

 

또한 컴포넌트를 나누는 단위 또한 제각각이어서 하나의 컴포넌트를 찾을 때 오래걸렸다. 특히 props를 받는 하위 컴포넌트를 찾고 싶을 때도 많은 컴포넌트 중에 찾아야 해서 한세월이었다;;

 

아토믹 패턴은 모든 페이지가 네 개의 폴더로 나뉜다.

 

아토믹 패턴은 크게 페이지 단위로 폴더를 나누고 atoms,  molecules, organisms, templates 폴더들이 모여 하나의 페이지를 완성한다. 그렇기 때문에 폴더구조가 예쁘게 구조화된다. 컴포넌트 찾기도 수월하다.

폴더구조 자체가 하위 구조에서 상위 구조로 가기 때문에 props를 빈번하게 사용하는 React의 경우 하위 컴포넌트와 의존성을 갖는 일이 많다는 점에서 궁합이 잘 맞는다는 생각이 들었다.

 

그리고 또 큰 이유는 컴포넌트 재사용이 용이하다는 점이었다. 이전 프로젝트에서 거의 유사한 UI인데도 재사용을 못하고 복붙해서 새로운 컴포넌트를 만든 경우가 있었는데 이게 참 비효율적이라고 느껴져서 아까웠다.

아토믹 패턴을 사용하면 컴포넌트를 최소한으로 작게 나눠 당연히 컴포넌트를 조합해서 재사용을 할 수 있으니 정말 좋은 패턴이라고 생각했다. 

그렇게 아토믹 패턴의 장점만 보고 도입을 결정했다.

 

2. 아토믹 디자인 패턴의 우여곡절 도입기🔥

이론으로만 봤을 때는 깔끔하게 구조화될 것이라고 생각했다. 하지만 실제 개발은 이론과 차이가 존재했다.

1) 모든 페이지가 4개의 단계로 딱딱 나누어지지 않았다.😭

이 부분이 가장 이론과 다르다고 생각한 부분이었다.

atoms와 templates는 각각 '더이상 나누어지지 않는 컴포넌트'와 '전체 페이지를 이루는 가장 큰 컴포넌트' 라는 명확한 기준이 있기 때문에 수월하게 만들 수 있었지만 그 사이에 있는 molecules와 organisms는 애매한 부분이 많았다. 이게 molecules로 가야 하는지 organisms로 가야 하는지 애매하거나 그 사이에 또 여러개의 계층이 존재하는 경우도 많이 있어서 같은 계층 간에 하위 컴포넌트가 생기는 좀 이상한(?) 현상도 생겼다.

 

CartMain 안에 CartItem 하위 컴포넌트 존재
하위 컴포넌트 CartItem이 상위 컴포넌트 CartMain과 같은 계층에 존재

 

이때 가장 많은 현타를 느꼈다고 보면 되겠다. 계층인데 계층이 아니게 되어버렸기 때문에 아토믹 패턴의 의미가 없다는 생각이 들어 중간에 아토믹을 접을까 생각도 했다. 하지만 장점도 분명 있었고 많은 부분을 개발해놓은 상태였기 때문에 계속하기로 했다. 

 

2) props drilling의 잦은 발생! 🚨

이 부분 또한 상당히 스트레스를 받는 점이었다.

너무 잘게 나눈 컴포넌트로 인해 data를 저 밑의 하위 컴포넌트로 보내줘야 하는 일이 발생했다. 그래서 props drilling 현상이 발생했다.

 

또한 중복되거나 유사한 컴포넌트의 재사용을 위해서는 props로 스타일을 넘겨줘야 했는데 이때 너무 많은 스타일을 커스텀하듯이 넘겨줘야 해서 코드가 지저분해졌다.

수많은 속성을 props로 받고 있는 모습

 

위 사진과 같이 많은 컴포넌트에서 사용되는 InlineText 라는 컴포넌트가 있는데 이것은 화면 내 글씨를 나타내는 컴포넌트이다. 그런데 이러한 글씨는 글자색, 두께 등등 스타일이 제각각이어서 재사용을 위해서는 이러한 부분을 전부 props 로 넘겨줘야 하는 경우가 발생했다. 코드도 지저분하고 귀찮은 일이다.

 

3) 재사용도 생각보다 어렵더라..🤔

아이러니하게도 아토믹 패턴의 가장 큰 장점인 컴포넌트 재사용도 그다지 빛을 발하지 못했던 것 같다.

내가 잘못 사용한 것일 수도 있으나 앞서 말한 props drlling 발생을 줄이기 위해서 어느정도 타협점을 만들어야 했다.

 

사실 비슷한 UI라고 해도 픽셀값이 조금씩 다른 경우가 많아 재사용이 쉽지 않았다. 재사용을 하려면 margin, padding 등 많은 부분을 커스텀하듯이 props로 만들어줘야 했는데 이렇게 되면 결국 또 앞서 말한 props drlling 이 발생했다. 따라서

위와 같이 너무 많은 props를 보내줘야 할 경우 재사용을 하지 않고 새로운 컴포넌트를 만드는 경우도 잦았다.

결국 모든 것은 props drilling을 막기 위한 고군분투였음.

 

4) 네이밍의 어려움

너무 많은 컴포넌트가 생기다보니 네이밍이 어려웠다.

흔히 하는 말로 개발자들이 힘든 일이 함수명 변수명 짓는 일이라고 하지 않는가?.. 그게 진짜 그냥 하는 말이 아니라 정말 힘든 것 같다. 특히 뭐 레이아웃이나 일부 버튼 등 재사용이 많이 되는 컴포넌트의 경우는 포괄적인 네이밍을 해줘야 하는데 적절한 네이밍을 짓기 애매한 경우가 많아 더욱 스트레스였다.

 

여담으로 내가 이 네임을 썼는지도 잊어버려서 페이지 간 똑같은 네이밍의 컴포넌트도 종종 만들어졌는데, 언제는 한 버튼컴포넌트를 자동완성으로 import 해올 때 똑같은 네이밍의 다른 버튼 컴포넌트가 import된 경험도 있다.

 

암튼 나는 네이밍 컨벤션을 확실하게 정하고 시작하지 않아서 더 힘들었는데 이걸 본 사람들은 꼭 네이밍 컨벤션을 잡고 프로젝트를 시작할 것을 추천한다. 어떤 사람은 gpt한테 물어본다는데 그것도 좋은 방법인듯.

 

5) 절충안👌

props 를 보내주는 일을 줄이기 위해 간단한 atoms는 스타일 컴포넌트로만 작성한 경우도 많았다. onClick 과 같은 이벤트 처리를 위해서라도 그렇게 만들어야 했다.

 

또한 자연스럽게 상태관리를 위한 Redux로 자주 사용되는 state(토큰, 장바구니 금액 등)를 저장하게 되었다.

상태관리 도구를 사용하는 이유가 다 있음을 느꼈고 이번 기회에 리덕스 사용이 익숙해져서 좋다고 생각한다.

Redux store에 저장한 slice들

 

3. 정리📝

결론적으로 아토믹 패턴을 사용하고 싶다면 다음과 같은 장단점을 고려하시길 바랍니다.

 

1) 장점💗

  • 하나의 페이지를 4개의 계층으로 분류하기 때문에 상위 컴포넌트에서 하위 컴포넌트를 찾기 용이하다.
  • 폴더구조가 깔끔해지고 구조의 가독성이 향상된다. 협업 시에 도움이 될 것 같다.

2) 단점💦

  • 페이지 계층을 4개의 단계로 나누기 어렵다.
  • 리액트와 결합할 경우 props drilling이 발생할 수 있다.
  • 재사용을 위해서 많은 속성을 props로 커스텀 해야한다.
  • 많은 컴포넌트 생성으로 네이밍이 더욱 어렵다.