본문 바로가기

루퍼스/라이팅

[성장기] 요구사항만 구현하던 SI 주니어가, 처음 설계를 해보며 바뀐 생각들

 

구현 전에 무엇을 결정해야 하는가

루퍼스 2주차를 진행하면서 이번에는 코드를 바로 작성하지 않고 설계 문서를 먼저 정리하게 되었다.
나는 그동안 요구사항이 내려오면 빠르게 기능을 붙이는 방식에 익숙했다.

그런데 이번에 처음으로 "구현 전에 무엇을 결정해야 하는가" 를 중심에 두고 설계 문서를 작업하게 되었다.

 

내가 원래 일하던 방식

나는 SI 환경에서 주로 개발을 해왔다.

돌아보면 제대로 된 요구사항 명세서를 기준으로 개발한 경험은 거의 없었던 것 같다..

대부분은 어디선가 복붙된 듯한 간단한 설계 문서 이거나 PM 과 여러 차례 조율하며 기능을 맞춰가는 방식에 가까웠다.

이런 방식도 편한 협업이라기 보다는 일정, 범위, 우선순위를 맞추기 위한 조정에 가까웠다.

 

이번 프로젝트에서 받은 요구사항 범위

이번 설계는 아래 도메인 범위를 기준으로 진행하게 되었다.

User: 회원가입, 내 정보 조회, 비밀번호 변경
Brand/Product: 브랜드 조회, 상품 목록/상세 조회, 관리자 브랜드/상품 관리
Like: 좋아요 등록/취소, 내가 좋아요한 목록 조회
Order: 주문 생성, 주문 목록/상세 조회, 주문 시점 스냅샷 보존
Admin: 관리자 전용 브랜드/상품/주문 관리 API

 

물론 이번 요구사항에 포함되지 않은 것들도 명확했다.

장바구니, 결제, 쿠폰 등등은 이번 범위 밖이었다.

하지만 범위를 먼저 고정하고 시작하니 지금 해야 할 것과 나중에 할 것을 나누기가 훨씬 쉬워졌다.

 

설계를 왜 잘해야 하는지, 이번에 체감한 이유

처음에는 설계를 자세히 하는 이유가 크게 와닿지 않았다.

어차피 개발에 들어가면 요구사항은 바뀌고, 문서도 다시 수정하게 된다고 생각했다.

그래서 "왜 지금 이렇게 구체적으로 정리해야 하지?" 라는 질문을 먼저 하게 되었다.

 

설계를 먼저 하니 구현 전에 보이게 되는 것들이 있었다.

요구사항 누락과 해석 충돌이 먼저 드러나게 되었다.
API, 도메인, DB 정책이 서로 안 맞는 지점을 미리 잡게 되었다.
책임 분리가 명확해져서 코드 위치를 두고 흔들리는 시간이 줄어들게 되었다.
삭제/보존/정합성 같은 운영 이슈를 개발 전에 결정하게 되었다.
결과적으로 재작업 비용이 줄어들게 되었다.

 

결국 설계는 문서를 예쁘게 만드는 일이 아니었다. 

개발하면서 서로 다르게 이해해서 생길 수 있는 충돌을, 시작 전에 맞춰보는 과정에 더 가까웠다.

 

시퀸스 다이어그램, 클래스 다이어그램, ERD를 써보며 느낀 차이

시퀸스 다이어그램

시퀸스 다이어그램 예시

 

시퀸스 다이어그램은 요청 흐름과 실패 지점을 드러내는데 가장 유용하게 느껴졌다.

어디서 트랜잭션이 시작되고 끝나는지 먼저 보이게 되었다.

예외가 나면 어느 지점에서 끊기고, 동시성 충돌이 어디서 날 수도 있는지 같이 보였다.

코드를 짜기 전에 "실패하면 어디까지 롤백할지" 같은 고민 포인트가 먼저 보이게 되었다.

 

클래스 다이어그램

클래스 다이어그램 예시

 

클래스 다이어그램은 나에게 아직 익숙한 도구는 아니었다.

정리해보니 "누가 어떤 책임을 가져야 하는가" 를 먼저 생각하게 만드는 도구에 가까웠다.

Controller, Service, Repository를 나눠서 보니, 구현할 때 로직 위치를 결정하는 기준이 조금씩 보이기 시작했다.

아직 익숙하지는 않지만, 코드를 바로 쓰기 전에 구조를 한 번 정리해보는 데 의미가 있다고 느끼게 되었다.

 

ERD

ERD 예시

 

ERD 는 단순히 테이블 관계를 그리는 문서라고 생각했다.

실제로 정리해보니 어떤 컬럼에 FK를 둘지, 삭제를 어떻게 처리할지, 고아 데이터는 어떻게 막을지 같은 기준을 정해야 했다.

주문 스냅샷을 어떻게 보존할지, 조회 성능을 위해 인덱스를 어디에 둘지도 결국 ERD에서 보게 되었다.

그래서 ERD는 단순한 구조 그림이라기보다, 운영에서 지켜야 할 기준까지 담는 문서에 가깝다고 느끼게 되었다.

 

가장 크게 고민한 지점: Soft Delete vs Hard Delete

이번 설계에서 가장 오래 고민한 주제는 브랜드/상품 삭제 부분이였다.

요구사항은 "브랜드 삭제 시 해당 브랜드 상품도 삭제" 였다.

두가지의 선택지에서 고민을 하게 되었다.

Hard Delete: 단순하고 정합성 관리가 쉽다.
Soft Delete: 복구 가능성이 있지만 조회/제약/운영 복잡도가 크게 증가한다.

 

여기서 같이 보게 된 조건이 주문 스냅샷 보존이었다.
주문은 order_items에 당시 상품명/가격이 남기 때문에, 이력 자체는 유지된다고 판단하게 되었다.
그래서 이 조건이라면 Hard Delete도 충분히 가능한 선택이라고 보게 되었다.
반대로 운영에서 복구 가능성이 핵심이면 Soft Delete 쪽이 더 맞다고 생각하게 되었다.

결국 중요한 건 기술 선호가 아니었다.
시스템이 어떤 리스크를 반드시 감당해야 하는지, 그 기준을 먼저 정하는 게 더 중요하다고 느끼게 되었다.

 

장바구니를 이번 설계에 넣지 않은 이유

장바구니는 이커머스에서 흔한 도메인이라 처음에는 미리 추가하는게 맞다고 생각하게 되었다.

하지만 요구사항 근거 없이 선반영하면 현재 범위의 복잡도만 커질 수도 있겠다는 생각이 들었다.

그래서 이번 설계에서는 장바구니를 실제 도메인으로 추가하지 않게 되었다.

현재 요구사항에 없으면 지금 구현하지 않는다.
대신 나중에 필요해질 가능성이 높은 기능은 다음 설계 단계에서 확장 항목으로 명확히 남긴다.
구현 범위와 확장 후보를 분리해서 결정한다.

 

이렇게 범위를 나누는 방식이 과설계를 줄이면서 다음 단계로 이어가기 좋다고 판단하게 되었다.

 

이번 경험 이후 생각의 변화


이번 경험 이후로는 코드를 바로 시작하기보다, 먼저 기준을 맞추는 쪽으로 생각이 바뀌게 되었다.  
요구사항을 사용자 관점에서 다시 읽어보고, 요청 흐름에서 어디가 실패 지점인지 먼저 확인하고, 데이터를 어떤 방식으로 보존할지까지 초반에 정리해보게 되었다.  

나는 여전히 구현 중심의 개발자라고 생각한다.  
다만 이번에는 구현 속도만큼이나 “왜 이 선택을 하는지”를 설명할 수 있어야 한다는 점을 배우게 되었다.  
앞으로는 정답을 빨리 고르는 것보다, 변경이 와도 흔들리지 않을 기준을 먼저 세우는 습관을 가져가려고 한다.