오늘은 상태 머신, 작동 방식 및 AASM gem을 사용하여 Ruby 프로젝트에서 사용하는 방법에 대해 알아보겠습니다.
지금 :
신호등을 상상해보세요...
빨간색, 녹색 또는 노란색일 수 있습니다.
색상이 바뀌면 다음 색상은 현재를 기반으로 합니다. 하나.
시각 장애인이 언제 건널 수 있는지 알 수 있도록 소리를 내는 종류라고 가정해 보겠습니다.
지금 :
당신은 이것을 위한 소프트웨어를 작성하고 있습니다.
매번 어떤 소리를 재생하고 다음에 어떤 색상을 내야 하는지 어떻게 알 수 있나요?
다음과 같은 if 문을 작성할 수 있습니다.
if @light.state == "green" @light.play_green_sound end if @light.state == "green" @light.change_to_yellow end # ...
이 상태 확인 코드는 어디에나 있습니다!
이를 어떻게 개선할 수 있습니까?
객체 지향 디자인 원칙을 적용하면 상태 디자인 패턴을 재발견하게 됩니다.
상태 디자인 패턴이란 무엇입니까?
상태 디자인 패턴은 상태 머신을 구현하는 한 가지 방법입니다.
3개의 구성요소가 필요합니다. :
Context
클래스, 이 클래스는 현재 상태를 알고 있습니다.State
클래스에서 이 클래스는 개별 상태에서 구현해야 하는 메서드를 정의합니다.- 모든 주에 대해 하나의 클래스. 이 클래스는
State
에서 상속됩니다. 수업
신호등 예에서 컨텍스트는 TrafficLight
입니다. 그 자체.
그리고 상태는 Green
입니다. , Red
&Yellow
.
모든 주에서 무엇을 해야 할지 알게 될 것입니다.
큰 이점 ?
모든 상태는 자신을 알고 있으므로 현재 상태를 확인할 필요가 없습니다. 이는 종종 복잡성의 원인이 되는 덜 조건부 문장으로 변환됩니다.
신호등 구현
이 패턴의 실제 구현을 위한 코드를 살펴보겠습니다.
다음은 TrafficLight
입니다. :
class TrafficLight def initialize @state = nil end def next_state(klass = Green) @state = klass.new(self) @state.beep @state.start_timer end end
기본 State
는 다음과 같습니다. :
class State def initialize(light) @light = light end def beep end def next_state end def start_timer end end
예, 이 3가지 방법은 비어 있습니다.
이 "인터페이스"를 정의하는 것은 다른 프로그래밍 언어(예:Java)의 일반적인 규칙이지만 Ruby에서는 널리 사용되지 않습니다.
이것은 데모용입니다.
그러나 우리는 여전히 initialize
모든 상태에 컨텍스트가 필요하기 때문에 모든 상태 간의 메서드 (TrafficLight
object) 상태 변경 신호 .
지금 :
3가지 상태가 서로 매우 유사해 보이기 때문에 그 중 하나에 대한 코드를 보여 드리겠습니다.
다음은 Green
입니다. 상태:
class Green < State def beep puts "Color is now green" end def next_state @light.next_state(Yellow) end def start_timer sleep 5; next_state end end
모든 상태는 다음으로 전환하는 방법과 시기를 알고 있습니다.
AI 게임 예시
상태 머신을 사용하여 RubyWarrior와 같이 현재 상태에 의존하는 게임을 해결할 수 있습니다.
RubyWarrior에서는 플레이어 개체와 보드가 제공됩니다.
목표는 :
- 보드의 모든 적을 물리치세요
- HP를 0 이상으로 유지하면서 출구에 도달
한 번에 하나씩 이동할 수 있으며 레벨을 완료하려면 좋은 선택을 해야 합니다.
현재 상태를 보면 선택하는 데 도움이 됩니다.
이것이 상태 머신이 좋은 솔루션인 이유입니다.
예시 :
class Attacking < State def play(warrior) warrior.attack! @player.set_state(Healing) unless enemy_found?(warrior) end end
이것은 우리 전사가 있을 수 있는 상태 중 하나입니다. 시야에 적이 없을 때 Healing
로 이동합니다. 전투 피해로부터 회복하는 상태입니다.
AASM 보석 사용
전환이 유효한지 확인하면서 현재 상태를 추적하려면 AASM과 같은 상태 머신 gem을 사용할 수 있습니다.
이 보석은 이벤트라는 아이디어를 기반으로 제작되었습니다. (조명 스위치를 누르는 것과 같은) 다른 상태로의 전환을 트리거합니다.
예시 :
require 'aasm' class Light include AASM aasm do state :on, :off event :switch do transitions :from => :on, :to => :off, :if => :on? transitions :from => :off, :to => :on, :if => :off? end end end
이 클래스를 사용하는 방법 :
light = Light.new p light.on? # true light.switch p light.on? # false
이 상태 머신을 사용하면 현재 상태가 "꺼짐"인 경우에만 "켜짐" 상태로 전환할 수 있습니다. 상태 전환 중에 특정 코드를 실행하기 위해 여러 콜백(전/후)을 가질 수도 있습니다.
이러한 콜백 다음과 같은 항목이 포함될 수 있습니다.
- 이메일 보내기
- 상태 변경 기록
- 실시간 모니터링 대시보드 업데이트
또한 AASM에는 ActiveRecord
를 사용하여 현재 상태를 데이터베이스에 저장하는 옵션이 있습니다. .
AASM 보석 비디오
요약
상태 머신, 상태 디자인 패턴 및 AASM gem에 대해 배웠습니다! 내 Ruby 뉴스레터(구독자 7000명 이상)를 구독하여 지금 계속 학습하여 새 기사 및 구독자 전용 Ruby 팁을 놓치지 마세요. .
이제 이러한 새로운 아이디어로 연습할 시간입니다 🙂
읽어주셔서 감사합니다!