상태 머신이란?
유한 상태 머신(FSM)은 다음 네 가지 요소를 모델링합니다:
-
상태(States): (예:
pending,approved,rejected) -
이벤트(Events): 전환을 유발하는 트리거
-
상태 간 유효한 경로(Valid paths)
-
선택적 가드(Guards) 및 콜백(Callbacks)
이는 결제가 완료되기 전에 주문을 배송하는 것과 같은 유효하지 않은 동작으로부터 시스템을 보호합니다.
젬 없는 간단한 예시
개념 이해를 돕기 위해 젬 없이 Order 클래스를 통해 상태 전환을 구현하는 예시를 살펴볼 수 있습니다. 이 방식은 아이디어를 이해하는 데 좋지만, 실제 애플리케이션에서는 젬을 사용하는 것이 더 효율적입니다.
```ruby class Order STATES = %i[pending paid shipped delivered].freeze attr_reader :state
def initialize @state = :pending end
def pay ; transition_to(:paid) if state == :pending; end def ship ; transition_to(:shipped) if state == :paid; end def deliver ; transition_to(:delivered) if state == :shipped; end
private
def transition_to(new_state) puts “Transition: #{state} → #{new_state}” @state = new_state end end ```
가장 인기 있는 Ruby 상태 머신 젬
1. AASM (대부분의 Rails 앱에 권장)
Ruby 생태계에서 가장 널리 채택된 솔루션 중 하나입니다.
-
장점: 깔끔하고 읽기 쉬운 DSL, Rails 친화적, 가드, 콜백, 여러 머신 지원, 좋은 커뮤니티 지원
-
단점: 대규모 워크플로우에서 복잡해질 수 있음, DSL 유연성으로 인해 정리되지 않으면 코드가 지저분해질 수 있음
2. state_machine (고전적이지만 유지보수 중단)
많은 개발자들이 사랑했던 오리지널 DSL입니다.
-
장점: 아름다운 DSL, 역사적으로 성숙하고 안정적
-
단점: 더 이상 활발히 유지보수되지 않음, 많은 포크로 인한 파편화된 생태계
-
권장: 레거시 앱에 적합하며, 새로운 앱에는 권장되지 않습니다.
3. Statesman (감사 추적에 용이한 워크플로우)
상태 전환을 데이터베이스 테이블에 저장하는 다른 철학을 가집니다.
-
장점: 규정 준수 및 이력 추적에 탁월, 깔끔한 아키텍처, 길고 복잡한 워크플로우에 적합
-
단점: 더 많은 상용구 코드, 모델 콜백 없음, 간단한 앱에는 과할 수 있음
4. Workflow (경량 Ruby FSM)
작고 빠른 것을 원할 때 적합합니다.
-
장점: 작고 간단함, Rails가 아닌 Ruby 앱에 매우 적합
-
단점: Rails에서 인기가 적음, 고급 기능 부족
어떤 젬을 사용해야 할까요?
-
AASM: 대부분의 Rails 앱에 적합. 쉽고 강력하지만 복잡해질 수 있습니다.
-
state_machine: 레거시 앱에 적합. 깔끔한 DSL을 제공하지만 유지보수되지 않습니다.
-
Statesman: 감사 추적이 필요한 워크플로우에 적합. 로그 기록 및 구조가 좋지만 상용구 코드가 많습니다.
-
Workflow: 경량 Ruby 앱에 적합. 간단하고 빠르지만 기능이 적습니다.