Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Ruby로 상태 머신 마스터하기:실용 가이드

상태 머신은 무언가의 가능한 모든 상태를 보유할 수 있습니다. 그리고 이러한 상태 간에 허용되는 전환이 있습니다. 예를 들어 문의 상태 머신에는 두 가지 상태(open)만 있습니다. 그리고 closed ) 및 전환이 2개(opening)뿐입니다. 그리고 closing ).

반면에 복잡한 상태 기계는 수백 개의 전환이 있는 여러 가지 다른 상태를 가질 수 있습니다. 실제로 주위를 둘러보면 유한 상태 기계가 주변에 있다는 것을 알 수 있습니다. 웹사이트에서 물건을 살 때, 자판기에서 과자 한 갑을 얻을 때, 심지어 ATM에서 돈을 인출할 때도 마찬가지입니다.

이번 포스팅에서는 Ruby에서 상태 머신을 설정하고 상태 머신 gem을 사용하는 방법을 살펴보겠습니다.

개발 중인 상태 머신

개발 중에 상태 머신이 언제 필요합니까? 간단한 대답은 상태 전환에 대한 여러 규칙을 모델링하거나 일부 전환에 부작용을 수행하려는 경우입니다. 여기서 핵심은 상태 머신의 이점을 누릴 수 있는 애플리케이션 부분을 식별하는 것입니다. 저에게 항상 적합한 좋은 예는 Order입니다. 전자상거래 애플리케이션의 맥락에서.

온라인으로 제품을 판매하는 간단한 애플리케이션의 경우 Order 여러 상태 중 하나일 수 있습니다:

  • created
  • processing
  • ready
  • shipped
  • delivered
  • void

다음 다이어그램에서 허용되는 전환을 확인할 수 있습니다.

Ruby로 상태 머신 마스터하기:실용 가이드

상태 시스템의 형태로 주문을 시각화하면 제품 주문부터 배송까지 전체 흐름을 즉시 명확하게 이해할 수 있습니다. 그리고 우리 개발자에게는 흐름의 특정 지점에서 수행할 수 있는 작업과 수행할 수 없는 작업에 대한 명확하고 설정된 단계가 가능해집니다.

즉, 매우 광범위한 문제에 대해 이것을 선택하여 토끼 구멍에서 뛰어내린 다음 추론하고 따라가기 어려운 수백 개의 상태로 끝나는 것은 쉽습니다. 따라서 구현하기 전에 제안된 상태 머신에 대한 최상위 아이디어와 상태 차트를 항상 준비하십시오.

Ruby의 첫 번째 상태 머신

OrderStateMachine을 구현해 봅시다. 루비와 함께.

 

이는 충분히 간단한 구현입니다. 상태 시스템에서 가능한 각 전환에 대해 몇 가지 온전성 검사를 수행하고 전환을 수행하는 새로운 메서드를 정의합니다.

위 구현의 가장 큰 장점은 모든 것이 명시적이라는 점입니다. 모든 신규 개발자는 상태 머신의 전체 범위를 매우 빠르게 이해할 수 있습니다.

전환에 몇 가지 부작용을 추가할 수 있는 방법을 살펴보겠습니다. 포장되어 배달 가능한 주문을 자동으로 배송합니다.

 

순진한 구현은 훌륭하게 작동하지만 특히 전환과 조건이 많은 경우 지나치게 장황합니다.

Ruby Toolbox를 빠르게 확인하면 상태 시스템에 대한 몇 가지 보석이 표시됩니다.state_machinesaasm 가장 널리 사용되는 두 가지가 있으며 Rails와 함께 사용하려는 경우 둘 다 ActiveRecord 어댑터와 함께 제공됩니다. 두 가지 모두 철저한 테스트를 거쳐 생산 준비가 완료되었으므로 상태 시스템을 구현해야 하는 경우 확인하세요.

Ruby에서 상태 머신 Gem 사용

이번 게시물에서는 Order에 대한 상태 머신을 모델링하는 방법을 설명하겠습니다. state_machines 사용 보석.

 

위 클래스는 간단한 상태 머신과 가능한 모든 전환을 정의합니다. 또한 주문에 따라 많은 유틸리티 메소드를 자동으로 노출합니다.

 

Ruby의 상태 머신 Gem으로 부작용 실행

실제 시스템의 일반적인 경우와 마찬가지로 상태 머신의 많은 전환에는 부작용이 따릅니다. state_machines gem을 사용하면 이를 쉽게 정의하고 실행할 수 있습니다. 두 가지 부작용을 추가해 보겠습니다.

  1. ready로의 모든 전환 시 , 주문이 deliverable인 경우 배송 위탁을 생성하세요. .
  2. fail_delivery 전체에서 이벤트를 알리는 이메일을 사용자에게 보냅니다.
 

평소대로 다음 순서대로 전환을 수행할 수 있습니다.

 

state_machines에 대한 Github 페이지를 확인하는 것이 좋습니다. gem이 제공하는 가능한 모든 옵션에 대해 알아보세요.

Ruby on Rails에서 ActiveRecord와 함께 State Machines Gem 사용

이전에 논의한 대로 state_machinesaasm ActiveRecord를 지원합니다. state_machines를 사용하는 경우 ActiveRecord를 사용하여 gem을 구현하면 많은 것이 변경되지 않습니다. 이 게시물의 이전 섹션에서 이미 논의한 내용 대부분을 계속 사용할 수 있습니다.

다음은 몇 가지 추가 기능입니다.

  1. 부작용은 트랜잭션 내부에서 발생합니다. 이는 전환 후크 내에서 일부 데이터베이스 작업을 수행하고 트랜잭션이 실패하는 경우 상태 변경이 커밋되지 않음을 의미합니다. use_transactions를 참조하세요. 이 동작을 비활성화하려는 경우.
  2. 다른 모든 ActiveRecord 콜백과 마찬가지로 전환에서 현재 모델의 속성을 업데이트하려면 before_transition 내에서 이 작업을 수행해야 합니다. 콜백. after_transition 내의 속성을 업데이트하려면 , 모델을 다시 저장해야 합니다. 다음 예를 확인하세요:
 
  1. Gem은 상태별로 모델을 필터링하는 범위를 자동으로 제공합니다. 예를 들어 Order.with_state(:processing)을 수행할 수 있습니다. 모든 처리 주문을 찾으려면 Order.without_state(:processing) 처리 중이 아닌 모든 주문을 찾으려면
  2. 일치하는 전환 없이 상태 변경을 시도하는 경우(예:processing에서) delivered로 ), 레코드가 저장되지 않고 유효성 검사 오류에 오류가 추가됩니다. 생성된 오류 메시지를 국제화하려면 구성 파일 내의 상태 및 이벤트에 대한 번역을 제공하는 몇 가지 키를 추가하기만 하면 됩니다(예:en.yml) ):
 

참고 :ActiveRecord 성능 문제를 해결하려면 이 게시물을 확인하세요.

마무리:Ruby로 상태 머신 구축

이 게시물에서 우리는 간단한 상태 머신을 구축하기 전에 개발 단계에서 상태 머신을 사용하는 이유를 살펴보았습니다. 마지막으로 Ruby 및 Ruby on Rails에서 상태 머신 gem을 사용하는 방법을 살펴보았습니다.

이제 상태 머신에 대한 기본적인 이해를 마쳤으므로 이미 상태 머신을 사용하고 있거나 이를 통해 큰 이점을 얻을 수 있는 여러 시나리오를 인식하게 되실 것입니다.

다음 시간까지 상태 머신 구축에 행운이 있기를 바랍니다!

추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!

Ruby로 상태 머신 마스터하기:실용 가이드

풀킷 고얄

우리의 객원 저자인 Pulkit은 수석 풀스택 엔지니어이자 컨설턴트입니다. 여가 시간에는 자신의 블로그에 자신의 경험을 글로 씁니다.

Pulkit Goyal의 모든 기사