일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 오라클 디비
- 자바 프로젝트
- 파이썬 소스
- SQL
- 백준 알고리즘
- smart cast
- dynamic query
- hyperledger
- gradle
- 학점
- K6
- 티스토리
- jsp
- 파이썬
- 운영체제
- 알고리즘
- 프로젝트
- 리눅스
- oracle
- JVM
- 오라클
- 자바
- 문법 정리
- resilience4j
- auto configure
- spring
- c#
- MongoDB
- 유사코드
- 초대장
Archives
- Today
- Total
모종닷컴
유한 상태 기계 (Finite-State Machine, FSM) 본문
반응형
유한 상태 기계
컴퓨터 프로그램을 설계할 때 쓰이는 모델이라고 설명되어 있습니다. 간단하게 '상태 기계'라고 부르기도 한다고 하네요. 저는 주로 상태 기계라는 용어로 많이 들었던 것 같아요. 이름으로 짐작할 수 있는데 유한 상태 기계는 유한한 개수의 상태를 가질 수 있음을 말합니다. 또한 몇 가지 조건이 붙는데 이 유한 상태 기계는 오로지 하나의 상태만 가질 수 있으며 특정 Event에 의해서만 다른 상태로 변화할 수 있다고 합니다. 그리고 이렇게 Event에 의해 상태가 변화하는 것을 전이(Transition)이라고 합니다.
일상생활에서 유한 상태 기계를 찾아보자.
가장 대표적으로 언급되는 일중 하나는 스위치입니다. 스위치는 ON, OFF 두 개의 상태만 가질 수 있습니다. 그러면 생각해볼게요. 각각의 상태로 전이할 수 있는 동작이 무엇이 있을까요? OFF인 스위치를 ON 상태로 만들기 위해서는 '스위치를 위로 올린다'라고 볼 수 있을 것 같고, ON 상태인 스위치를 OFF로 만들기 위해서는 '스위치를 아래로 내린다'로 볼 수 있겠네요.
저는 커피를 굉장히 좋아하는데 커피 머신을 코드로 표현해보도록 하겠습니다. 대충 생각하면서 짜놓은 거라 말도 안 되는 기계가 만들어질 수 있지만 그냥 넘어가 주세요 ㅎㅎ..
상태 클래스
abstract class CoffeeMachineStatus {
abstract val desc: String // 커피 머신에 표시될 상태 이름.
/**
* [toBe] 상태로 전이한다.
* @param toBe 변경하려는 상태
* @return 변경된 상태
* @throws IllegalArgumentException
* */
fun transitionTo(toBe: CoffeeMachineStatus): CoffeeMachineStatus {
return if (toBe is Initialize) {
Ready()
} else {
require(isChangeable(toBe))
toBe
}
}
/**
* 현재 상태가 [toBe]로 전이할 수 있는지를 판단.
* */
@kotlin.jvm.Throws(IllegalArgumentException::class)
abstract fun isChangeable(toBe: CoffeeMachineStatus): Boolean
}
class Ready : CoffeeMachineStatus() {
override val desc = "준비 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Order
}
class Order : CoffeeMachineStatus() {
override val desc = "주문 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Calc
}
class Calc : CoffeeMachineStatus() {
override val desc = "계산 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Making
}
class Making : CoffeeMachineStatus() {
override val desc = "커피 내리는 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Complete
}
class Complete : CoffeeMachineStatus() {
override val desc = "완료 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Ready
}
class Initialize : CoffeeMachineStatus() {
override val desc = "초기화 상태"
override fun isChangeable(toBe: CoffeeMachineStatus) = toBe is Ready
}
- 각 상태에서는 전이할 수 있는 상태를 정의합니다.
커피 머신
class CoffeeMachine {
private var status: CoffeeMachineStatus // 하나의 상태만 가진다. 최초 상태는 READY
fun printStatus() {
log.info { "현재 기계 상태 : ${status.desc}" }
}
init {
this.status = Ready()
}
fun calc() {
log.info { "계산 시작." }
changeStatus(Calc())
}
fun order() {
log.info { "주문 시작." }
changeStatus(Order())
}
fun making() {
log.info { "커피 만들기 시작." }
changeStatus(Making())
}
fun complete() {
log.info { "커피가 만들어졌습니다." }
changeStatus(Complete())
}
fun initialize() {
log.info { "기계를 초기화합니다." }
changeStatus(Initialize())
}
private fun changeStatus(toBe: CoffeeMachineStatus) {
try {
this.status = status.transitionTo(toBe)
} catch (e: IllegalArgumentException) {
log.info { "기계가 오동작 하였습니다. 초기화합니다." }
this.status = status.transitionTo(Initialize())
}
}
}
- 하나의 상태만 가집니다.
- 최초 생성시 대기 상태로 초기화합니다.
- 특정 메서드(=이벤트)가 일어나면 상태 전이가 일어납니다.
- 상태 전이에 실패하면 초기화 상태로 돌립니다.
클라이언트
class Client {
private lateinit var coffeeMachine: CoffeeMachine
@Before
fun init() {
coffeeMachine = CoffeeMachine()
}
@Test
fun `정상적인 주문`() {
coffeeMachine.order()
coffeeMachine.printStatus()
coffeeMachine.calc()
coffeeMachine.printStatus()
coffeeMachine.making()
coffeeMachine.printStatus()
coffeeMachine.complete()
coffeeMachine.printStatus()
coffeeMachine.initialize()
coffeeMachine.printStatus()
}
@Test
fun `손님 뭘 드시고 싶으신거에요`() {
coffeeMachine.calc()
coffeeMachine.printStatus()
}
@Test
fun `에이 그냥 안먹을래`() {
coffeeMachine.order()
coffeeMachine.printStatus()
coffeeMachine.calc()
coffeeMachine.printStatus()
coffeeMachine.initialize()
coffeeMachine.printStatus()
}
}
반응형
'기술 용어' 카테고리의 다른 글
Swap memory (0) | 2022.11.27 |
---|---|
서버 이중화 동작 방식 (0) | 2022.09.11 |
데이터 레이크 (0) | 2022.08.14 |
온프레미스(On-premise) (0) | 2022.08.12 |
C.A.P 이론 (0) | 2022.07.16 |