JS/React

React - Atomic Design 이란?

shin96bc 2024. 3. 9. 17:56

Atomic Design(아토믹 디자인)이란?

아토믹 디자인은 디자인 패턴중에 하나입니다.

 

가장 작은 원자단위부터 원자가 모여서 분자를 이루고 분자들을 모아서 유기체를 형성하고, 유기체를 모아 하나의 템플릿으로 만들 수 있으며, 템플릿에 데이터를 주입해서 최종적으로 페이지를 생성하는 구조입니다.

 

아토믹 디자인은 총 5단계를 거쳐서 컴포넌트를 생성하고, 최종적으로 완성된 페이지를 유저에게 제공합니다.

 

그 과정에서 생성한 원자, 분자, 유기체 등은 재사용이 가능하기 때문에 유지보수가 용이해집니다.

 

Atomic Design의 5단계

atoms(원자)

  • Button, Input 등과 같은 범용적이고 가장 기본적인 Component들이 여기에 해당합니다.
  • 원자에는 컬러, 폰트, 애니메이션 같이 추상적인 요소가 포함되기도 합니다.

molecules(분자)

  • InputForm, List와 같이 레이아웃을 조립하는 단위의 Component들이 여기에 해당합니다.
  • 원자들을 결합해서 분자를 생성할 수 있습니다.
  • 분자는 그 자체의 특성을 가지고 있어서 원자들 자체로는 유용하지 않지만 Button, Input, Label들을 모아서 SearchForm을 형성하면 실제로 무엇인가를 할 수가 있습니다.

organisms(유기체)

  • Banner, Modal 같이 분자와 원자를 조합하여 생성된 Component가 여기에 해당합니다.
  • 분자를 모아 유기체를 생성하기 위해서는 Component가 독립적이고, 기동성 있고 재사용 가능하게 제작되어야 합니다.

templates(템플릿)

  • 템플릿은 유기체들을 모아서 유저에게 한 공간에서 제공할 서비스의 디자인을 확인할 수 있는 틀입니다.
  • 추상적인 분자와 유기체들을 모아서 그에 대한 맥락을 제공해줍니다.

pages(페이지)

  • 페이지는 템플릿에 실제 데이터를 넣어서 유저에게 제공되는 최종단계 입니다.
  • 디자인의 실제 맥락을 파악하고 개선할 수 있습니다.

 

Atomic Design의 폴더 구조

 

Atomic Design 패턴은 도대체 어떤 상황에 적용해야하는가?

처음 Atomic Design을 접했을 때는 templates 단계와 page 단계의 차이가 무엇인지?, 데이터 바인딩은 어느 단계에서 하는게 맞는지?, 각 단계들을 나누는 정확한 기준이 무엇인지? 등 많은 것들이 명확하지 않았습니다.

 

그래서 과연 이렇게 명확하지 않은 방법론이 과연 좋은 방법론인가? 좋은 방법론이라면 명확한 방법을 제시해줘야 하는게 아닌가 라는 생각도 했었습니다.

 

물론 이런 측면은 사용자측에 자유도가 높아지기 때문에 사용자에 따라서 더 좋은 방법들이 생겨날 수 있어서 무조건 나쁘다고 말할 수는 없지만 주니어 개발자의 입장에서는 조금은 명확하게 방법을 제시해줬으면 좋았을텐데 라는 마음이었습니다.

 

여기서부터는 지극히 저의 개인적인 생각고 정답이 아니기 때문에 이런 생각을 가진 사람도 있구나 정도로만 가볍게 읽고 넘어가시기 바라겠습니다.

 

Atomic Design을 도입하기 전에 꼭 아래의 3가지의 질문을 확인할 필요가 있습니다.

 

우리 프로젝트가 Atomic Design을 도입하기에 적합한 구조인가?

  • 프로젝트의 크기가 너무 작다면 Atomic Design 패턴을 도입하는게 오히려 독으로 작용할 수 있습니다. 왜냐하면 Atomic Design 패턴은 러닝커브가 높고 초기 작업에 시간이 많이 들기 때문입니다. 물론 확장성을 고려한다면 나쁘지 않은 선택일 수 있지만, 투자하는 비용에 비해 얻는 것이 적을 수가 있습니다.
  • 반대로 프로젝트의 크기가 방대하다면 정말 명확한 기준에 따라서 Component들을 나누고 관리하지 않는다면 구조만 엄청나게 복잡해져서 오히려 유지보수하기 힘든 프로젝트가 될 수 있습니다.
  • 또한 애플리케이션에서 재사용되는 요소들이 그리 많지 않다면 Atomic Design 패턴의 장점이 그다지 느껴지지 않을 수 있습니다.

 

팀원들과 Atomic Design의 각 단계를 나누는 명확한 기준에 대한 합의가 가능한가?

  • 같이 개발하는 팀원들이 각자 다른 기준으로 Component를 만든다면 어떻게 될까요? 아마도 프로젝트 구조가 엉망진창이 되어서 소통에도 장애가 생길 것이고, 많은 사이드 이펙트도 생길 수 있을 것입니다. 또한 다른 개발자가 만든 Component와 본인이 만든 Component의 기준이 다르기 때문에 재사용이 원활하지 않을 것이고 결국 비슷한 종류의 Component를 새로 만들게 될 것이고 불필요하게 비슷한 Component가 많이 생겨날 것입니다.
  • 협업에서 가장 중요한 것은 팀원들 모두가 하나가 되어서 같은 목표와 기준을 가지고 개발하는 것인데 각자의 기준이 다른 상태로 개발이 진행된다면, 분명 추후에 해당 프로젝트를 유지보수해야하는 사람에게 지옥과도 같은 시간을 선물하게 될 것입니다.
  • 그러므로 팀원들과 명확한 기준에 대해서 합의가 불가능 하다면 과감히 Atomic Design 패턴을 포기하는 것이 좋겠습니다.

 

기획자, 디자이너와 원활한 소통이 가능한가?

  • Atomic Design 패턴은 개발자 뿐만아니라 디자이너도 어느정도 Atomic Design 패턴에 대해서 알고 있어야 좀 더 원활한 진행이 가능합니다.
  • 또한 Atomic Design은 UI의 변화에 유연하지 못하기 때문에 기획이나 디자인 단계에서 변경사항이 생기게 될 경우 컴포넌트를 하나로 합치거나, 하나의 컴포넌트를 나눠야 하는 상황들이 생길 수 있고, 폰트 사이즈, 두께등의 사소한 변경점들이 컴포넌트 체계에 치명적인 영향을 줄 수도 있습니다. 그것은 기획자, 디자이너들이 state와 props에 대한 이해도가 낮거나 거의 없기 때문입니다.
  • 그래서 충분한 소통을 통해서 기획자와 디자이너와 개발자가 모두 Atomic Design 패턴에 대한 지식을 가지고 진행해야만 합니다.
  • 하지만 현실은 그렇지 못한 경우가 더 많기에 높은 러닝커브 때문에 오히려 의사소통에 장애가 되기 쉽습니다. 이런 경우에는 과감하게 도입을 포기하는 것이 좋을 것 같습니다.

 

그렇다면 Atomic Design 패턴은 어떻게 사용해야하는가?

자 위의 3가지 질문에 전부 yes라고 대답했다면 이제 Atomic Design 패턴을 도입할 준비를 해야합니다.

 

Atomic Design에 대해서 구글에 검색해보면 많은 사람들이 사용해본 경험에 대해서 쓴 글들을 볼 수 있었습니다. 어떤 사람은 유기체 부터 데이터를 바인딩 하기도 하고, 어떤 사람은 templates 단계를 page 단계와 합치거나 templates 대신 또 다른 단계를 추가하기도 하고, 어떤 사람은 재사용에 대한 집착을 버리기도 하고, 또 어떤 사람은 Atomic Design 자체를 부정하는 사람도 있었습니다.

 

많은 글들을 읽어보고 느꼈던 점은 다 일리가 있는 말이라는 것이었습니다. 아직 Atomic Design 패턴에 대한 확실한 예시가 존재하지 않기도 하고 저도 사용하면서 여러가지 의문점들이 생겼었기 때문입니다.

 

결론부터 말하자면 React의 디자인 패턴에는 정답이 없다고 생각합니다. Atomic Design 패턴이던 Container-Presenter 패턴이던 각자 마주한 상황에 맞게 변형해서 사용하면 되지 않을까라고 생각합니다. 어떤 디자인 패턴도 모든 상황을 해결해주지는 못하기 때문입니다.

 

자 이제 우리 주니어 개발자의 입장에서는 그래서 도대체 어떻게 사용하라는건데?? 라는 의문이 생길 것입니다. 그래서 지금부터 제가 괜찮다고 생각한 방법들을 말씀드리도록 하겠습니다.

 

먼저 구글링을 통해서 괜찮다고 느꼈던 방법 2가지를 먼저 소개드리겠습니다.

  • templates 단계를 삭제하고 유기체 단계에서 데이터 바인딩을해서 page단에서 사용하는 방법
    • 이렇게하면 page 단계에서 좀 더 유연한 개발이 가능합니다.
  • 재사용의 집착에서 벗어나는 방법
    • 재사용에 집착하며 개발을 진행하다보면 어느순간 하나의 Component가 매우 복잡해지고 코드는 알아보기 힘들고 더이상 건드리기 무서워지는 순간이 옵니다.
    • 그래서 재사용의 집착에서 벗어나서 의존하는 모델이 같은지 다른지에 따라 재사용의 여부를 결정해서 의존하는 모델이 다르다면 과감하게 새로운 Component를 만들어줍시다.

 

자 이제 제가 생각했던 방법을 소개드리겠습니다.

  • 저는 Java와 Spring으로 처음 개발을 시작했기 때문에 Spring의 개발방식에 영감을 많이 받았습니다. 그래서 이 React도 Spring처럼 구성한다면 어떨까? 하는 발상을 해보았습니다.
  • 먼저 React에서 가장 중요한 부분은 무엇일까요? 저는 관심사의 분리라고 생각합니다. 하나의 Component를 세분화하여 각 Component가 하나의 역할만을 수행하도록 구성하여 결합도를 낮추고, 응집도를 높여서 재사용성을 높이고, 변경사항이 발생했을 때 파급효과를 최대한 줄이고자 하는게 핵심이 아닐까 싶습니다.
  • 자 이제 React를 Spring처럼 구현할 수 있다고 생각한 이유에 대해서 설명드리겠습니다.
  • 첫번째로 위에 설명했던 React의 핵심적인 부분이 결국에 Spring의 SOLID원칙중 하나인 단일책임원칙(SRP)과 같은 곳을 바라보고 있지 않나 생각합니다. 그렇다면 React의 Component는 Spring의 interface라고 볼 수 있지 않을까요? 사용하는 측에 어느정도 규격을 강제하는 부분이 있고, 하나의 Component를 다양한 형태로 사용할 수 있는 부분이 마치 OOP의 다형성을 생각나게 만듭니다.
  • 원자 단위 Component를 여러 분자 단위 Coponent에서 다양한 형태로 사용할 수 있고, 분자단위 Component 또한 여러 유기체 단위 Component에서 다양한 형태로 사용할 수 있습니다.
  • 두번째로 SOLID원칙중 하나인 인터페이스 분리 원칙(ISP)처럼 범용 인터페이스 하나보다 특정 클라이언트를 위한 여러개의 인터페이스가 더 낫다. 라는 부분이 원자 단위까지 세분화하는 Atomic Design 패턴과 상당히 맞닿아 있다라고 생각합니다.
  • 세번째로 SOLID원칙중 하나인 개방-폐쇄 원칙(OCP)처럼 확장에는 열려있고, 수정에는 닫혀있어야 한다. 인터페이스를 구현한 새로운 클레스를 만들어서 기존 코드를 변경하지 않고 새로운 기능을 구현한다. 라는 부분이 React Component의 코드를 변경하지 않고도 사용하는 곳에서 props와 children을 이용해서 다른 기능을 하도록 만들 수 있는 것과 유사하다고 생각합니다.
  • 자 여기까지 내용을 봤을 때 React도 충분히 Spring처럼 객체지향적인 설계가 가능할 것 같다는 생각이 들지 않나요? 만약 귀찮게 그렇게까지 원칙을 지키며 개발해야하는가? Spring처럼 어느정도 구조를 강제하는 것을 선호하지 않으신다면 제가 생각한 방법은 맞지 않을 수 있습니다.
  • 저는 Spring처럼 원칙에 맞게 개발하면 물론 개발 단계에서는 불편할 수 있지만 유지보수, 확장 단계까지 갔을 때 비로소 꽃을 피운다고 생각합니다. 그때부터는 확장, 유지보수의 비용을 굉장히 많이 절약할 수 있다고 확신합니다.
  • 자 그런데 여기서 몇가지 의문점이 생길 수 있습니다. 모든 Component는 한가지 책임을 가지고 있고, 한단계 위의 Component에서 다양한 형태로 사용될 수 있는건 알겠는데 그럼 Style이나 데이터는 어디서 주입해야 맞을까요? Spring과 다르게 의존성주입(DI) 기능도 없는데 객체지향적인 설계가 가능할까? 토글처럼 상호 작용을 통해 변화하는 UI들을 모두 원칙에 맞춰서 개발할 수 있을까? 등의 질문들이 생길 수 있을거라고 생각합니다.
  • 이런 질문들에 대한 저의 답은 상황에 따라서 적절히 Compound component pattern 등을 도입한다거나, React에 맞게 어느정도 변경해서 적절하게 적용한다면 해결될 수 있지 않을까 생각합니다.

지금부터 제가 구현했던 방식에 대해서 설명드리겠습니다.(추가 예정)

 

장점

  • 원자, 분자, 유기체 단위로 만들어둔 Component들을 재사용할 수 있습니다. 따라서 유기체, 템플릿 단계에서 개발 속도가 매우 빨라집니다.
  • Component 마다 각각의 스타일을 포함하고 있기 때문에 Component 스타일 변경으로 모든 곳을 한번에 변경할 수 있습니다.
  • 스타일을 최소한으로 구현할 수 있습니다.

단점

  • 재사용성이 높은 Component도 존재하지만, 그렇지 못한 Component도 존재합니다. 예상치 못한 Component의 변화가 생긴 경우 props를 추가할 것인지, 새로운 Component를 생성할 것인지 선택하기가 어려워집니다.
  • 페이지에서 원자까지 props를 전달하며 Props Drilling이 발생합니다.
  • 5단계의 구분이 명확하지 않기 때문에, Component를 어떤 기준으로 나누고 재사용해야할 지 판단하기가 어렵습니다.

정리

  • 아토믹 디자인 패턴은 Component를 합성하고 재사용하면서 개발에 속도를 붙여줄 순 있지만, 아직 아토믹 디자인에 익숙하지 않은 개발자나, 이토믹 디자인 패턴이 해결해줄 수 없는 케이스를 마주하는 경우에는 오히려 속도가 떨어질 수 있습니다.
  • 따라서 자신이 진행하는 프로젝트는 어떤 디자인 패턴을 사용해서 개발을 진행할 것인지 충분히 생각하고 진행하는 것이 바람직할 것입니다.