리팩토링이란? 2026 비개발자가 바이브 코딩 코드 구조를 나눈 방법

리팩토링이란? 2026 비개발자가 바이브 코딩 코드 구조를 나눈 방법

페스티봄을 만들면서 리팩토링이란 말을 실제로 체감한 건 기능이 꽤 늘어난 뒤였습니다. 처음에는 축제 일정이 화면에 나오고, 아티스트가 연결되고, 관리자 페이지에서 정보가 저장되는 것만으로도 만족스러웠습니다. 일단 작동하는 모습을 보고 나면 다음 기능을 붙이고 싶었어요.

그렇게 1단계를 만들고 기능을 추가한 뒤 기존 코드에 합치는 일을 반복했습니다. 어느 순간부터는 작은 내용을 고치려고 해도 어디를 확인해야 하는지 바로 알기 어려웠어요. 한 파일 안에서 화면도 만들고 데이터를 불러오고 저장까지 처리하고 있었기 때문입니다.

공부하면서 한 파일에 너무 많은 역할을 맡기면 수정 범위가 커진다는 내용을 배웠습니다. 하나를 고쳤을 때 다른 곳에서 어떤 문제가 생길지 예측하기도 어려우니, 기능을 조립식으로 나눠야 한다는 설명이었습니다. 그 뒤부터 AI에게 너무 긴 파일이 없는지 중간중간 확인시키고, 기존 기능을 유지하면서 구조를 나누는 작업을 요청했습니다.

이번 글에서는 비개발자가 바이브 코딩으로 만든 페스티봄을 실제로 어떻게 정리했는지 이야기합니다. 리팩토링의 뜻부터 긴 코드를 나눈 기준, 구조화한 뒤 제가 체감한 변화까지 차례로 담았습니다.

리팩토링이란 무엇인가

리팩토링은 사용자가 보는 기능은 그대로 둔 채 코드의 내부 구조를 고치는 작업입니다. 새 버튼을 만들거나 화면을 추가하는 것이 아니라, 이미 작동하는 코드를 다음에 이해하고 수정하기 쉬운 모습으로 바꿉니다.[1]

축제 등록을 예로 들면 결과는 전과 똑같이 저장됩니다. 대신 한 파일에 섞여 있던 화면 표시, 입력값 관리, 데이터 조회와 저장을 각각 맡을 곳으로 옮깁니다. 나중에 저장 오류가 생기면 화면 전체를 뒤지는 대신 데이터 처리 부분부터 살펴볼 수 있습니다.

리팩토링은 코드를 한꺼번에 새로 쓰는 작업과도 다릅니다. 작은 부분을 옮기고 기존 기능이 그대로 작동하는지 확인하는 과정을 반복합니다. 페스티봄도 전체 구조를 한 번에 뒤집지 않고, 역할이 많이 몰린 파일부터 하나씩 정리했습니다.

바이브 코딩에서도 코드 구조가 필요한 이유

바이브 코딩의 장점은 원하는 기능을 빠르게 확인할 수 있다는 점입니다. 저처럼 코드를 잘 모르는 사람도 자연어로 요구사항을 설명하고 결과를 보면서 다음 단계를 이어갈 수 있습니다.

다만 AI가 기능을 빨리 만들어준다고 해서 프로젝트의 구조까지 저절로 단순하게 유지되지는 않았습니다. 새로운 요청을 할 때마다 상태나 함수를 하나씩 보태다 보면 비슷한 코드가 생기고, 한 화면이 여러 일을 맡게 됩니다. 작동은 하지만 다음 수정이 점점 어려워지는 거죠.

저는 ‘조립식으로 코딩한다’는 말을 모든 코드를 잘게 쪼개라는 뜻으로 이해하지 않았습니다. 화면 모양을 바꾸는 일과 데이터를 저장하는 일처럼 서로 다른 이유로 수정되는 코드를 구분하는 기준으로 받아들였습니다.

React 공식 문서도 화면을 여러 컴포넌트로 나누고, 하나의 컴포넌트가 가능하면 한 가지 관심사를 맡도록 설명합니다. 역할이 계속 늘어나면 더 작은 컴포넌트로 분리할 수 있습니다.[2] 코드를 직접 다 읽지 못하더라도 어떤 기준으로 나눌지는 배울 수 있었어요.

페스티봄의 코드가 길어진 과정

페스티봄은 처음부터 완성된 설계대로 만든 서비스가 아니었습니다. 처음에는 축제 정보만 넣으려고 했지만, 아티스트를 누르면 어느 페스티벌에 출연하는지도 보여주고 싶었어요. 그래서 아티스트 테이블을 따로 만들고 축제와 연결했습니다.

같은 아티스트가 날짜를 달리해 여러 번 출연하는 경우도 생겼습니다. 처음 구조로는 하나의 페스티벌에 한 번만 연결할 수 있어서 데이터 구조를 다시 바꿨어요. 관리자 기능과 달력도 필요한 내용을 발견할 때마다 조금씩 추가했습니다.

관리자 화면에서는 수동 입력 중 빠뜨리거나 중복되는 정보를 줄이려고 JSON 등록 기능을 만들었습니다. 신규 축제 등록, 기존 축제 수정, 티켓과 라인업 검토가 이어지면서 한 화면이 처리하는 일도 많아졌어요.

구조를 정리하기 전에는 신규 축제 후보 화면이 약 750줄, 기존 축제 JSON 수정 페이지가 약 590줄이었습니다. 캘린더의 중심 파일도 약 450줄 안에서 월 이동, 검색, PC와 모바일 조작, 화면 구성을 함께 처리했습니다. 파일이 길다는 이유만으로 문제가 되는 것은 아니지만, 서로 다른 역할이 섞였는지 확인할 계기는 됐습니다.

긴 코드를 역할에 따라 나눈 방법

처음부터 제가 파일을 하나씩 읽고 분리 위치를 정한 것은 아닙니다. AI에게 긴 파일과 반복되는 처리를 먼저 찾게 하고, 각 파일이 무슨 일을 하는지 설명해 달라고 했어요. 설명을 본 뒤 기능은 바꾸지 말고 역할만 나누도록 요청했습니다.

페스티봄에서는 크게 네 가지 역할로 구분했습니다.

  • page.tsx: 주소를 읽고 어떤 화면을 열지 결정
  • 컨트롤러: 입력 상태와 버튼을 눌렀을 때 일어나는 동작 관리
  • lib 폴더: Supabase 조회와 저장, 데이터 변환
  • 화면 컴포넌트: 전달받은 내용을 사용자에게 표시

구조를 나눈 뒤 기존 축제 JSON 수정 페이지는 약 590줄에서 27줄로 줄었습니다. 코드가 없어진 것은 아닙니다. 주소를 읽고 화면을 고르는 부분만 페이지에 남기고, 입력 상태와 저장 동작은 컨트롤러로 옮겼습니다.

캘린더도 비슷했습니다. 중심 파일은 약 450줄에서 120줄 정도가 됐고, 월 이동과 화면 상태, 스와이프, 검색, 날짜 칸과 옆 패널을 각각 나눴습니다. 월 이동에 문제가 생기면 캘린더 전체보다 컨트롤러와 스와이프 코드를 먼저 보면 됩니다.

여기서 알게 된 점은 파일을 나눈다고 전체 코드가 갑자기 짧아지는 것은 아니라는 사실이었어요. 실제 동작을 담당하는 컨트롤러는 여전히 긴 편입니다. 대신 화면을 고칠 때 저장 코드까지 함께 읽지 않아도 되니 확인할 범위가 줄었습니다.

신규 등록과 기존 수정 기능을 합치지 않은 이유

비슷해 보이는 기능을 모두 공통 코드로 합치는 것도 좋은 방법은 아니었습니다. 신규 축제 등록과 기존 축제 수정은 모두 기본 정보, 티켓, 라인업을 차례로 검토합니다. 화면만 보면 하나의 기능으로 묶어도 될 것처럼 보입니다.

하지만 신규 등록은 아직 없는 축제를 만들고, 기존 수정은 이미 저장된 정보 중 필요한 부분만 바꿉니다. 임시 데이터를 담는 곳과 마지막에 저장하는 과정도 달랐습니다. 두 기능을 억지로 합치면 신규인지 수정인지 구분하는 조건이 계속 늘어납니다.

그래서 검토 단계를 거친다는 큰 규칙만 같게 두고 실제 처리 흐름은 따로 관리했습니다. 반대로 여러 화면에서 똑같이 쓰는 데이터 변환은 lib 폴더의 공통 함수로 모았습니다.

조립식 구조는 무조건 합치거나 무조건 나누는 방식이 아니었습니다. 함께 바뀌는 기능은 묶고, 바뀌는 이유가 다르면 따로 두는 쪽이 이해하기 쉬웠습니다. Next.js도 한 가지 폴더 구조를 강제하기보다 경로나 기능을 기준으로 파일을 구성할 수 있도록 안내합니다.[3]

구조화한 뒤 코드를 보는 방식이 달라졌다

구조를 나누고 나니 무엇이 어떤 기능을 맡는지 한눈에 구분하기 쉬워졌습니다. 파일 이름만 봐도 신규 축제 후보를 다루는지, 기존 축제 수정 상태를 관리하는지, 달력의 스와이프를 처리하는지 짐작할 수 있었어요.

제게 가장 큰 변화는 코드를 이해하는 속도였습니다. 예전에는 긴 파일을 처음부터 훑어야 했다면, 이제는 궁금한 기능이 있는 폴더부터 좁힐 수 있습니다. 문제가 생기거나 특정 코드가 궁금해 AI에게 물어볼 때도 어디를 확인해야 할지 찾기 쉬워졌어요.

구조화 작업 때문에 기존 기능이 특별히 깨진 적은 없었어요. 한 번에 한 역할씩 옮기고 신규 등록, 기존 수정, 아티스트, 캘린더처럼 기능별로 다시 확인했습니다. 구조를 정리하는 중에는 새로운 기능을 함께 넣지 않았습니다.

물론 파일을 나눴다고 모든 코드를 이해하게 된 것은 아닙니다. Supabase에 저장되는 과정이나 컨트롤러 안의 상태는 지금도 설명을 들어야 합니다. 그래도 모르는 범위가 프로젝트 전체에서 특정 기능 하나로 줄어든 것은 큰 차이였어요.

비개발자가 AI에게 리팩토링을 요청한 방법

처음에는 “긴 코드를 정리해 줘”라고만 말해도 될 것 같았습니다. 하지만 파일 길이만 줄이려 하면 이름만 다른 파일이 늘거나, 서로 다른 기능을 잘못 합칠 수 있습니다.

그래서 바로 코드를 고치게 하지 않고 현재 구조부터 조사하게 했습니다. 어떤 파일이 길고, 한 파일 안에 어떤 역할이 섞여 있으며, 반복되는 처리가 어디에 있는지 먼저 설명받았습니다. 그다음 기존 기능과 데이터 구조는 유지한다는 범위를 정했습니다.

현재 기능은 바꾸지 말고 긴 파일이 맡은 역할부터 정리해 줘. 화면 표시, 상태와 사용자 동작, 데이터 조회와 저장, 공통 변환으로 나눌 수 있는지 계획을 먼저 보여줘. 신규 등록과 기존 수정처럼 목적이 다른 흐름은 억지로 합치지 말고, 한 단계씩 수정한 뒤 기존 동작을 확인해 줘.

작업이 끝난 뒤에는 새로 생긴 파일의 목록만 받지 않았습니다. 각 파일이 무슨 일을 맡았고, 다음에 문제가 생기면 어디부터 확인하면 되는지 다시 설명하게 했습니다. 이 설명을 들어야 제가 구조를 이해하고 다음 요청도 구체적으로 할 수 있었어요.

비개발자인 제게 리팩토링은 코드를 직접 능숙하게 고치는 기술이라기보다 AI가 만든 결과를 계속 관리하는 방법에 가까웠습니다. 기능을 추가하는 속도만큼 중간에 구조를 살펴보는 시간도 필요했습니다.

페스티봄을 처음부터 완벽한 구조로 만들지는 못했습니다. 필요한 기능을 하나씩 알아가며 여러 번 코드를 나눴습니다. 지금도 모르는 부분은 많지만, 적어도 무엇을 물어보고 어디부터 확인해야 하는지는 전보다 분명해졌습니다.

참고 자료

  1. Martin Fowler, Refactoring: 외부 동작을 유지하면서 내부 구조를 바꾸는 리팩토링의 정의와 작은 단위로 진행하는 원칙을 확인했습니다.
  2. React, Thinking in React: 화면을 컴포넌트 계층으로 나누고 각 컴포넌트가 하나의 관심사를 맡도록 하는 기준을 참고했습니다.
  3. Next.js Project Structure: 경로나 기능을 기준으로 프로젝트 파일을 구성하는 방법을 확인했습니다.