1인 개발을 하다 보면 가장 경계해야 할 적은 바로 '과거의 나'입니다. 기능 구현을 최우선으로 하느라 덕지덕지 붙여놓았던 수많은 if-else 문과 하드코딩된 변수들은 결국 거대한 기술 부채가 되어 목을 조르기 시작합니다.
기술 부채의 폭발
플레이어 컨트롤러 스크립트가 어느새 2,000줄이 넘어가는 'God Class'가 되었습니다. 상태 제어 변수가 꼬이면서 공격 도중 회피 시 콜라이더가 증발하는 기상천외한 버그가 발생하기 시작했습니다.
1. 상태 패턴(State Pattern)을 통한 분리
이 혼란을 잠재우기 위해 각각의 행동을 불리언(Boolean) 변수로 관리하는 대신, 상태 자체를 하나의 독립된 객체로 분리하는 상태 패턴을 도입했습니다.
PlayerController.cs - Refactoring Status
void Update() {
- if (isAttacking && !isJumping && hasStamina) {
- PerformAttack();
- } else if (isJumping && isDashing) {
- AirDash();
- }
+ // State Pattern: 현재 할당된 상태 객체의 Update만 실행
+ currentState?.UpdateState();
}
2. 무기 시스템의 확장: 전략 패턴(Strategy)
내친김에 하드코딩 되어있던 무기 교체 시스템도 갈아엎었습니다. IWeapon 인터페이스를 만들어 공격 로직을 캡슐화함으로써, 개방-폐쇄 원칙(OCP)을 준수하도록 만들었습니다.
WeaponSystem.cs - Strategy Pattern
public void ExecuteAttack() {
- switch (currentWeaponType) {
- case WeaponType.Sword: MeleeAttack(); break;
- case WeaponType.Bow: ShootArrow(); break;
- }
+ // Strategy Pattern: 무기의 타입에 관계없이 인터페이스 메서드만 호출
+ equippedWeapon.ExecuteAttack();
}
3. Git Diff가 선사하는 카타르시스
조심스럽게 VS Code의 Source Control 탭을 열어 변경 사항을 확인했습니다. 수백 줄의 빨간색 텍스트가 사라지고, 간결하고 구조화된 초록색 텍스트가 자리를 잡았습니다. 모든 기능이 똑같이 작동하면서도 내부의 톱니바퀴는 훨씬 견고하게 맞물려 돌아가기 시작했습니다.