프론트엔드 개발자로 나름 일 해오면서 내가 생각하는 개발에 대해 적어보려고 한다.
참고로 아직까지 주니어이고 싶은 내 개인적인 생각이고 의견인 만큼, 정답은 아니며, 충분히 다른 의견도 있을 수 있다.
그저 참고 정도로만 활용될 수 있으면 좋을 것 같다.
객체지향 패러다임을 주로 사용하는 언어의 분야에서는 아키텍처의 중요성을 많이 알고 도입하려는게 많이 보인다.
나 역시 객체지향 패러다임의 언어로 공부를 시작했었기 때문에, 아키첵처를 굉장히 좋아하는 개발자가 됐을 수도 있다.
개인적으로 개발을 프론트엔드로 시작한 사람들한테 보이는 공통적인 특징이 있다.
아키텍처에 대해 너무 소홀히 여기는 편인거 같다.
계층을 왜 나눠서 관리를 하는지, view의 역할이 무엇인지 등 이해를 잘 하지 못하는 경우가 많았다.
개인적으로 프론트엔드 개발자가 하는 말 중 싫어하는 몇 가지 말이 있다.
A: "기획(스펙)이 다 나오지 않아서 못해요"
B: "API가 아직 나오지 않아서 못해요"
아키텍처를 이해하면 사실 이런 말을 꺼내선 안된다고 생각하는편이다.
물론 기획이 나오지 않거나, API가 나오지 않으면 개발을 완성할 수는 없다. 하지만 개발은 할 수 있다.
이런 관점에서의 내용을 아키텍처의 관점에서 이번 글에서 담아보려고 한다.
나무위키 에서는 아키텍처에 대한 개념적 설명을 아래과 같이 말한다.
목표하는 대상에 대하여 그 구성과 동작 원리, 구성 요소 간의 관계 및 시스템 외부 환경과의 관계 등을 설명하는 설계도 혹은 청사진을 말한다.
이론적인 수준에 머무르지 말고 지극히 현실적인 의미의 청사진을 만든다는 데 중점을 둔 용어다. 따라서 아키텍처를 설계 과정에는 정책의 변화, 인력 문제와 같은 내부적 요인 뿐 아닌 유저의 행동 경향, 최근 소프트웨어의 동향 및 업데이트 현황 등 외부적 요인까지 종합적으로 고려하여 다양한 변수에 대응할 수 있도록 하는 것이 핵심이다.
우리는 개발자이기 때문에, 좀 더 구체적으로 소프트웨어 아키텍처로 구분한다.
소프트웨어 아키텍처에 대한 개념은 요즘IT 라는 페이지에서 참고했다.
소프트웨어 아키텍처는 시스템의 기본구조이며, 시스템을 구성하는 요소와 각 요소 간의 관계를 정의하는 일종의 청사진입니다. 소프트웨어 아키텍처는 시스템의 주요 속성을 결정하고, 개발 과정의 중요한 설계 결정을 통제하는 역할을 합니다. 아울러 시스템의 전반적인 틀을 제시하고, 각 이해관계자 사이의 의사소통을 돕는 도구가 되기도 하죠.
즉, "시스템의 기본구조이며, 각 요소 간의 관계를 정의하여 다양한 변수에 대응할 수 있게 하는 것"이 소프트웨어 아키텍처의 개념이 될 것 같다.
아직 개념만으로는 위에서 언급한 A와 B는 해결이 될 수 없다.
그럼 실제 코딩을 하는 개발자 관점에서 클린 아키텍처로 넘어가보도록 한다.
아마 개발을 어느정도 접했다면, 클린 아키텍처에 대해 들어봤을거다.
그 중 가장 유명한 내용은 역시 Robert C Martin(엉클 밥)이 얘기하는 아래 이미지의 계층형 아키텍처일 것이다.
참고: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
이 아키텍처에 대한 설명은 다른 블로그 글에서 잘 설명하고 있을거니... 넘어가도록 한다.
클린 아키텍처라고 구글에 검색하면 참 많은 내용이 나올 것이며, 이 글에서 언급하고 싶은 내용은 클린 아키텍처에 대한 설명이 아니기 때문이다.
개인적으로 이 아키텍처는 참 잘 그려진 아키텍처라고 생각한다.
FE, BE를 넘어 전반적인 아키텍처에서도 적용이 가능한 모델이다.
물론 각 분야의 전문가들이라면 더 잘게 쪼개는 것도 가능하지만, 간단하게 생각한다면 이렇게 볼 수 있을 것 같다.
즉, 분야에 관계없이 적용 가능한 모델이라고 생각한다.
앞서 프론트엔드로 개발을 시작한 사람들이 클린 아키텍처에 대해 약하다고 언급했었다.
그 이유 중 하나가, 리액트 혹은 뷰 처럼 프레임워크(라이브러리)가 너무 잘 되어있어서라고도 생각한다.
프레임워크를 사용하는 것은 문제가 되지 않지만, 좀 더 잘 사용했으면 한다.
프론트엔드 개발자이기 때문에, 프론트엔드 관점으로 좀 더 설명을 해보면, 프론트엔드 개발도 위에 만든 아키텍처로 구분하여 개발할 수 있다.
- VIEW: 사용자가 보는 실제 화면 혹은 컴포넌트
- VIEW MODEL: 실제 화면 혹은 컴포넌트를 구성하기 위해 필요한 데이터 및 로직 (화면에 맞게 가공 할 데이터)
- MODEL: 화면에 보여주기 위한 데이터를 BE로부터 받아와 가공한 데이터 (원시 데이터를 프론트에서 사용하도록 가공한 데이터)
- ENTITY: BE로부터 전달 받은 원시 데이터
이렇게 계층적으로 구분을 하게 되면, 앞서 말한 B는 해결이 된다.
BE와의 연결점은 ENTITY만 담당하며, MODEL에서 프론트에서 사용할 데이터로 가공을 하게 된다.
즉, 화면(디자인)이 있다면, 프론트는 프론트 따로 MODEL의 데이터로 개발을 진행하며, API가 모두 나왔다면, 그때 API와 연결을 통해 화면에 맞게 개발 된 MODEL로 변환(가공)하면 된다.
이렇게 할 경우, 앞단 (VIEW, VIEW MODEL)은 확인하지 않아도 정상적으로 동작할 것이며, API의 값이 일부 변하더라도, 변환하는 로직만 추가, 수정해주면 되기 때문에 변환, 확장에 있어 좀 더 자유롭게 개발이 가능하다.
(물론, 정상적인 데이터로 가공을 했는지 확인은 하긴 해야한다. - 근데 이건 너무 당연...)
4단계의 계층만으로는 사실 개발이 되지 않는다.
그 안에서 또 여러 계층 혹은 아키텍처가 필요하다.
즉, 하나의 프로젝트에는 여러개의 아키텍처가 혼합되어 만들어지며, 전체를 보면 굉장히 많은 경우가 위의 이미지처럼 Layered Architecture로 구성이 되어있다.
흔한 예로, 프론트에서 VIEW를 구성하기 위해 사용하는 Atomic Design Pattern 같은 경우가 있다.
참고: https://atomicdesign.bradfrost.com/chapter-2/
Page를 구성하기 위해 컴포넌트들을 잘게 쪼개고, 특정 단위로 합치는 형태의 디자인패턴이다.
이 컴포넌트들이 가질 데이터를 view model에서 정의하면 클린 아키텍처 중 앞단(VIEW, VIEW MODEL)이 만들어지게 된다.
함수형 컴포넌트가 도입이 되면서, 개인적으로 나는 view model을 정의하기 위해 hook을 즐겨 사용하는 편이다.
FE의 뒷단(MODEL, ENTITY)을 구성하는데는 전역 상태 (store) 구조를 주로 사용한다.
수 많은 라이브러리 (react query, redux, mobx, recoil 등)를 통해 데이터를 관리하게 만들며, 서버로부터 받아온 데이터들을 저장해둔다.
VIEW와 VIEW MODEL을 구성하는 앞단과 MODEL과 ENTITY를 구성하는 뒷단으로 구분하여 개발할 수 있다.
VIEW MODEL에서 각종 라이브러리의 query를 통해 store에 저장 된 값을 가져와 component에 맞게 가공하고, 컴포넌트들로 페이지를 만들 수 있다.
뒷단에서는 프론트에서 사용할 데이터들로 만들어두고, 이후 API와 연결하는 과정을 추가하면 된다.
보통 개발을 할 때 뒷단은 나중에 신경써도 개발이 가능하다.
데이터를 관리하는 역할이기 때문에, 앞단에서 데이터를 전달 받을 수 있게만 개발하면 되기 때문이다.
그럼 아까 언급한 A의 문제는 앞단을 구성하는 아키텍처로 개선할 수 있다.
기획이 아무것도 없다면, 우선 프로젝트 전반적인 구조와 설계를 할 수 있다.
큰틀에서 위 그림과 같은 아키텍처를 만드는 과정을 진행한다.
기획이 일부라도 나온 상태라면, 먼저 디자인을 입히지 않은 기능 혹은 필수적인 컴포넌트들을 구현한다.
"A 라는 기능이 필요해요" 정도의 기획만 있더라도, 그 기능에 필요한 버튼이라던가, 중요 로직은 얼마든지 개발할 수 있다.
예를들어, "사용자의 정보를 검색할 수 있는 페이지가 필요해요" 정도의 내용만 전달 받아도, 검색을 위한 input과, 버튼 그리고 검색 결과라는 데이터가 필요함을 유추할 수 있다.
그러면, 디자인은 나중에 입히더라도, input을 위한 컴포넌트를 만들 수 있고, 버튼을 위한 컴포넌트, 그리고 검색 결과를 보여줄 데이터들을 구성할 수 있다.
결과페이지도 미리 만들 수 있지만, 테이블로 구현될 지, 리스트로 구현될 지 모를 수 있어 데이터들을 가공하고 전달 할 수 있을 정도로만 만들어 둘 수 있다.
실제로 기획은 더 상세히 나오겠지만, 이렇게 단편적인 정보만으로 프론트는 할 일들을 만들 수 있다.
애자일 프로세스에 한 방법이기도 하다.
또한, 이렇게 개발을 할 경우 확장과 수정에 용이하다.
각 계층을 독립적으로 운영할 수 있고 영향도를 최소화 할 수 있기 때문이다.
그치만... 글로만 작성해봤자 실제로 경험을 해보지 않으면 이해하기 어렵다...
(이게 프론트엔드로 개발을 시작한 아키텍처를 잘 모르는 분들이 경험하기 가장 어려운것 같다.)
결과적으로, 아키텍처를 구성할 수만 있어도, 위에 언급한 A와 B는 어느정도 해결이 가능해진다.
A: "기획(스펙)이 다 나오지 않아서 못해요"
B: "API가 아직 나오지 않아서 못해요"
프론트엔드 개발자들이 놀고 있을 필요가 없다고 생각한다.
얼마든지 효율적으로 일 할 수 있다.
이 글은 개인적인 견해를 많이 담은 내용이기에 정답은 아니다.
그저 참고 정도가 될 수 있으면 좋겠다는 생각으로 작성했다.
다른 분야의 개발자들에 비해 유독 프론트엔드에서만 아키텍처에 대한 관점을 이해하지 못하는 경우를 많이 접했어서 글을 작성했다.
물론 모든 프론트엔드 개발자들에게 말하는 것이 아니며, 개인적으로 만났던 개발자 중 그저 프론트엔드 개발자들이 관심도가 더 적었다는 내용이다.
아키텍처는 계속 발전하고 끊임없이 새로운 아키텍처들이 나오고 있다.
최근(은 아니지만..)에는 헥사고날 아키텍처라던가, FSD 패턴이라던가 여러 아키텍처 패턴들이 나오고 있다.
이 패턴들은 일괄되게 한 가지 지향점을 가지는데, 확장에 변경에 유연하다는 것이다.
즉, 대부분의 아키텍처는 결국 사용자의 needs에 맞게, 변화하는 세계에 맞게 소프트웨어의 확장과 변경이 유연하게 설계가 되어오는 것 같다.
그래서 어느 순간부터 개발을 하면서, 분야에 관계없이 개발이 크게 다르지 않다라는 생각을 가지게 됐다.
(물론, 다르긴 하다. 그저 큰 틀에서 보면 비슷하다고 생각할 뿐이다.)
나중에 시간이 된다면, 이 글에서 작성한 내용을 코드로 풀어볼 수 있다면 좋을 것 같다.
참고로 개인적인 아키텍처 설계에 대한 생각으로, 정말 완벽한 클린 아키텍처는 이론상 가능하며, 변화하는 세계에 맞춰 개발하다보면 어느정도는 타협을 해야하긴 하다.
개인적인 이라는 단어를 굉장히 많이 사용했는데,
개인적으로 생각하는 내용을 열심히 반복하여 알리려는 것도 있고, 욕 먹기 싫어서기도 하다... ㅎ
추가 의견은 얼마든지 환영합니다 :)
끝~