팀스파르타 코딩

📚 TIL - 2025년 05월 03일 (토) / 코드 구조화와 실전 예제 분석

creator2041 2025. 5. 3. 22:50

🔍 오늘의 주제: 게임 코드 구조화의 필요성과 실전 적용

오늘은 코드 분리(모듈화)의 중요성과 실전 프로젝트 구조 예시를 중심으로 학습하고 정리했다.
초보 개발자일수록 모든 기능을 한 파일에 넣는 경향이 있는데, 이로 인해 발생하는 문제와 개선 방향을 집중적으로 분석했다.


🧠 학습 내용 요약

✅ 1. 왜 코드를 나눠야 하나?

  • 유지보수의 어려움: Game.cs에 모든 기능을 때려박으면 1주일 후 본인도 못 읽는다.
  • 협업의 충돌: 여러 사람이 하나의 파일을 수정하면 Merge Conflict의 지옥이 열린다.
  • 버그 추적 난이도 상승: 전투 버그 수정하려고 인벤토리 코드까지 훑어야 한다.
  • 의존성 얽힘: 전투 코드 수정했는데 상점에서 아이템이 사라진다? 나도 모르는 의존성 때문.

✅ 2. 코드 분리의 기본 원칙

  • 클래스 하나 = 역할 하나
    • ex) Player.cs는 플레이어만, BattleManager.cs는 전투만.
  • 실생활 비유: 요리사가 손질, 조리, 설거지까지 다 하면 효율 떨어지는 것과 같음.
  • UI vs 로직 분리: 계산 로직과 보여주는 로직은 분리해서 재활용과 유지보수를 쉽게.

✅ 3. 실제 프로젝트 코드 분석

기존에 우리 초보적인 팀원들이 함께 힘을 합쳐 진행한 텍스트RPG 프로젝트에서는 아래와 같이 기능이 분리되어 있음:

  • Game.cs: 전체 흐름 컨트롤 (게임 루프, 상태 관리)
  • Player.cs: 직업, 능력치, 장비, 인벤토리 초기화 포함
  • Item.cs + ItemManager.cs: 아이템 정의 및 초기화/목록 관리
  • Inventory.cs: 아이템 장착/해제 및 플레이어 능력치 반영
  • Monster.cs: 적 행동 정의 및 전투중 공격 처리
  • Shop.cs: 상점 UI 및 구매 흐름, 그리고 "육군 이등별" 특수 분기
  • Music.cs: NAudio 기반 배경음악 재생
  • Program.cs: Main 진입점

➡️ 이미 잘 분리된 구조라는 평가를 받았지만, 추가적으로 다음 리팩토링 고려 가능:

  • BattleManager.cs: 전투 시스템을 Game.cs에서 분리
  • UIManager.cs: 텍스트 출력, 애니메이션, 콘솔 색상 등을 따로 관리
  • StateManager.cs: 현재 상태가 전투인지 상점인지 등 전체 상태 전환 관리

🧩 기존 코드 리팩토링 제안: 더 나은 구조를 위한 설계

현재까지 작성된 Game.cs, Battle.cs, Player.cs, Monster.cs, Shop.cs는 각각 기능이 집중되어 있지만 점차 비대해지고 있으며, 유지보수와 확장성 측면에서 다음과 같은 역할 분리 구조로 개선할 수 있다. 다음은. AI가 생각할때 기능은 유지하며 양이 방대해 질때, 분리할수있는 구조의 제안이다.


🎮 Game.cs → 게임 시스템 전체 분리

현재 Game.cs는 게임 루프, 초기화, 상태 전환, 텍스트 출력, 인스턴스 관리 등 너무 많은 책임을 지고 있다.

📂 제안 분리 구조:

클래스명책임
GameController 게임 전체 상태 흐름(시작/종료, 상호작용 등) 제어
GameLoop 메인 루프 및 사용자 입력 처리
GameInitializer 플레이어 생성, 인벤토리 세팅, 첫 스토리 로딩 등
StoryManager 텍스트 스토리, 나레이션 처리
PlayerCreator 캐릭터 생성 전용 유틸리티
 

⚔️ Battle.cs → 전투 시스템 분리

현재 Battle.cs는 적 생성, 전투 UI, 턴 처리, 데미지 계산, 전투 종료까지 모두 책임진다.

📂 제안 분리 구조:

클래스명책임
BattleSystem 전투의 전체 흐름을 담당하는 상위 관리자
TurnManager 턴 순서/상태/지속시간 관리
ActionResolver 공격, 스킬, 방어 등 실제 효과 계산
BattleUI 전투 중 텍스트, 선택지, 효과 등 출력
BattleRewardManager 전투 종료 후 보상 (골드, 경험치, 아이템 등) 지급
 

👤 Player.cs → 플레이어 시스템 분리

Player 클래스는 현재 스탯, 인벤토리, 장비, 레벨 등 모든 데이터를 가지고 있다.

📂 제안 분리 구조:

클래스명책임
Player 이름, 직업 등 기본 정보와 참조 연결만 담당
PlayerStats 체력, 마나, 공격/방어, 회복 등 수치 관리
PlayerSkills 사용 가능한 스킬 목록과 효과 계산
EquipmentManager 무기/방어구 장착 및 능력치 반영
PlayerProgressionSystem 경험치, 레벨업, 성장 처리 로직
 

👹 Monster.cs → 몬스터 시스템 분리

몬스터는 단일 클래스로 AI와 행동 로직, 생성 모두 담당하고 있음.

📂 제안 분리 구조:

클래스명책임
MonsterBase 이름, 스탯, 데미지 처리 등 기본 속성
MonsterTypes 몬스터 종족/직업/등급별 확장
MonsterBehavior 특수 행동 로직 (도주, 스킬 사용 등)
MonsterSpawner 적 그룹 및 배치 결정, 생성 타이밍
AIDecisionMaker 턴마다 어떤 행동을 할지 결정 (AI 패턴)
 

🛒 Shop.cs → 상점 시스템 분리

Shop.cs는 상점 UI, 상품 목록, 가격 계산, 구매 처리까지 모두 담고 있음.

📂 제안 분리 구조:

클래스명책임
ShopManager 상점 메뉴/흐름 관리
ShopInventory 상품 목록 및 종류별 필터링
PriceCalculator 가격 계산 (직업, 난이도, 할인 등 반영)
ShopDialogue 상점 주인 대사 관리
TransactionProcessor 구매, 판매, 실패 처리 등 트랜잭션
 

💡 정리 및 기대 효과

  • 개발자 개인 기준: 클래스가 작고 단순해져 유지보수가 쉬워진다.
  • 팀 협업 기준: 각 시스템이 분리되어 Git 충돌이 줄고, 병렬 개발이 가능해진다.
  • 유지보수 기준: 버그 수정 시 영향을 미치는 범위를 예측할 수 있다.
  • 확장 기준: 새로운 기능 추가(예: '스킬 시스템' 추가 시 PlayerSkills에만 영향)를 안정적으로 진행할 수 있다.

✅ 4. 얻은 인사이트

  • 코드 구조화는 귀찮은 게 아니라, 시간을 아끼기 위한 장기적 투자다.
  • 코드가 분리될수록, 디버깅이 쉬워지고 버그가 줄어든다.
  • 나중에 다른 팀원이 참여하거나, 시간이 지나도 유지보수가 쉬워진다.
  • 게임 개발에서 '전투', '상점', '스토리', 'UI'는 모두 개별 시스템이다.

🛠️ 느낀 점

  • 처음부터 완벽하게 분리하려는 강박은 필요 없다. 기능 구현 후, 리팩토링하며 점진적으로 분리해도 충분하다.
  • 이제 Game.cs 안에서 전투나 상점 코드를 보는 것만으로도 이건 "아니다"라는 느낌이 올 정도로 감각이 생겼다.
  • 특히 Inventory.cs에서 Player를 참조하여 스탯을 조작하는 구조는 의존성 주입 개념을 알게 해줌.

✅ 정리 문장

코드를 나눈다는 건 머리로 감당할 수 있을 만큼 문제를 쪼갠다는 뜻이다.