About architecture
문제점들
프론트엔드 아키텍처에 대한 논의는 보통 프로젝트가 커지고,
그로 인해 개발 생산성이 눈에 띄게 떨어지거나 일정이 계속 지연될 때 자연스럽게 시작됩니다.
Bus-factor & 온보딩
현재 프로젝트의 구조와 아키텍처를 일부 기존 팀원만 제대로 이해하고 있는 경우가 많습니다.
이런 상황에서는 새로운 팀원이 들어올 때마다 다음과 같은 문제가 생깁니다.
예시:
- 신규 팀원이 스스로 작업을 할 수 있을 정도로 익숙해지기까지 오랜 시간이 걸립니다.
- 명확한 아키텍처 설계 원칙이 없어, 개발자마다 제각기 다른 방식으로 문제를 해결합니다.
- 거대한 모놀리스 코드베이스에서 데이터 흐름을 추적하기 어렵습니다.
암묵적인 부작용과 예측 불가능한 영향
개발이나 리팩터링 과정에서 작은 수정이 생각보다 큰 범위에 영향을 주는 일이 자주 발생합니다.
이는 모듈 간 의존성이 복잡하게 얽혀 있어, 한 부분을 고칠 때 다른 부분이 함께 깨지기 쉬운 구조 때문입니다.
예시:
- 기능 간에 불필요한 의존성이 점점 쌓입니다.
- 한 페이지의 상태(store)를 수정했는데, 전혀 다른 페이지 동작이 갑자기 이상해집니다.
- 비즈니스 로직이 여러 파일과 레이어에 흩어져 있어, 전체 흐름을 따라가기 어렵습니다.
제어되지 않는 로직 재사용
기존에 있는 로직을 적절히 재사용하거나 확장하기가 어렵다는 것도 큰 문제입니다.
보통 아래와 같은 두 가지 극단적인 상황이 나타납니다.
- 재사용 가능한 코드가 분명히 있음에도, 매번 비슷한 모듈을 처음부터 새로 구현합니다.
- 반대로, 거의 한 곳에서만 사용하는 코드까지 전부
shared폴더로 옮겨져,
실제로는 재사용되지 않는 “공용 모듈”이 계속 쌓입니다.
예시:
- 동일한 계산/검증 로직이 여러 군데에서 복붙으로 반복 구현되어,
수정할 때는 모든 위치를 하나씩 찾아 고쳐야 합니다. - 버튼, 팝업 같은 컴포넌트가 스타일/동작이 약간씩 다른 여러 버전으로 중복 존재합니다.
- 유틸 함수들이 규칙 없이
utils.ts,helpers.ts등에 계속 쌓여,
어떤 함수가 있는지 찾기 어렵고 중복도 쉽게 생깁니다.
요구사항
“이상적인” 아키텍처를 이야기할 때, 현실적인 관점에서 다음과 같은 요구사항을 생각해 볼 수 있습니다.
note
여기서 “쉽다”라는 말은
“대부분의 개발자가 합리적인 시간 안에 이해하고 실제로 적용할 수 있다” 는 의미입니다.
모든 상황에 완벽히 들어맞는 아키텍처는 없기 때문에,
실제 팀과 프로젝트에 맞는 실용적인 합의가 더 중요합니다.
명시성
- 프로젝트의 구조와 아키텍처를 누구나 쉽게 이해하고, 다른 사람에게 설명할 수 있어야 합니다.
- 아키텍처는 프로젝트의 비즈니스 도메인과 핵심 가치를 자연스럽게 드러내야 합니다.
- 각 계층(layer)과 모듈 간의 의존 관계와 영향 범위가 명확해야 합니다.
- 중복된 로직을 쉽게 찾아내고 제거할 수 있어야 합니다.
- 중요한 비즈니스 로직이 프로젝트 전반에 얇게 흩어져 있지 않도록 관리해야 합니다.
- 규칙이나 추상화는 필요 이상으로 복잡하지 않게, 최소한으로 유지해야 합니다.
제어
- 새로운 기능을 빠르게 추가하고, 발생한 문제를 쉽게 찾아 해결할 수 있어야 합니다.
- 프로젝트 전체의 개발 흐름을 계획하고 조정할 수 있는 구조여야 합니다.
- 코드가 확장하기 쉽고, 유지보수하기 편하며, 필요할 때 제거도 수월해야 합니다.
- 기능 단위(feature 단위)로 경계와 격리 수준이 명확해야 합니다.
- 컴포넌트나 모듈은 교체/삭제하기 쉬운 형태여야 합니다.
- 미래의 변경을 과하게 예측해 과도하게 최적화하는 설계는 지양합니다
- 앞으로 어떤 요구사항이 나올지는 정확히 알 수 없기 때문입니다.
- 대신 “삭제하기 쉬운 구조”를 더 중요하게 봅니다
- 지금 알고 있는 요구사항을 기준으로 의사결정하는 편이 더 실용적입니다.
- 미래의 변경을 과하게 예측해 과도하게 최적화하는 설계는 지양합니다
적응성
- 다양한 규모와 성격의 프로젝트에 적용할 수 있어야 합니다.
- 기존 시스템 및 인프라와도 큰 충돌 없이 통합할 수 있어야 합니다.
- 프로젝트의 전 생애주기(초기, 운영, 확장 단계)에 걸쳐 일관되게 적용 가능해야 합니다.
- 특정 프레임워크나 기술 스택에 과도하게 묶여 있지 않아야 합니다.
- 여러 팀 혹은 여러 명의 개발자가 병렬로 개발하고,
팀이 커져도 구조가 버티도록 설계되어야 합니다. - 비즈니스 요구사항과 기술 환경이 바뀌더라도 유연하게 대응할 수 있어야 합니다.