본문 바로가기

Dev./Error.

[Error] 키오스크 트러블 슈팅 1 - 상태 패턴

728x90
반응형

enum 상수과 switch문으로 관리하던 상태에서  상태 패턴 적용 해보는 것도 괜찮을 것 같다고 하셔서 검색 후 내 코드에 적용해 보았다. 기존에 키오스크 실질적인 기능을 담당하는 start() 메소드가 굉장히 길었는데 그 부분은 간략하게 생략되었지만 고려해봐야할 몇가지 문제가 생겼다. 그 과정을 정리해보려고 한다.

목표

기존 enum + switch 구조에서 상태 패턴(State Pattern)을 적용하여 Kiosk 클래스의 start 메소드 단순화 및 코드 재사용성 향상을 시도

상태 패턴 적용 후 장점

 

  • start() 메소드가 간단해지고, 상태 전환 로직이 상태 객체로 분리됨.
  • 상태별 클래스(StartState, MainMenuState, ...)를 독립적으로 관리 가능 → 재사용성, 확장성 향상.
  • 새로운 상태 추가 시 기존 switch 문 수정 없이 상태 클래스 추가로 유지보수 가능

겪은 문제

1. 참조 문제

  • SubMenu부터 Kiosk → menuList → Menu → MenuItem 등 깊은 참조가 발생.
  • 상태 클래스가 메뉴 접근을 위해 Kiosk 내부 구조까지 알아야 하고, 깊은 참조 문제를 해결하기 위한 추가 메소드(getMenuByIndex, getMenuItemListByMenuIndex)가 늘어남.
  • Optional과 인덱스를 동시에 쓰면서 참조 체인 관리가 헷갈리기 시작
    예: Optional<Menu> + 1-based 사용자 입력 → 0-based 리스트 접근 → Optional.get() - 1 조합으로 혼동 발생

2.  인덱스 문제

  • 1-based 사용자 입력과 0-based 리스트 인덱스 혼용 → 잘못된 메뉴 선택 가능
  • 상태 전이마다 참조 체인을 유지해야 하므로, SubMenu, Cart 등 다음 상태에서도 동일 인덱스를 전달해야하는 이슈
  • Optional 객체를 쓰더라도, 실질적 참조에서 혼동은 여전히 존재

3. 디버깅 난이도

  • 상태 수만큼 클래스 증가, 추가 메소드 증가
  • 상태 패턴 적용 후 start 메소드는 간단해졌지만, 상태 객체별 참조와 인덱스 관리 때문에 디버깅이 오히려 힘들어졌다.
  • 동적으로 변하면서 한눈에 보이지 않아 인덱스 오류 흐름을 찾기위해 프린트문으로 디버깅해야하는 일이 발생
  • 단순 직선적 메뉴 흐름에서 오히려 코드 복잡도 증가

 

결론 및 배운 점

 

  • 상태 패턴은 복잡한 상태 전이, 이벤트 기반 앱에서 장점이 크다.
  • 단순한 직선적 메뉴 앱(ACCESS → MAIN_MENU → SUB_MENU → CART → ORDER → EXIT)에서는 enum + switch 구조가 충분하고 더 직관적임
  • Optional, 인덱스, 상태 참조 체인을 관리할 때 혼동을 줄이는 방법을 이번 리팩토링을 통해 경험함
  • 상태 패턴 적용 경험 자체가 의미 있음: 재사용성, 확장성, 단일 책임 원칙 위반 가능성 등 실제 트레이드오프를 체험함

완전히 롤백하진 않았고 enum 람다에서 각 상태에 따른 메소드를 참조하게끔 해서 메소드 의존성도 줄이며 재사용성,확장성을 늘리는 리팩토링을 진행했다.

 

728x90
반응형