- Published on
๐คฟ ์จ ๊พน ์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ 2 : ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine)
- Authors
- Name
- Woojin Son
๐คฟ ์จ ๊พน ์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ 2 : ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine)
- ๐คฟ ์จ ๊พน ์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ : ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine)
- ๐ค Intro
- ๐ง ์ํ (State) ์ ๋ํ ์ดํด
- ๐ง ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine) ์ ๋ํ ์ดํด
- ๐ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ด์ผ๊ธฐ : ์คํ ๋งํ ์ด๋ก ๊ณผ ํ๋ง ๋จธ์
- โ๏ธ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ด์ผ๊ธฐ : ์ปดํ์ผ๋ฌ
- ๐ฑ ์ค๋ฌด ์ด์ผ๊ธฐ : Spring State Machine
- ๐ช Outro
- ๐ Reference
๐ค Intro
๋ค์ ๋์์์ต๋๋ค. ์ฌ์ ํ ๋ฐ์ดํฐ๋ฅผ ์ํ์ฐจ ํ๊ณ ์๋ ์ํํธ์จ์ด ์ก๋ถ ์์ฐ์ง์ ๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine) ๋ผ๋ ๊ฐ๋ ์ ๊ฐ์ ธ์์ต๋๋ค.
Computer Science, ํํ ๋งํ๋ ์ปดํจํฐ๊ณตํ์ ์ ๊ณต ํ ์ฌ๋์๊ฒ๋ ์คํ ๋งํ ํน์ ์ปดํ์ผ๋ฌ ์ด๋ก ์๊ฐ์ ๋ค์ด๋ณด์ จ์์ง๋ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ ๊ณต์๊ฐ์ ์ฐธ ์ฌ๋ฐ๊ฒ ๋ค์์ง๋ง ๋ง์ ๋น์์ ์ง์์ผ๋ก ๋ชจ๋ ๊ฑธ ์ดํดํ๊ธด ์ด๋ ค์ ๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค.
์ด๋ฒ ํฌ์คํ
์์๋ ์ด ์ ํ ์ํ ๊ธฐ๊ณ
์ ๋ํ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ด์ผ๊ธฐ์ ์ค๋ฌด ์ฌ๋ก์ ๋ํด ์ด์ผ๊ธฐ ํด ๋ณผ๊น ํฉ๋๋ค.
๊ฐ๋ฐ์ ์ธ์๋ ๋ง์ ์ฌ๋๋ค์ด ์ฌ๋ฐ๊ฒ ์ฝ์ ์ ์๋๋ก ์ต๋ํ ์ฝ๋๋ ๋ฐฐ์ ํ๊ณ ์์ฑ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. (๋ง ์ฒ๋ผ ์ฝ๊ฒ ์ง์ผ์ง์ง ์์ง๋ง...๋ ธ๋ ฅ ํด ๋ณด๊ฒ ์ต๋๋ค. ๐ค)
๊ทธ๋ผ ํ๋ฒ ์จ ๊พน ์ฐธ๊ณ ๋ฅ ๋ค์ด๋ธ! ์์ํ๊ฒ ์ต๋๋ค.
๐ง ์ํ (State) ์ ๋ํ ์ดํด
์ฐ์ ์ํ ๋ผ๋ ๊ฒ์ ๋ํด ํ๋ฒ ์ง๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค. ์ํ๋ผ๋ ๋จ์ด์ ์ฌ์ ์ ์ ์๋ ์๋์ ๊ฐ์ต๋๋ค.
์ํ, ๏งบๆ ์ฌ๋ฌผยทํ์์ด ์ฒํด ์๋ ํํธ์ด๋ ๋ชจ์.
์ํํธ์จ์ด์ ์ธ๊ณ์์ ์ฌ๋ฌผ์ด๋ผ๊ณ ํ ์ ์๋ ๊ฑด ์์ ๋ฐ์ดํฐ ๋จ์ ํ๋ ๋ถํฐ ํํ ๊ฐ์ฒด๋ผ๊ณ ๋ถ๋ฅด๋ ์๋ฏธ ์๋ ๋ฐ์ดํฐ ๋ฉ์ด๋ฆฌ๋ผ๊ณ ํ ์ ์์ต๋๋ค.
๊ฐ๋จํ ์ ํธ๋ฑ ์ํํธ์จ์ด๋ฅผ ์๊ฐ ํด ๋ด๋ ์ ํธ๊ฐ 3 ๊ฐ์ ์ํ๋ก ๋๋์ฃ . ๋นจ๊ฐ๋ฑ, ๋ ธ๋๋ฑ, ์ด๋ก๋ฑ ์ด๋ ๊ฒ์.
๐ง : ์๋ ์ฐ๋ฆฌ๋ ์ ํธ๋ฑ์ ์ํ๊ฐ 4๊ฐ๊ฐ ์๋๋ฐ์?
๐ : ...๐๐
์ํ๋ ๊ณ์ํด์ ๋ณํ๋ ํน์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ง์ฝ ๋ณํ์ง ์๋๋ค๋ฉด ๊ทธ๊ฑด ์ํ๋ผ๊ณ ๋ถ๋ฅด์ง ์์์. ์์ (Constant) ๋ผ๊ณ ๋ถ๋ฅด์ฃ . ์ ํธ๋ฑ์ด ์ํ๊ฐ ๋ณํ์ง ์๋ ์ํ๋ผ๋ฉด ์ ํธ๋ฑ์ผ๋ก์จ ์๋ฏธ๊ฐ ์์ฃ .
๐ง ์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine) ์ ๋ํ ์ดํด
์ํ๋ ๊ณ ์ ๋์ด์์ง ์์ต๋๋ค. ๋ณํ๋ ํน์ฑ์ ๊ฐ์ง๊ณ ์๋๋ฐ, ์ด ์ํ๊ฐ ๋ณํ๋ ์กฐ๊ฑด์ ํํ ๋งํด์ ์ด๋ฒคํธ๋ผ๊ณ ํฉ๋๋ค.
๐ฅณ : ๋ญ์ ์ด๋ฒคํธ? ์ง ์์ ์์์ฌ ๋งํธ์์ ํ์ ์ธ์ผ์ ํ๋ค๊ตฌ์?
๐ : ๐... ๊ทธ๋์ ๊ทธ๊ฒ๋ ๋ง๊ธด ํฉ๋๋ค. ํด๋น ์กฐ๊ฑด์ ์ํด ์ ์ง๊ฐ์ด ์ด๋ฆฌ๋๊น์.
์ ํธ๋ฑ์ ์ํ๊ฐ ๋ณํ๋ ์กฐ๊ฑด์ผ๋ก๋ ์๊ฐ์ด ์๊ฒ ์ฃ . ์ ์ฒด ์ฌ์ดํด์ ๋ง์ฝ 5๋ถ์ผ๋ก ์ก๋๋ค๋ฉด, ๊ทธ ์ค 3๋ถ 55์ด๋ ๋นจ๊ฐ๋ถ, 5์ด๊ฐ ๋ ธ๋๋ถ, 1๋ถ๊ฐ ์ด๋ก๋ถ์ ํ ๋นํ๋ ์์ผ๋ก ์กฐ๊ฑด์ ๊ฑธ๊ฑฐ์์. 5๋ถ์ด ๋๋๋ฉด ๋ค์ ์ฌ์ดํด์ ๋๋ฆด๊ฒ๋๋ค.
์ํ๊ฐ ์ด๋ฒคํธ์ ๋ฐ๋ผ ๋ณํ๋ ๊ฒ์ ์ํ์ ์ ์ด (Transition) ๋ผ๊ณ ๋งํฉ๋๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ค ์ํ๋ก ๋ฐ๋์ด์ผ ํ๋ ์ง์ ๋ํ ์ํ์ ๋ชจ๋ธ์ '์ ํ ์ํ ๊ธฐ๊ณ (Finite State Machine)' ๋๋ '์ ํ ์คํ ๋งํค (Finite Automaton)' ์ด ๋ผ๊ณ ํฉ๋๋ค. ์ํ์ด๋ผ๋ ๋ง์ด ๋์์ ํ ์นซ ํ์ ๋ถ๋ค์ ๊ฑฑ์ ๋ง์ธ์. ์ด๋ฒ ํฌ์คํ ์์ ์ซ์๋ ์ต๋ํ ๋ฐฐ์ ํ ํ ๋๊น์.
์คํ ๋งํ ๋ผ๋ ๋จ์ด๋ '์ ํด์ง ๊ท์น์ ๋ฐ๋ผ ์ ๋ ฅ์ ์ฝ์ผ๋ฉด์ ๋ด๋ถ์ ์ํ๋ฅผ ๋ฐ๊พธ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ ๊ธฐ๊ณ์ ์ํ์ ๋ชจ๋ธ' ์ด๋ผ๋ ์๋ฏธ๋ฅผ ๋ด๊ณ ์์ต๋๋ค. '์๋'์ ์๋ฏธํ๋ ๊ทธ๋ฆฌ์ค์ด 'ฮฑแฝฯฯฮผฮฑฯฮฑ'์์ ์ ๋ํ์ฃ .
๐งฉ ํต์ฌ ์์
FSM์ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ์ง๋๋ค:
- State (์ํ) : ์์คํ ์ด ๊ฐ์ง ์ ์๋ ์ ํํ ์ํ๋ค
- Event/Input (์ ๋ ฅ) : ์ํ๋ฅผ ๋ณํ์ํค๋ ์๊ทน
- Transition (์ ์ด) : ์ ๋ ฅ์ ๋ฐ๋ผ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ณํ๋์ง์ ๋ํ ์ ์
- Initial State (์ด๊ธฐ ์ํ)
- Final/Accepting State (์ข ๋ฃ ์ํ) (์ต์ )
์: ์ปคํผ ์ฃผ๋ฌธ FSM
[์ฃผ๋ฌธ๋๊ธฐ] --์ฃผ๋ฌธโ [์ ์กฐ์ค] --์๋ฃโ [ํฝ์
๋๊ธฐ] --์๋ นโ [์๋ฃ]
๐ฏ ์ ์ ํํด์ผ ํ ๊น์??
์ํ๊ฐ ๋ฌดํํ๋ค๋ฉด ์์คํ ์ ์์ธก ๋ถ๊ฐ๋ฅํด์ง๋๋ค. ์ค๊ณ์ ๋๋ฒ๊น ์ด ์ด๋ ค์์ง๊ณ , ๋์์ ์ฆ๋ช ํ๊ธฐ๋ ์ด๋ ต์ฃ . ์ ํธ๋ฑ์ ์ํ๊ฐ ๋ฌดํ์ด๋ผ๊ณ ์๊ฐ ํด ๋ณผ๊น์?
๐ : ์ ๊ธฐ์ ์์ ์จ! ๋นจ๋ฆฌ๋นจ๋ฆฌ ์๊ฐ์?
๐ : ์๋ #^#%& ์ผ ์ ํธ๋ฑ์ด ์ด์ํ๋ค๊ณ !
์ ํ ์ํ๋ ๋ ผ๋ฆฌ์ ์ผ๋ก ์์ ํ ์ ์ํ ์ ์๋ ์ํ ์งํฉ์ด๋ผ๋ ๋ป์ ๋๋ค.
๐ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ด์ผ๊ธฐ : ์คํ ๋งํ ์ด๋ก ๊ณผ ํ๋ง ๋จธ์
๐ ๊ฐ์
์ฌ๋ด์ด์ง๋ง ์ปด๊ณต์ด ์ฝ๋ฉ ๋ฐฐ์ฐ๋ ๊ณณ์ด๋ผ ์คํดํ์๋ ๋ถ๋ค์ด ๊ฐ๋ ์์ผ์ญ๋๋ค...
๋ฌผ๋ก ๊ณผ ํน์ฑ์ ์ฝ๋ฉ์ ๋ง์ด ํ๊ธด ํ์ฃ . ๊ฐ์ธ์ ์ผ๋ก ์ฝ๋ฉ์ ๋ํ์์ ์ง์ ์ ์ผ๋ก ๋ฐฐ์ด ๊ฑด 1ํ๋ ๋๊ฐ ๋ง์ง๋ง์ด์๋ ๊ฒ ๊ฐ์ต๋๋ค.
2ํ๋ ๋ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์์ ์ ๋ค์ ๋์ง์ด๋ณด๋ฉด Java ๋ผ๋ ๊ฐ์ฒด์งํฅ ์ธ์ด์ ์ฒ ํ์ ๋ํ ์ด์ผ๊ธฐ๋ฅผ ๋ ํ์ จ๋ ๊ฒ ๊ฐ์ต๋๋ค. ํญ์ ์ ๊ธฐ์ต์ ๋ค๋ฆ๊ฒ ๋ ์ฌ๋ ค๋ณด๋ฉด ๊ทธ๋ ์ ๊ต์๋์ด ๊ทธ๋ ๊ฒ ์ค๋ช ํ๋ ์ง ์ดํด๊ฐ ๊ฐ๊ณค ํ์ฃ ...์ ์์ค ๊ณ ์ฌ๋ง ๋น ๋์ด์๋ ๊ต์๋๊ป์ ๋ง์ํ์ จ์ฃ .
๐จโ๐ฆฒ : ์ธ์ ๊ฐ ์ด ์์ ์จ์ฒ๋ผ ๋๊ณ ์ถ์ ๋ ์ด ์ฌ๊ฒ๋๋ค ํํ...
์ปดํจํฐ๋ ์ฐ๋ฆฌ๊ฐ ๊ฒ์ ํ ๋๋ ์ฐ์ง๋ง ๋ณธ์ง์ ์ธ ๋ชฉ์ ์ '๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ ๋๊ตฌ' ๋ผ๊ณ ํ ์ ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ฐ ์ง๋ฌธ์ ๋์ง ์ ์์ ๊ฒ ๊ฐ์์.
"์ปดํจํฐ๋ ๋๋์ฒด ์ด๋ค ๋ฌธ์ ๋ฅผ ํ ์ ์์๊น?"
"๋ ์ด๋ค ๋ฌธ์ ๋ ์ปดํจํฐ๋ก๋ ์ ๋ ๋ชป ํธ๋ ๊ฑธ๊น?"
์ด๋ฐ ์ง๋ฌธ์ ๋ตํ๋ ค๋ ๋ถ์ผ๊ฐ '์คํ ๋งํ ์ด๋ก (Automata Theory)' ์ด๊ณ ์ด๋ฅผ ํฌํจํ ๋ ํฐ ํ์ด '๊ณ์ฐ ์ด๋ก (Theory of Computation)' ์ ๋๋ค.
์ฆ, ์ฐ๋ฆฌ๊ฐ ์ปดํจํฐ๋ก ๋ฌด์ธ๊ฐ๋ฅผ ๋ง๋ค๊ธฐ ์ ์, โ์ด๊ฒ ์ปดํจํฐ๋ก ํด๊ฒฐ ๊ฐ๋ฅํ ๋ฌธ์ ์ธ์ง๋ถํฐ ๋ฐ์ ธ๋ณด์โ ๋ผ๋ ์ง๋ฌธ์ ๋์ง๋ ์์ฃผ ๊ธฐ์ด์ ์ด๊ณ ๋ ์ค์ํ ๋ถ์ผ์ธ ๊ฑฐ์ฃ .
๐๏ธ ์คํ ๋งํ ์ด๋ก (Automata Theory) ์๊ฐ
์ข ๋ ๊ตฌ์ฒด์ ์ผ๋ก ๋ค์ด๊ฐ๋ณผ๊ฒ์. ์คํ ๋งํ ์ด๋ก ์ ๊ณ์ฐ ๋ฅ๋ ฅ์ด ์๋ ๊ธฐ๊ณ์ ๊ทธ ๊ธฐ๊ณ๋ฅผ ์ด์ฉํด์ ํ ์ ์๋ ๋ฌธ์ ๋ฅผ ์ฐ๊ตฌํ๋ ๋ถ์ผ์์. ๋๋ฌด ๊ธธ๊ฒ ์ด์ผ๊ธฐํ๋ฉด ์ฌ๋ฏธ์์ผ๋๊น ๊ฐ๋จํ ์ค๋ช ํ์๋ฉด, โ๊ธฐ๊ณ๊ฐ ์ด๋ค ๋ฌธ์ ๊น์ง ํ ์ ์์๊น?โ๋ฅผ ๋ฐ์ง๋ ํ๋ฌธ์ด์์.
์คํ ๋งํ๋ ์ด์ฐ ์๊ฐ ๋์ ์ฃผ์ด์ง ์
๋ ฅ์ ์์กดํด ์๋ํ๋ ์ํ์ ์ธ ๊ธฐ๊ณ๋ผ๊ณ ์ํค๋ฐฑ๊ณผ์ ์ค๋ช
๋์ด์์ด์. ์ฌ๊ธฐ์ ์ด์ฐ
์ด๋ผ๋ ๊ฐ๋
์ด ์ค์ํ๋ฐ, ์ด์ฐ
์ ์ฐ์์ ์ด์ง ์๊ณ ๋ถ๋ฆฌ๋์ด ์๋ค๋ ์๋ฏธ์์.
์ฐ๋ฆฌ ์ฃผ์ ๊ฐ ๋ฅ๋ค์ด๋ธ๋ ์ข ๋ ๊น๊ฒ ์ค๋ช ํ๊ณ ๋์ด๊ฐ์๋ฉด, ์๋ ๋ก๊ทธ์ ๋์งํธ์ ๊ด๊ณ๋ฅผ ์๊ฐ ํด ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ข ๋ ์์ ํฉ๋๋ค.
์๋ ๋ก๊ทธ๋ ์ฐ์์ ์ธ ๊ฐ์ ๊ฐ์ง์ฃ . ๋น์ฅ ์ฑ ์ ์์ ์๋ ์๋ ๋ก๊ทธ ์๊ณ์ ์ด์นจ์ ๋งค๋๋ฝ๊ฒ ์์ง์ด๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ค๊ฐ ๊ฐ์ ๋ฌดํํ ์กด์ฌํ ์ ์์ด์. ๊ทธ๋์ 3์ด์ 4์ด ์ฌ์ด ์ด๋๊ฐ ๋ผ๋ ์ ๋งคํ ์๊ฐ๋ ์กด์ฌํ ์ ์์ฃ .
ํ์ง๋ง ๋์งํธ์ ์ธ๊ณ๋ ๋ค๋ฆ ๋๋ค. 3์ด, 4์ด ๊ฐ๊ฐ์ ๋จ๊ณ์ ๊ฐ๋ง ์กด์ฌํฉ๋๋ค. ์ค๊ฐ์ ๊ฐ์ด ๋ฌดํํ ์กด์ฌํ๋ ค๋ฉด ํ ์ ์๊ฒ ์ง๋ง, 3.333333333์ด ๋ฑ ์ค์์ ๋ฒ์์์ ๋์ด์ง ์ ๋ฐ์ ์์ต๋๋ค.
์ปดํจํฐ์์ ๋ณด๋ ๋ชจ๋ ๊ฐ๋ค ํ๋ํ๋๋ ์ด์ฐ์ ์ธ ์ ๋ณด์ ๋๋ค. ํค๋ณด๋ ์ ๋ ฅ๋ถํฐ ์ค์ ๊ฐ ํ๋ ๊น์ง๋ ๋ง์ด์ฃ . ์ปดํจํฐ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ค๋ฃจ๋ ๋ฐฉ์์ด ๊ทธ๋ ์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ์ ์ค์ ๊ฐ ํ๋๋ฅผ ์ ์ฅํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๋ฉด ๊ฒฐ๊ตญ ์ด๋ ์ ๋ ์์ ์์ ๋์ด์ง ์ ๋ฐ์ ์์ด์. ์๋๋ฉด ์ปดํจํฐ์ ํ๋์จ์ด์ ์ฉ๋์ ํ๊ณ๊ฐ ์์ผ๋๊น์.
์คํ ๋งํ๋ ๋จ๊ณ๋ณ๋ก ํ๋์ ์ ๋ ฅ์ ๋ฐ์ ์ฒ๋ฆฌํฉ๋๋ค. ํ ์ ๋ ฅ์ ๋ฐ๊ณ ์ํ๋ฅผ ๋ฐ๊พธ๊ณ , ๋ค์ ์ ๋ ฅ์ ๋ฐ๋ ๋ฑ ๋์ด์ง ์๊ฐ ์์์ ์์ง์ด๋ ๊ธฐ๊ณ์ ๋๋ค. ๋ญ๊ฐ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๊ณ ์๋ ์ํํธ์จ์ด์ ๋๋์ด ๋น์ทํ์ฃ ?
๐งฎ ๊ณ์ฐ ์ด๋ก (Theory of Computation)
๊ณ์ฐ ์ด๋ก ์ ํฌ๊ฒ ์ธ ๊ฐ์ง ์ค๊ธฐ๋ก ๋๋ฉ๋๋ค.
๋ถ์ผ | ๋ค๋ฃจ๋ ์ง๋ฌธ | ์์ |
---|---|---|
์คํ ๋งํ ์ด๋ก | ์ด๋ค ๋ฌธ์ ๋ฅผ ํ ์ ์๋๊ฐ? | ์ ๊ท ํํ์, ์ํ ๊ธฐ๊ณ |
๊ณ์ฐ ๊ฐ๋ฅ์ฑ ์ด๋ก | ์ด๋ค ๋ฌธ์ ๋ ์ ๋๋ก ๋ชป ํธ๋๊ฐ? | ์ ์ง ๋ฌธ์ (Halting Problem) |
๋ณต์ก๋ ์ด๋ก | ์ผ๋ง๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ํ ์ ์๋๊ฐ? | NP ๋ฌธ์ , ์๊ณ ๋ฆฌ์ฆ ์ฑ๋ฅ ๋ถ์ |
๊ณ์ฐ ์ด๋ก ์ ๋จ์ํ '๋ฌธ์ ๋ฅผ ํผ๋ค' ์์ ๋ฉ์ถ์ง ์๊ณ ํ ์ ์๋์ง, ์ผ๋ง๋ ๋น ๋ฅด๊ฒ ํ ์ ์๋ ์ง, ์์ ๋ชป ํธ๋ ๊ฑด ์๋์ง ๊น์ง ์ดํด๋ด ๋๋ค.
๐จ๏ธ ํ๋ง ๋จธ์ (Turing Machine)
์ปด๊ณต ์ ๊ณต์๋ผ๋ฉด ํ ๋ฒ์ฏค์ ๋ค์์ ์ด๋ฆ์ด์ฃ . ์ปดํจํฐ์ ์๋ฒ์ง๋ผ๊ณ ๋ถ๋ฆฌ๋ ์จ๋ฐ ํ๋ง(Alan Turing)์ด 1930๋ ๋์ ๊ณ ์ํ ๊ฐ๋ ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ์ฐ๋ ์ปดํจํฐ์๋ ๋ค๋ฅด๊ฒ, ํ๋ง ๋จธ์ ์ ํ์ค์ ์กด์ฌํ๋ ๊ธฐ๊ณ๋ ์๋์์. ํ์ง๋ง ์ด๋ก ์ ์ผ๋ก๋ ๋ชจ๋ ์ปดํจํฐ๊ฐ ํ๋ง ๋จธ์ ์ ํ๋ด ๋ด๊ณ ์๋ค๊ณ ํ ์ ์์ต๋๋ค.
ํ๋ง ๋จธ์ ์ ๊ต์ฅํ ๋จ์ํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ด์. ํ์ง๋ง ์ด ๋จ์ํ ๊ตฌ์กฐ๋ง์ผ๋ก๋ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๋ ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋จ์ ํํํ ์ ์์ต๋๋ค.
ํ๋ง ๋จธ์ ์ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์ฑ์์๋ก ๋์ด ์์ด์:
- ๋ฌดํํ ๊ธด ํ ์ดํ: ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ ์ ์๋ ๊ณต๊ฐ์ด์์. ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ ์ญํ ์ ํฉ๋๋ค.
- ํค๋(Head): ํ ์ดํ ์๋ฅผ ์๋ค๊ฐ๋ค ํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฑฐ๋ ์๋๋ค.
- ์ํ(State): ํ์ฌ ํ๋ง ๋จธ์ ์ด ์ด๋ค โ๋ชจ๋โ์ ์๋์ง๋ฅผ ๋ํ๋ ๋๋ค. ์คํ ๋งํ์์ ๋ฐฐ์ด ์ํ์ ๊ฐ์ ๊ฐ๋ ์ ๋๋ค.
- ์ ์ด ํจ์: ํ์ฌ ์ํ์ ํ ์ดํ์ ๋ฌธ์๋ฅผ ๋ณด๊ณ , ๋ฌด์์ ์ธ์ง, ์ด๋๋ก ์์ง์ผ์ง, ์ด๋ค ์ํ๋ก ์ ์ดํ ์ง๋ฅผ ๊ฒฐ์ ํ๋ ๊ท์น์ ๋๋ค.
์๋ฅผ ๋ค์ด ์์ฃผ ๋จ์ํ ํ๋ง ๋จธ์ ํ๋๋ฅผ ์๊ฐํด๋ณผ ์ ์์ต๋๋ค: โ0โ์ด ์ฐ์์ผ๋ก ์ฃผ์ด์ง ํ ์ดํ์์, ์ฒ์์ผ๋ก ๋์ค๋ โ1โ์ ๋ง๋๋ฉด ์์ ์ ๋ฉ์ถ๋ ๊ธฐ๊ณ. ์ด๊ฑด ์์ฃผ ๊ฐ๋จํ์ง๋ง, ๊ทธ ๋์์ ์ํ์ ์ ๋ ฅ, ์ถ๋ ฅ, ์ด๋์ผ๋ก ์ชผ๊ฐ๋ณด๋ฉด ํ๋ง ๋จธ์ ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅด๊ณ ์์์ ์ ์ ์์ด์.
์ด๋ฐ ๋ฐฉ์์ ์ฌ์ค ์ฐ๋ฆฌ๊ฐ ์์ฑํ๋ ๋ฐ๋ณต๋ฌธ(while loop)์ด๋ ์กฐ๊ฑด๋ฌธ(if-else)๊ณผ ๊ต์ฅํ ๋ฎ์ ์์ด์. ์ปดํ์ผ๋ฌ ์ ์ฅ์์ ๋ณด๋ฉด, ํ๋ง ๋จธ์ ์ ์์ฃผ ๋จ์ํ ๊ตฌ์กฐ์ง๋ง ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ ผ๋ฆฌ ํ๋ฆ์ ๊ฑฐ์ ๋ชจ๋ ํํํ ์ ์๋ค๋ ์ ์ด์ฃ .
โ ๊ทธ๋ผ ์ด๊ฑธ ์ ๋ง๋ค์์๊น?
ํ๋ง์ โ๋ฌด์จ ์ผ์ด๋ ์๋์ผ๋ก ๊ณ์ฐํ๋ ๊ธฐ๊ณโ๋ฅผ ์์ํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๊ธฐ๊ณ๊ฐ ํ ์ ์๋ ๋ฌธ์ ์ ํ๊ณ๊ฐ ๊ณ์ฐ ๊ฐ๋ฅํ ๋ฌธ์ (computable problem) ์ ์ ์๊ฐ ๋ ์ ์๋ค๊ณ ์๊ฐํ์ฃ .
๊ทธ๋์ ์ด๋ฐ ๊ธฐ์ค์ด ์๊น๋๋ค:
โํ๋ง ๋จธ์ ์ผ๋ก ํ ์ ์๋ค๋ฉด, ์ด ๋ฌธ์ ๋ ๊ณ์ฐ ๊ฐ๋ฅํ๋ค.โ ๋ฐ๋๋ก, โํ๋ง ๋จธ์ ์ผ๋ก๋ ๋ชป ํธ๋ ๋ฌธ์ ๋ ๊ณ์ฐ ๋ถ๊ฐ๋ฅํ ๋ฌธ์ ๋ค.โ
์ด ๊ธฐ์ค์ ์ง๊ธ๋ ๊ณ์ฐ ์ด๋ก ์ ํต์ฌ ์์น์ด์์. ์ ์ง ๋ฌธ์ (Halting Problem) ๊ฐ์ ๊ณ ์ ์ ์ธ ์ด์๋, ๊ฒฐ๊ตญ ํ๋ง ๋จธ์ ์ผ๋ก ํ ์ ์๋๊ฐ/์๋๊ฐ๋ฅผ ๋ฐ์ง๋ฉฐ ์ ์๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด โ์ด ํ๋ก๊ทธ๋จ์ด ๋ฌดํ ๋ฃจํ์ ๋น ์ง์ง ์๋์งโ๋ฅผ ์๋์ผ๋ก ํ๋จํ๋ ๋ฌธ์ ๋ ํ๋ง ๋จธ์ ์ผ๋ก๋ ํด๊ฒฐํ ์ ์๋ค๋ ๊ฒ์ด ์ ์ง ๋ฌธ์ (Halting Problem)์ฃ .
โ๏ธ ์ ํ์ํ๊ธฐ๊ณ vs ํ๋ง ๋จธ์
์ ํ ์ํ ๊ธฐ๊ณ๊ฐ โ๊ธฐ์ต ์์ด ํ๋จํ๋ ๊ธฐ๊ณโ๋ผ๋ฉด, ํ๋ง ๋จธ์ ์ โ๊ธฐ์ต์ ํตํด ๋ณต์กํ ํ๋ฆ์ ์ดํดํ๋ ๊ธฐ๊ณโ์ ๋๋ค. ๋ง์น ๊ณ์ฐ๊ธฐ์ ์์ ์ ๋์ ์ฐจ์ด๋๊น์?
ํต์ฌ์ ๊ธฐ์ต ๋ฅ๋ ฅ์ด์์. ํ๋ฒ ์ ๋ฆฌ ํด ๋ณด์์ต๋๋ค.
ํญ๋ชฉ | ์ ํ ์ํ ๊ธฐ๊ณ(FSM) | ํ๋ง ๋จธ์ |
---|---|---|
๊ธฐ์ต ๊ณต๊ฐ | ์์ ๋๋ ๋งค์ฐ ์ ํ์ (ํ์ฌ ์ํ๋ง ๊ธฐ์ต) | ๋ฌดํ ํ ์ดํ ์ฌ์ฉ ๊ฐ๋ฅ |
๊ณ์ฐ ๋ฅ๋ ฅ | ์ ๊ท ์ธ์ด๋ง ์ฒ๋ฆฌ ๊ฐ๋ฅ | ์ด๋ก ์ ์ผ๋ก ๋ชจ๋ ๊ณ์ฐ ๊ฐ๋ฅ |
ํ์ค ์ ์ฉ | ์ ๊ท์, ์ดํ ๋ถ์๊ธฐ ๋ฑ | ์ปดํจํฐ ์์ฒด์ ์ํ์ ๋ชจ๋ธ |
๋ณต์ก๋ | ๋จ์ | ๋ณต์กํ์ง๋ง ๊ฐ๋ ฅํจ |
๊ฒฐ๊ตญ ํ๋ง ๋จธ์ ์ ์ฐ๋ฆฌ๊ฐ ์ค๋๋ ์ฌ์ฉํ๋ ์ปดํจํฐ์ ์ํ์ ๋ชจ๋ธ์ด์, "์ปดํจํฐ๊ฐ ์ด๋๊น์ง ํ ์ ์๋์ง" ๋ฅผ ๊ท์ ํด์ฃผ๋ ๊ฐ์ฅ ์ค์ํ ๊ฐ๋ ์ด์์.
โ๏ธ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ด์ผ๊ธฐ : ์ปดํ์ผ๋ฌ
๐งฌ ์ปดํ์ผ๋ฌ ์ด๋ก (Compiler Theory)
์ปดํ์ผ๋ฌ๋ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ๊ณ ์์ค ์ธ์ด(Java, Kotlin, C ๋ฑ)๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ์ ์์ค ์ธ์ด(๊ธฐ๊ณ์ด ๋ฑ)๋ก ๋ฒ์ญํ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ด๋ถ์ ์ฐ๋ฆฌ๊ฐ ์์ ์ด์ผ๊ธฐํ ์คํ ๋งํ ์ด๋ก ์ด ์์ฃผ ๊น์ด ๋ น์ ์์ฃ .
์ด๋ฒ ์ธ์ ์์๋ ์ปดํ์ผ๋ฌ์ ๋์ ๋จ๊ณ๋ฅผ ์์ ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ ๋จ๊ณ๋ณ๋ก ์ํ์ ํ๋ฆ์ ์์๋ณด๊ธฐ ์ํด ์ํ ๋ค์ด์ด๊ทธ๋จ (State Diagram) ๋ํ ๊ทธ๋ ค๋ณผ๊ฒ์.
์ปดํ์ผ๋ฌ๋ ์ผ๋ฐ์ ์ผ๋ก ์๋์ ๊ฐ์ ๋จ๊ณ๋ก ๋์ํฉ๋๋ค.
๋จผ์ ์ดํ ๋ถ์ (Lexical Analysis) ๋จ๊ณ์
๋๋ค. ์์ค ์ฝ๋๋ฅผ ํ ํฐ(Token)์ด๋ผ๋ ์ต์ ์๋ฏธ ๋จ์๋ก ๋๋๋๋ค. ์ฌ๊ธฐ์ ์ ํ ์ํ ๊ธฐ๊ณ(FSM) ๊ฐ ํ์ฝํฉ๋๋ค. ์๋ฅผ ํ๋ ๋ค์ด๋ณผ๊ฒ์. int
, ์ ์ ์๋ฃํ ํค์๋๋ฅผ ์ธ์ํ๋ ์ํ ๋ค์ด์ด๊ทธ๋จ์ ํ๋ฒ ๊ทธ๋ ค๋ณผ๊น์?

์ ๋ ฅ ์คํธ๋ฆผ์์ i โ n โ t ์์ผ๋ก ์ฝํ๋ฉด int๋ผ๋ ํค์๋ ํ ํฐ์ผ๋ก ์ธ์ํฉ๋๋ค. ๊ทธ ์ธ ์ ๋ ฅ์ด ์ค๋ฉด ๋ค๋ฅธ ์ํ๋ก ์ ์ดํ๊ฑฐ๋ ๊ฑฐ๋ถ ์ํ๋ก ์ด๋ํ ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์์๋ก ์ซ์๋ฅผ ์ธ์ํ๋ ์์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค. 12345 ์ฒ๋ผ ์ฌ๋ฌ ์๋ฆฌ ์ ์๋ฅผ ์ธ์ํ๋ ์ํ ๋ค์ด์ด๊ทธ๋จ์ ๊ทธ๋ ค ๋ณด๊ฒ ์ต๋๋ค.

ํ๋ ์ด์์ ์ซ์๋ฅผ ์ฝ์ผ๋ฉด DIGIT ์ํ์ ๋จธ๋ฌด๋ฅด๋ฉฐ ์ซ์๋ฅผ ๊ณ์ ๋์ ํฉ๋๋ค. ์ดํ ๊ณต๋ฐฑ์ด๋ ๋ค๋ฅธ ๊ธฐํธ๊ฐ ์ค๋ฉด ์ํ ์ข ๋ฃ๋๊ณ ํ ํฐ์ด ๋ฐํ๋์ฃ .
๋ค์์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ (Syntax Analysis) ๋จ๊ณ์ ๋๋ค. ๋ฌธ๋ฒ ๊ตฌ์กฐ๋ฅผ ๋ถ์ํ์ฌ ํ์ฑ ํธ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. ๋ฌธ๋งฅ ์์ ๋ฌธ๋ฒ(Context-Free Grammar) ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์คํ ๊ธฐ๋ฐ ์คํ ๋งํ(PDA) ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์คํ์ด๋ผ๋ ์ด๋ฆ์ ๋ง๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์์๋์ฃ .
์คํ์ ๋ํด ๊ฐ๋จํ ์ค๋ช ํด ์ฃผ์๋ฉด ๋ฐ์ดํฐ๋ฅผ ์์๋๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ (ํํ ๋งํ๋ ์๋ฃ๊ตฌ์กฐ) ์ ๋๋ค.
๋จผ์ ๋ค์ด์จ ๋ฐ์ดํฐ๊ฐ ๋ง์ง๋ง์ ๋๊ฐ๋ First In Last Out (FILO) ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง์ฃ . ์ฐ๋ฆฌ๊ฐ ์ด๋ถ์ ๊ฐ์ด์ ์์๋๋ฉด ๋งจ ๋ฐ์ ์๋ ๊ฑธ ๋นผ์ง ์๋ฏ์ด ์คํ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์๋ ๋ช ๋ น์ ์ผ๋ฐ์ ์ผ๋ก
push
๋นผ๋ ๋ช ๋ น์pop
์ด๋ผ๊ณ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด๋ณผ๊น์? ์ค์ฒฉ ๊ดํธ ((()))
๋ฅผ ์ธ์ํ๋ ์ํ ๋ค์ด์ด๊ทธ๋จ์ ๊ทธ๋ ค๋ณผ๊ฒ์.
stateDiagram-v2
[*] --> S0 : ์
๋ ฅ ์์
S0 --> S0 : ( / push
S0 --> S0 : ) / pop
S0 --> ACCEPT : ์คํ์ด ๋น์์ ๋ ์
๋ ฅ ์ข
๋ฃ
์ฌ๋ ๊ดํธ (๋ฅผ ์ฝ์ผ๋ฉด ์คํ์ push ํฉ๋๋ค. ๋ซ๋ ๊ดํธ )๋ฅผ ์ฝ์ผ๋ฉด ์คํ์์ pop ํ์ฃ .
์คํ์ด ์ ํํ ๋น์ด์ผ ACCEPT ์ํ๋ก ์ง์ ํ๊ฒ ๋ฉ๋๋ค. ์ต์ข ์ ์ผ๋ก ์ค์ฒฉ ๊ดํธ๋ฅผ ์ป๊ฒ ๋์ฃ .
์๋ง ์ฝ๋ฉ ๊ณต๋ถํ์๋ ๋ถ๋ค์ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ํ ๋ ์ด๋ฐ ๋ฌธ์ ๋ง์ด ๊ฒช์ด๋ณด์ จ์๊ฒ๋๋ค. ์คํ์ ํ์ฉํ ์ ์๋ ์ง ๋ฌป๋ ๋ฌธ์ ์ฃ .
๋ง์ง๋ง์ผ๋ก ์๋ฏธ ๋ถ์, ์ค๊ฐ ์ฝ๋ ์์ฑ, ์ต์ ํ ๋จ๊ณ์ ๋๋ค. ์ ์ ์ถ์ํ๋ ํํ์ ๋ ํจ์จ์ ์ธ ์ฝ๋๋ก ๋ฐ๊พธ๊ณ ์ต์ข ๋ชฉ์ ์ฝ๋๋ก ๋ณํํ์ฃ .
์๋ฅผ ๋ค์ด int x = 2 + 3;
๋ผ๋ ์ฝ๋๋ฅผ ์ปดํ์ผ๋ฌ๊ฐ ๋ถ์ํ๋ ๊ณผ์ ์ ๊ตฌ์ฒด์ ์ผ๋ก ์ค๋ช
ํด ๋ณผ๊ฒ์.
๋จผ์ ์ดํ ๋ถ์ ๋จ๊ณ์ ๋๋ค. ์ ๋ ฅ์ด int, x, =, 2, +, 3, ; ๊ฐ๊ฐ์ผ๋ก ๊ตฌ๋ถ๋ ์ ์์ฃ . ๊ทธ ๊ฒฐ๊ณผ ์๋์ ๊ฐ์ด ํ ํฐ์ด ์์ฑ๋ฉ๋๋ค.
[Keyword:int], [Identifier:x], [Operator:=], [Literal:2], [Operator:+], [Literal:3]
๋ค์์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ ๋จ๊ณ์ ๋๋ค. AST ๋ Abstract Syntax Tree ํน์ ๋จ์ํ Syntax Tree ๋ผ๊ณ ๋ถ๋ ค์. ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก ์์ฑ๋ ์์ค ์ฝ๋์ ์ถ์ ๊ตฌ๋ฌธ ๊ตฌ์กฐ์ ํธ๋ฆฌ ์ ๋๋ค.
์ฌ๊ธฐ์ ํธ๋ฆฌ๊ฐ ๋ฌด์์ธ๊ฐ์...๋ผ๊ณ ํ์๋ ๋ถ๋ค์ ์ํด ์ค๋ช ๋๋ฆฌ์๋ฉด ์ผ์ข ์ ๊ทธ๋ํ์ ๋๋ค. ๊ฐ๊ฐ์ ์์๋ค์ด ์ฐ๊ฒฐ ๋์ด์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์๋ฏธํด์.
๋จ, ๊ฐ๊ฐ ๊ตฌ์ฑ์์ (๋ ธ๋ ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.) ๊ฐ์ ์ฐ๊ฒฐ ๊ฒฝ๋ก๋ฅผ ํ๊ณ ๊ฐ์ ๋ ๋ณธ์ธ์๊ฒ ๋์์ค๋ ์ํ์ด ์์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฅ ์ผ์๋ก ์ฐ๊ฒฐ ๋ ๊ตฌ์กฐ๋ผ๋ฉด ๋ค์ ๋์์ฌ ์ ์๊ฒ ์ฃ ?
ํค์๋๋ค์ ๋ํ AST ๋ ์๋์ ๊ฐ์ด ์์ฑ๋ฉ๋๋ค.
Assignment
โโโ Identifier(x)
โโโ Expression
โโโ Literal(2)
โโโ +
โโโ Literal(3)
๋ค์์ผ๋ก ์๋ฏธ๋ถ์ ๋จ๊ณ์ ๋๋ค. ์ฝ๋๋ฅผ ๊ฐ๊ฐ ํ ํฐ์ผ๋ก ๋๋ ํ ๋ ธ๋๋ค์ด ์ฐ๊ฒฐ ๋ ํธ๋ฆฌ๋ก ๋ง๋ค์์ผ๋ ์๋ฏธ๋ฅผ ๋ถ์ ํด ๋ณด์์ผ ๊ฒ ์ฃ ?
- x ๊ฐ int ๋ก ์ ์ธ ๋์์ต๋๋ค.
- 2 + 3 ์ ๊ฒฐ๊ณผ๋ int (์ ์) ์ ๋๋ค. ํ์ ์ด ์ผ์นํ๋ค์.
- ์ฌ๋ณผ ํ ์ด๋ธ์ x ๋ฅผ ๋ฑ๋กํฉ๋๋ค. ์ ์ธ ๋ ๋ณ์๋ค์ ์ ์ฅํ๋ ๊ณณ์ด์์.
๋ค์์ผ๋ก ์ค๊ฐ ์ฝ๋ ์์ฑ ๋จ๊ณ์ ๋๋ค. ์ปดํ์ผ๋ฌ๋ ๋ค์ํ ํ๋์จ์ด๋ฅผ ์ง์ํด์ผ ํฉ๋๋ค. ํํ ๋งํ๋ ์ปดํจํฐ CPU ์ฌ์ ์ค์ x86, ARM ๊ฐ์ ์ฉ์ด๊ฐ ๋์ค์์์? ์ด๋ฐ CPU ๋ค ๊ฐ๊ฐ์ ๊ฐ์์ ๊ธฐ๊ณ์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ง์น ํ๊ตญ์ธ, ์ค๊ตญ์ธ์ด ์ธ์ด๊ฐ ๋ค๋ฅธ ๊ฒ ์ฒ๋ผ ๋ง์ด์ฃ . ์ปดํจํฐ์๊ฒ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ๋ถ์ํด์ ๊ฐ์ CPU ๊ฐ ์ดํดํ ์ ์๋ ๊ธฐ๊ณ์ด๋ก ๋ฐ๊พธ๊ธฐ ์ ์๋ ์ค๊ฐ ๋จ๊ณ์ ํํ์ผ๋ก ๋ณํ ํด์ผ ํฉ๋๋ค.
ํํ ์ฐ์ด๋ ๊ฒ 3-address-code ์ธ๋ฐ, 2๊ฐ์ ์ ๋ ฅ์ฉ, 1๊ฐ์ ์ถ๋ ฅ์ฉ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ง์ ํ๋ค๊ณ ์ด๋ ๊ฒ ์ด๋ฆ์ด ๋ถ์์ด์.
t1 = 2 + 3
x = t1
์ด๋ ๊ฒ ์ชผ๊ฐ๋๋ฉด 2 + 3 ์ด๋ผ๋ ํํ์์ด ๋ณ๋์ ๋ณ์ (t1) ์ ๋ด๊น๋๋ค. ์ดํ ๋ค๋ฅธ ๊ณณ์ ์ฌ์ฌ์ฉ๋๊ฑฐ๋ ๊ณ์ฐ์ ๋ฏธ๋ฆฌ ํด๋ฒ๋ฆฌ๋ ์ต์ ํ (Constant Folding) ์ ํ ์ ์์ฃ .
๋ค์์ผ๋ก ์ต์ ํ ๋จ๊ณ์ ๋๋ค. ์ฝ๋๋ฅผ ๋ ๋น ๋ฅด๊ณ , ์งง๊ณ , ํจ์จ์ ์ผ๋ก ๋ง๋๋ ๋จ๊ณ์ ๋๋ค. ์๊น ์ธ๊ธํ Constant Folding ์ ํด๋ณผ๊น์?
t1 = 2 + 3 โ t1 = 5
x = t1 โ x = 5
์ด ์ฐ์ฐ ์์ฒด๋ฅผ ์ปดํ์ผ ๊ณผ์ ์์ ํด๋ฒ๋ ค์ ํ๋ก๊ทธ๋จ์ด ์คํ๋๋ ๋ฐํ์์ ํ์ง ์๋๋ก ๋ฏธ๋ฆฌ ์์ํ ํด ๋ก๋๋ค.
๋ง์ง๋ง์ผ๋ก ๋ชฉ์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. ์ฐ๋ฆฌ์ ํ๋ซํผ (x86, ARM) ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ด ๋ชฉ์ ์ฝ๋๋ ์ด์ ๋ธ๋ฆฌ๋ผ๊ณ ํ๋๋ฐ CPU ์ ๊ธฐ๊ณ์ด๋ฅผ ์ฌ๋์ด ์ดํดํ ์ ์๋ ์ ๋๋ก ๋ฒ์ญ ํด ๋๊ฑฐ๋ผ๊ณ ๋ง ์ดํดํด๋์๋ฉด ์ข์ต๋๋ค.
MOV eax, 5
MOV [x], eax
๊ฐ 5๋ฅผ eax ๋ ์ง์คํฐ์ ๋ฃ๊ณ eax ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ฃผ์ x์ ์ ์ฅํ๋ค๋ ๋ป์ ๋๋ค.
์ ๊ฐ ๊ธฐ๊ณ์ด ์ฝ๋ฉ์ ํ ์ค ์๋ ๊ฑด ์๋๋๋ค....์ด์ฌํ ์ฐพ์๊ฐ๋ฉฐ ์์๋ฅผ ๋ง๋ค์์ฃ .
์ด๋ ๊ฒ ๋ณด๋ฉด ์คํ ๋งํ ์ด๋ก ์ ๋จ์ํ ํ๋ถ ์์ ์ ๊ณจ์น ์ํ ์ด๋ก ์ด ์๋๋ผ, ํ๋ ํ๋ก๊ทธ๋๋ฐ์ ๊ฐ์ฅ ํต์ฌ์ ์ธ ๊ธฐ์ ์ ์์ฉ๋๊ณ ์๋ ๊ตฌ์กฐ๋ผ๋ ๊ฑธ ์ ์ ์์ต๋๋ค.
๐ฑ ์ค๋ฌด ์ด์ผ๊ธฐ : Spring State Machine
์ง๊ธ๊น์ง ์ ํ ์ํ ๊ธฐ๊ณ(FSM)์ ๊ฐ๋ ๊ณผ ๊ทธ ์ด๋ก ์ ๋ฐฐ๊ฒฝ, ๊ทธ๋ฆฌ๊ณ ์ปดํ์ผ๋ฌ์ฒ๋ผ FSM์ด ํ์ฝํ๋ ๋ํ์ ์ธ ์์ ๊น์ง ์ดํด๋ดค์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ๋ฌป๋ ๋ถ๋ค๋ ๊ณ์ค ์ ์์ด์.
"๊ทผ๋ฐ... ์ด๊ฑธ ์ฐ๋ฆฌ๊ฐ ์ค๋ฌด์์ ์ ์จ์ผ ํ์ฃ ?"
์ข์ ์ง๋ฌธ์ ๋๋ค. ์๋ํ๋ฉด ๋๋ถ๋ถ์ ์์คํ ์ ์๊ฐ๋ณด๋ค ํจ์ฌ '์ํ' ์ค์ฌ์ผ๋ก ํ๋ฌ๊ฐ๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ์ฌ์ฉ์๊ฐ ๊ฒฐ์ ๋ฅผ ๋๋ ์ด์.
- ๊ฒฐ์ ์ค์ ์ทจ์ํ ์๋ ์๊ณ , ์คํจํ ์๋ ์๊ณ , ์ฑ๊ณตํ ์๋ ์์ฃ .
- ์ฑ๊ณตํ๋ฉด ๋ฐฐ์ก์ผ๋ก ๋์ด๊ฐ๊ณ , ๋ฐฐ์ก ์ค์๋ ์ํ๋ '์ถ๊ณ ์๋ฃ', '๋ฐฐ์ก ์ค', '๋ฐฐ์ก ์๋ฃ' ๋ฑ์ผ๋ก ๊ณ์ ๋ฐ๋์ด์.
์ฆ, ์์คํ ๋ด๋ถ์์ ํ์ฌ ์ํ(state) ์ ์ด๋ฒคํธ(event) ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ๋์์ ๊ฒฐ์ ํด์ผ ํ๋ ํ๋ฆ์ด ๋ฌด์ํ ๋ง์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฑธ ๊ฐ๋ฐ์ ์ ์ฅ์์ ์ฝ๋๋ก ํ์ด๋ณด๋ฉด ์ด๋ป๊ฒ ๋๋๊ณ ์?
if (status == "PENDING") { ... } else if (status == "PAID") { ... } else if (...)
๐จ : ์ ์ ๊ดด๋ฌผ์ด ๋์ด๊ฐ๋๋คโฆ
๐ : ์ฌ๊ธฐ ์คํ๊ฒํฐ ์ํค์ ๋ถ?
๋ณต์กํ๊ฒ ๊ผฌ์ธ ์ฝ๋๋ฅผ ํํ ์คํ๊ฒํฐ ์ฝ๋๋ผ๊ณ ํฉ๋๋ค. ์ ์ง๋ณด์๋ฅผ ํ๊ธฐ ์ด๋ ค์์ง์ฃ .
์ด์ ์ฌ๊ธฐ์ Spring State Machine์ด ๋ฑ์ฅํฉ๋๋ค.
โ Spring State Machine์ด๋?
Spring State Machine์ ๋ณต์กํ ์ํ ์ ์ด ๋ก์ง์ ์ ์ธ์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ์
๋๋ค.
์ํ(state), ์ด๋ฒคํธ(event), ์ ์ด(transition)๋ฅผ ์ฝ๋๋ก ์ ์ํ๊ณ , ์ํ๊ฐ ์ ์ด๋ ๋ ์ด๋ค ์ก์
์ ์คํํ ์ง ์ง์ ํ ์ ์์ฃ .
์์ ์คํ ๋งํ ์ด๋ก ์์ ๋ณธ ๊ตฌ์ฑ์์์ ๋น๊ตํด๋ณด๋ฉด ๊ฑฐ์ ๋๊ฐ์ต๋๋ค.
์คํ ๋งํ ๊ตฌ์ฑ ์์ | Spring State Machine ๋์ ๊ฐ๋ |
---|---|
์ํ (State) | ์ํ ์ด๊ฑฐํ (enum) ๋๋ ๋ฌธ์์ด |
์ ๋ ฅ/์ด๋ฒคํธ (Event) | ์ ์ด ํธ๋ฆฌ๊ฑฐ์ฉ ์ด๋ฒคํธ |
์ ์ด (Transition) | source , target , event |
์ ์ด ์กฐ๊ฑด/์ก์ | guard , action ๋ฉ์๋ |
์ฆ, ํ๋ถ ์์ ์ด๋ ต๊ฒ ๋ฐฐ์ด ์คํ ๋งํ ์ด๋ก ์ด,
์ค์ ์๋น์ค์ ๋ณต์กํ ์ํ ํ๋ฆ์ ๋ช
ํํ๊ณ ํ
์คํธ ๊ฐ๋ฅํ ์ฝ๋๋ก ๋ง๋ค๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋ฌด๊ธฐ๋ก ์ฌ๋ฑ์ฅํ๋ ๊ฒ๋๋ค.
๐ก ์ธ์ ์ฐ๋ฉด ์ข์๊น?
Spring State Machine์ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ํนํ ์ ์ฉํฉ๋๋ค.
- ์ํ๊ฐ 3~4๊ฐ ์ด์์ด๊ณ , ๊ฐ ์ํ๋ง๋ค ์ด๋ฒคํธ ์กฐ๊ฑด์ด๋ ํ์ฒ๋ฆฌ ๋ก์ง์ด ์กด์ฌํ ๋
- ์ํ ์ ์ด๊ฐ ๋ช ํํ ํ๋ก์ธ์ค (๊ฒฐ์ , ์ฃผ๋ฌธ, ๋ฐฐ์ก, ์น์ธ, ์ธ์ฆ ๋ฑ)๋ฅผ ๊ตฌํํ ๋
- ํ๋ฆ ํ
์คํธ๊ฐ ์ด๋ ค์ด
if-else
์ง์ฅ์์ ๋ฒ์ด๋๊ณ ์ถ์ ๋ - ์ํ์ ๋ฐ๋ผ ๋น์ฆ๋์ค ๋ก์ง์ด ๋ถ๊ธฐ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ฃผ ๋ณ๊ฒฝ๋ ๋
๐งฉ Spring State Machine ์ ๊ตฌ์ฑ์์
์ข ๋ ๊ตฌ์ฒด์ ์ผ๋ก Spring State Machine ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์คํ ๋งํ์ ๊ตฌ์ฑ์์์ ๋์๋๋ ํค์๋๋ค์ด ์๋ ๊ฑด ์ดํดํ์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ด ๊ธฐ์ ์ ์จ๋จน๊ธฐ ์ํด์ ๊ฐ ๊ตฌ์ฑ์์๋ค์ ๋ํด ์ ํํ ์ดํดํ๊ณ ๋์ด๊ฐ์ผ ํฉ๋๋ค.
๐ ์ํ (State)
Spring State Machine ์์ ์ํ (State) ๋ ์์คํ
์ด ์ผ์ ์์ ์ ์ฒํด ์๋ ๋
ผ๋ฆฌ์ ๊ตฌ๊ฐ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค. ์ฃผ๋ก enum
ํด๋์ค๋ก ์ ์ธํ์ฃ .
์ฌ๊ธฐ์ enum ์ด๋?
๊ฐ์ ์งํฉ์ ์ด๋ฃจ๋ ์์๋ฅผ ๋ปํ๋ ๋ฐ์ดํฐ ์ ๋๋ค. ์ด๊ฑฐํ์ด๋ผ๊ณ ๋ ๋ถ๋ฅด์ฃ .
enum ์ ๊ตฌ์ฑํ๋ ๋ฉค๋ฒ๋ค ๊ฐ๊ฐ์ ๊ฐ์์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค.
์์๋ค์ ๋ชจ์ ๋ ๊ฒ์ด๋ผ ์ดํดํด๋ ์ข์์.ํด๋์ค๋ ๋ ๋ฌด์์ธ๊ฐ? ๋ผ๊ณ ์ง๋ฌธํ์ค ๋ถ๋ ๊ณ์ค ๊ฒ ๊ฐ์ต๋๋ค.
์ง๊ธ์ ์ฝ๋๋ณด๋จ ๊ฐ๋ ์ ๋ํ ์ด์ผ๊ธฐ๋ฅผ ํ๊ณ ์ถ์ผ๋ ๊ฐ๋จํ๋ง ์ค๋ช ํ์๋ฉด, ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๋ ์ฝ๋ ๋จ์๋ผ๊ณ ์๊ฐ ํด ์ฃผ์ธ์.์ด ํด๋์ค ๋ผ๋ ์ค๊ณ๋๋ฅผ ํตํด ์์ฑ ๋ ๊ฐ์ฒด๋ค์ด ์ํธ์์ฉํ๋ฉด์ ์ํํธ์จ์ด๋ฅผ ์ด๋ค์. ์ํํธ์จ์ด ๊ฐ๋ฐ ๋ฐฉ๋ฒ๋ก ์ค '๊ฐ์ฒด์งํฅ' ์ ์ฌ์ฉํ๋ค๋ฉด ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋ก์ง๋ค์ ๊ตฌํํ ์ ์์ด์.
๋ฌผ๋ก ์ ์ผํ ๋ฐฉ๋ฒ์ ์๋๋๋ค. ์ฐ๋ฆฌ์๊ฒ '์ ์ฐจ์งํฅ' ๋ ์์ผ๋๊น์.
์ด ์ํ ๋ฐ์ดํฐ ์ค ๋ก์ง์ ์คํํ ๋์ ์ํ๋ฅผ entry
, ๋ก์ง์ด ๋๋ ๋์ ์ํ๋ฅผ exit
์ด๋ผ๊ณ ํฉ๋๋ค.
enum class PaymentState {
WAITING, PROCESSING, APPROVED, FAILED, CANCELED
}
์๋ฅผ ๋ค์ด ์ฃผ๋ฌธ ์์คํ ์์๋ ๊ฒฐ์ ๋๊ธฐ -> ๊ฒฐ์ ์ค -> ๊ฒฐ์ ์๋ฃ ๋ฑ์ ์ํ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
๐ฆ์ด๋ฒคํธ (Event)
์ํ์ ์ ์ด๋ฅผ ์ ๋ฐํ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์๋ฏธํฉ๋๋ค.
์ด ๋ํ enum
์ผ๋ก ์ ์ธ ํ ์ ์์ต๋๋ค. ์ด ์ด๋ฒคํธ๋ค์ ์ธ๋ถ ์
๋ ฅ ๋๋ ๋ด๋ถ ํธ์ถ๋ก ๋ฐ์ํ ์ ์์ฃ .
enum class PaymentEvent {
REQUEST, APPROVE, DECLINE, CANCEL
}
๋ง์ฝ ์ฌ์ฉ์๊ฐ ๊ฒฐ์ ์์ฒญ ๋ฒํผ์ ํด๋ฆญํ๋ฉด REQUEST
์ด๋ฒคํธ๊ฐ ๋ฐ์ ํ๊ฒ ๋๊ฒ ์ฃ ?
๐ ์ ์ด (Transition)
ํ ์ํ์์ ๋ค๋ฅธ ์ํ๋ก ์ด๋ํ๋ ๊ฒฝ๋ก๋ฅผ ์ ์ํฉ๋๋ค.
source
, target
, event
๊ฐ๊ฐ์ ์กฐํฉํด์ ๋ง๋ค์ฃ . ์๋ฅผ ๋ค์ด๋ณผ๊น์?
transitions
.withExternal()
.source(PaymentState.WAITING)
.target(PaymentState.PROCESSING)
.event(PaymentEvent.REQUEST)
WAITING
์ํ์์ REQUEST
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด PROCESSING
์ผ๋ก ์ ์ดํ๋ค๋ ์๋ฏธ๋ฅผ ๊ฐ์ง ์ฝ๋์
๋๋ค. ์ด๋ ๊ฒ ๊ฐ ์ํ๋ค์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ค ์ ์์ต๋๋ค.
๐ก๏ธ ๊ฐ๋ (Guard)
๊ฐ๋ (Guard) ๋ ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ ๋ ๋๋ง ์ ์ด๋ฅผ ํ์ฉํ๋ boolean (true / false) ์กฐ๊ฑด์ ๋๋ค. ์ด ๊ฒฝ์ฐ ์กฐ๊ฑด์ด true ์ผ ๋๋ง ์ ์ด๋๋๋ก ๋ฉ์๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๐โโ๏ธ ๋ฉ์๋๊ฐ ๋ญ์์?
๋ฉ์๋(method)๋ ์ปดํจํฐ ํ๋ก๊ทธ๋๋ฐ์์ ํน์ ์์ ์ ์ํํ๋ ๋ช ๋ น๋ฌธ ์งํฉ์ ์๋ฏธํฉ๋๋ค.
ํํ ํจ์ (function) ์ด๋ผ๊ณ ๋ ํ๋๋ฐ ์ข ๋ ๋ถ๋ถ์งํฉ ์ ์ธ ์๋ฏธ์์.
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์์๋ ํด๋์ค๊ฐ ๊ฐ์ง ์ ์๋ ๊ธฐ๋ฅ์ ๋จ์๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ฒ์ฉ์ ์ผ๋ก ์ฐ์ด๋ ์์ ๋จ์๊ฐ ์๋๋ผ ํน์ ๊ฐ์ฒด๊ฐ ๊ฐ์ง ์ ์๋ ๊ธฐ๋ฅ์ ๋จ์๋ฅผ ์๋ฏธํ์ฃ .
.guard { context ->
val paymentId = context.extendedState.variables["paymentId"] as Long
paymentService.canProcess(paymentId)
}
๊ฒฐ์ ๊ฐ ๊ฐ๋ฅํ ์ํ์ธ ์ง ํ์ธ ํ ํ์ ๊ฒฐ์ ์์ฒญ ์ ์ด๋ฅผ ํ๊ณ ์ถ์ ๋ ๊ฐ๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๐ฌ ์ก์ (Action)
์ก์ (Action) ์ ์ ์ด ์์ ๋๋ ์ํ ์ง์ ์ ์คํํ ๋น์ฆ๋์ค ๋ก์ง์ ๋๋ค.
.action { context ->
val paymentId = context.extendedState.variables["paymentId"] as Long
paymentService.processPayment(paymentId)
}
processPayment
๋ผ๋ ๋ฉ์๋๋ฅผ ํธ์ถํด ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ์์์์. ํน์ ์ํ์ ์ง์
ํ์ ๋ (PROCESSING
์ด ๋๊ฒ ์ฃ ?) ์ด ๋ก์ง์ ํธ์ถํ๋ผ๊ณ ํ๋ก๊ทธ๋๋ฐ ํ ์ ์์ฃ .
๐ฆ ExtendedState
ExtendedState ๋ ์ํ ์ ์ด ์์ ์ ๊ณต์ ํ ์ ์๋ ์ ์ญ ์ํ ์ ์ฅ์์ ๋๋ค. ๊ฒฐ์ ID (paymentId) ์ ๊ฐ์ ์ ๋ณด๋ฅผ FSM ์์์ ๊ณต์ ํ ๋ ์ฌ์ฉํ์ฃ .
stateMachine.extendedState.variables["paymentId"] = 123L
๐ณ ๊ฒฐ์ ์๋น์ค ์์ ๋ก ๋ณด๋ Spring State Machine
๋ง์นจ ๊ฒฐ์ ์ ๋ํ ์์๊ฐ ์์ ๋์ค๊ธฐ๋ ํ์ผ๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ค๋ฌด์์ ๋์ ํ ์์ ๋ฅผ ์ง์ด๋ณด๊ฒ ์ต๋๋ค.
์ฌ์ฉ์๊ฐ ๊ฒฐ์
๋ฒํผ์ ๋๋ฅด๋ฉด ์ด ๋ก์ง์ ์๋์ ๊ฐ์ ์ํ๋ฅผ ๊ฐ์ง๋๋ค.
- ๋๊ธฐ ์ค โ ์ฒ๋ฆฌ ์ค โ ์น์ธ๋จ
- ํน์ ์ค๊ฐ์ ์คํจ, ํน์ ์ฌ์ฉ์ ์ทจ์
- ๋ ๊ฒฝ์ฐ์ ๋ฐ๋ผ์ ํ๋ถ, ์ฌ์น์ธ, ๋ณด๋ฅ ์ํ๋ ์์ ์ ์์ต๋๋ค
์ด์ฒ๋ผ ์ํ๊ฐ ๋ช ํํ ๊ตฌ๋ถ๋๊ณ , ์ ์ด๊ฐ ์ด๋ฒคํธ๋ก ์ธํด ๋ฐ์ํ๋ ๊ฒฝ์ฐ Spring State Machine์ ์ ์ฉํ๊ธฐ ์ข์ต๋๋ค.
๋จผ์ ์ ์ฒด ํ๋ฆ์ ๋จ์ํํด ์๊ฐํํด๋ณด๊ฒ ์ต๋๋ค.
[WAITING] --๊ฒฐ์ ์์ฒญโ [PROCESSING]
| |
| +--์น์ธโ [APPROVED]
| +--์คํจโ [FAILED]
| +--์ทจ์โ [CANCELED]
โ๏ธ ๋ก์ง ์์ฑ
Spring(Kotlin) ์์๋ก ํ๋ฒ ๋ณผ๊น์? (์ฝ๋๋ ์ต์ํ์ผ๋ก ์์ฑ ํด ๋ณด๊ฒ ์ต๋๋ค.)
enum class PaymentState {
WAITING, PROCESSING, APPROVED, FAILED, CANCELED
}
enum class PaymentEvent {
REQUEST, APPROVE, DECLINE, CANCEL
}
๊ฒฐ์ ์ฒ๋ฆฌ์ ํ์ํ ์ํ์ ์ด๋ฒคํธ๋ค์ enum
ํด๋์ค๋ก ์ ์ธ ํด ๋ก๋๋ค.
@Configuration
@EnableStateMachine
class PaymentStateMachineConfig : StateMachineConfigurerAdapter<PaymentState, PaymentEvent>() {
override fun configure(states: StateMachineStateConfigurer<PaymentState, PaymentEvent>) {
states
.withStates()
.initial(PaymentState.WAITING)
.end(PaymentState.APPROVED)
.end(PaymentState.FAILED)
.end(PaymentState.CANCELED)
.states(EnumSet.allOf(PaymentState::class.java))
}
override fun configure(transitions: StateMachineTransitionConfigurer<PaymentState, PaymentEvent>) {
transitions
.withExternal().source(PaymentState.WAITING).target(PaymentState.PROCESSING).event(PaymentEvent.REQUEST)
.and()
.withExternal().source(PaymentState.PROCESSING).target(PaymentState.APPROVED).event(PaymentEvent.APPROVE)
.and()
.withExternal().source(PaymentState.PROCESSING).target(PaymentState.FAILED).event(PaymentEvent.DECLINE)
.and()
.withExternal().source(PaymentState.PROCESSING).target(PaymentState.CANCELED).event(PaymentEvent.CANCEL)
}
}
๊ทธ๋ฆฌ๊ณ ์ด ์ํ๋ค์ ๋ณํ์ ๋ํ ์ ์ด ๋ฐฉํฅ์ฑ์ Configuration ์ฝ๋๋ก ์์ฑํ ์ ์์ต๋๋ค. ๊ฒฐ์ ๋ก์ง์ ์ด๊ธฐ ์ํ๋ WAITING
, ๊ทธ๋ฆฌ๊ณ APPROVED
, FAILED
, CANCELED
๋ ์ข
๋ฃ ์ํ์ฃ . ์ด ์ํ๋ค์ ๊ด๊ณ๋ฅผ StateMachineStateConfigurer
์ ์ง์ ํด ์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ํ ์ ์ด ํ๋ฆ ๊ด๊ณ๋ฅผ StateMachineTransitionConfigurer
์ ์์ฑ ํฉ๋๋ค.
์ฝ๋๊ฐ ์ถ์์ ์ผ ์ ์์ผ๋ ์ํ ๋ค์ด์ด๊ทธ๋จ์ ๊ทธ๋ ค๋ณผ๊น์?

์ง๊ธ๊น์ง ์ ๋ฐ๋ผ ์ ์ฃผ์ จ์ต๋๋ค. State Machine ์ ์ค์ ํ์ผ๋ ์ค์ ์๋น์ค์ ํ๋ฒ ๋ น์ฌ๋ณด๊ฒ ์ต๋๋ค.
Spring MVC ๊ตฌ์กฐ ์์์ ๊ฒฐ์ ์์ฒญ์ ๋ํ ๋ก์ง์ ์ด๋ ๊ฒ ํ๋ฌ๊ฐ๋๋ค.
Controller (๊ฒฐ์ ์์ฒญ) โ Service (์ํ ์ ์ด trigger)
โ StateMachine โ action / entry ์คํ
@Component
class PaymentActions {
@Bean
fun requestAction(): Action<PaymentState, PaymentEvent> {
return Action { context ->
val paymentId = context.extendedState.variables["paymentId"] as Long
paymentService.processPayment(paymentId)
}
}
}
๋ง์ฝ ๊ฒฐ์ ์์ฒญ์ด PROCESSING
์ํ๊ฐ ๋์์ ๋ ์คํ๋์ด์ผ ํ ๋น์ฆ๋์ค ๋ก์ง์ด ๊ฒฐ์ ๋ก์ง ํธ์ถ์ด๋ผ๋ฉด ์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ์์ฑํ๋ Configuration
์ฝ๋์ ๋ถ๊ฐ ๋ก์ง์ ์ฐ๊ฒฐํฉ๋๋ค.
transitions
.withExternal()
.source(PaymentState.WAITING)
.target(PaymentState.PROCESSING)
.event(PaymentEvent.REQUEST)
.action(paymentActions.requestAction())
Service ๋ ์ด์ด (๋น์ฆ๋์ค ๋ก์ง ๋ ์ด์ด) ์์๋ ๊ทธ๋ผ ์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
@Service
class PaymentService(
private val stateMachineFactory: StateMachineFactory<PaymentState, PaymentEvent>
) {
/**
* ๊ฒฐ์ ์์ฒญ์ด ๋ค์ด์ค๋ ๊ฒฝ์ฐ ์ ์ผ ๋จผ์ ํธ์ถ๋๋ ๋ฉ์๋
*/
fun handlePaymentRequest(paymentId: Long) {
val stateMachine = stateMachineFactory.getStateMachine(paymentId.toString())
stateMachine.start()
stateMachine.extendedState.variables["paymentId"] = paymentId
stateMachine.sendEvent(PaymentEvent.REQUEST)
}
/**
* ๊ฒฐ์ ๋ก์ง ์์
*/
fun processPayment(paymentId: Long) {
// do something
}
}
๊ฒฐ์ ์์ฒญ์ด ๋ค์ด์์ ๋ handlePaymentRequest
๋ฉ์๋๋ถํฐ ํธ์ถํ๋ค๊ณ ์๊ฐํด๋ณด๋ฉด, ๋ฉ์๋๊ฐ ํธ์ถ๋์์ ๋ stateMachine ์ ํ๋ ๋ถ๋ฌ์ต๋๋ค.
์ ์ฒด ํ๋ฆ์ ์ํ ๋ค์ด์ด๊ทธ๋จ์ผ๋ก ์์ฝํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
sequenceDiagram
participant C as Controller
participant S as PaymentService
participant FSM as StateMachine
participant PG as PG API
C->>S: ๊ฒฐ์ ์์ฒญ(paymentId)
S->>FSM: ์ํ ๋จธ์ ์์ ๋ฐ ์ด๋ฒคํธ ์์ฒญ(REQUEST)
FSM->>S: action(requestAction) ํธ์ถ
S->>PG: ๊ฒฐ์ ์น์ธ ์์ฒญ
PG-->>S: ์น์ธ ์๋ต
๋ชจ๋ ๊ฒฐ์ ๋ก์ง์ด ๋๋๊ณ APPROVED
์ํ์ ์ง์
ํ์ ๋ ์๋์ ๋ณด๋ด๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ก์
์ ์ง์ ํด์ค ์๋ ์์ฃ .
/**
* APPROVED ์ํ๊ฐ ๋์์ ๋ Slack, Telegram ๋ฑ์ผ๋ก ์๋ ์ ๋ฌ
*/
@Bean
fun approvalEntryAction(): Action<PaymentState, PaymentEvent> {
return Action { context ->
val paymentId = context.extendedState.variables["paymentId"] as Long
notificationService.sendApprovalMessage(paymentId)
}
}
override fun configure(states: StateMachineStateConfigurer<PaymentState, PaymentEvent>) {
states
.withStates()
.initial(PaymentState.WAITING)
.state(PaymentState.APPROVED, paymentActions.approvalEntryAction(), null)
}
๐งช ๋ก์ง ํ ์คํธ
์ง๊ธ๊น์ง ๋ก์ง์ ์ ์์ฑํ์ง๋ง, ๊ฐ๋ฐ์ ์ ์์ ํ ์คํธ๋ฅผ ํ๊ณ QA ๋ก ๋๊ฒจ์ผ๊ฒ ์ฃ ?
์ง๊ธ๊น์ง ์์ฑํ State Machine ์ Kotest ๋ก ํ ์คํธ ํด ๋ณด๊ฒ ์ต๋๋ค.
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.statemachine.StateMachine
import org.springframework.statemachine.config.StateMachineFactory
import org.springframework.test.context.TestPropertySource
@SpringBootTest
@TestPropertySource(locations = ["classpath:application-test.properties"])
class PaymentStateMachineBehaviorSpecTest @Autowired constructor(
private val stateMachineFactory: StateMachineFactory<PaymentState, PaymentEvent>
) : BehaviorSpec({
given("๊ฒฐ์ ์ํ ๋จธ์ ์ด ์ด๊ธฐํ๋์์ ๋") {
`when`("REQUEST ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด๋ฉด") {
then("WAITING โ PROCESSING ์ํ๋ก ์ ์ด๋๋ค") {
val machine: StateMachine<PaymentState, PaymentEvent> =
stateMachineFactory.getStateMachine("PAYMENT_REQ_1")
machine.start()
machine.sendEvent(PaymentEvent.REQUEST)
machine.state.id shouldBe PaymentState.PROCESSING
}
}
`when`("REQUEST โ APPROVE ์ด๋ฒคํธ๋ฅผ ์์๋๋ก ๋ณด๋ด๋ฉด") {
then("WAITING โ PROCESSING โ APPROVED ์ํ๋ก ์ ์ด๋๋ค") {
val machine = stateMachineFactory.getStateMachine("PAYMENT_REQ_2")
machine.start()
machine.sendEvent(PaymentEvent.REQUEST)
machine.sendEvent(PaymentEvent.APPROVE)
machine.state.id shouldBe PaymentState.APPROVED
}
}
`when`("REQUEST โ DECLINE ์ด๋ฒคํธ๋ฅผ ์์๋๋ก ๋ณด๋ด๋ฉด") {
then("WAITING โ PROCESSING โ FAILED ์ํ๋ก ์ ์ด๋๋ค") {
val machine = stateMachineFactory.getStateMachine("PAYMENT_REQ_3")
machine.start()
machine.sendEvent(PaymentEvent.REQUEST)
machine.sendEvent(PaymentEvent.DECLINE)
machine.state.id shouldBe PaymentState.FAILED
}
}
}
})
ํํ ๋ณด๋ ํ ์คํธ ์ฝ๋์ง๋ง, State Machine ์ผ๋ก ๋ก์ง์ ์์ฑํ๊ฒ ๋๋ฉด ๋ง์น ๊ธฐ๊ณ๋ฅผ ์กฐ์ํ๋ ๊ฒ์ฒ๋ผ ๋ช ์์ ์ด๊ณ ๊ฐ๊ฒฐํ๊ฒ ์์ฑํ ์ ์๋ค๋ ์ด์ ์ด ์์ฃ .
โ ๏ธ Spring State Machine ๋์ ์ ๊ณ ๋ คํด์ผ ํ ์ ?
์ฌ๊ธฐ๊น์ง ์ฝ์ด ๋ณด์ จ์ ๋ ์๋นํ ์ ํฌ ๋น์ฆ๋์ค ๋ก์ง์ ์์ฑํ๋ ๋ฐ ๋์์ด ๋๋ค๊ณ ์๊ฐ์ด ๋์ค ์ ์์ง๋ง, ์ด๋ฐ ์์ง๋์ด๋ง์ ๊ณต์๊ฐ ๋ค์ด๊ฐ๋ ์์ ์ ๋๋ค. ๊ทธ๋์ ๋ช ๊ฐ์ง ๊ธฐ์ค์ ๊ฐ์ง๊ณ ๋ก์ง์ ์์ฑํด์ผ ํฉ๋๋ค.
๋จผ์ Finite State Machine ์ ์ฐ๋ ๊ฒ ๊ณผํ ์ค๊ณ์ธ ์ง ๊ณ ๋ คํด๋ณผ ํ์๊ฐ ์์ต๋๋ค. ์ํ๊ฐ ์ ๋ค๋ฉด, ์๋ฅผ ๋ค์ด 2 ~ 3๊ฐ ์ ๋๋ฉด ๊ตณ์ด State Machine ๊น์ง ํ์๊ฐ ์์ ์ ์์ด์. ๋จ์ํ ์ฝ๋๋ก ํด๊ฒฐ ๋ ๋งํผ ๊ฐ๋จํ ๋ฌธ์ ๋ผ๋ฉด ๊ฐ๋จํ๊ฒ ํด๊ฒฐํ๋ ๊ฒ ๋ง์ต๋๋ค.
๋ํ ๋ณต์กํ ์กฐ๊ฑด ๋ถ๋ฆฌ์ ๋ํด์๋ Guard ๋ก ์ ๋ถ๋ฆฌํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์น์ธ ์กฐ๊ฑด์ 1๋ถ ์ด๋ด ์ฌ์๋ ํ๊ฑฐ๋ ์ฌ์ฉ์ ์ํ๊ฐ ๋ธ๋ํ์์ธ ๊ฒฝ์ฐ์ Guard ๋ก ์ถ์ถํด์ผ ํ์ฃ .
๋ํ ์ฅ๊ธฐ ๊ฑฐ๋๋ ์น์ธ ํ๋ก์ธ์ค ๋ฑ ์ํ๋ฅผ ๋ณด์กดํด์ผ ํ๋ ๊ฒฝ์ฐ์ Oracle, MySQL ๊ฐ์ RDB ํน์ Redis ๋ฑ์ ์ ์ฅํด์ผ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ์ ์ฅ ๋ฐฉ์์ ๋ฐ๋ผ ๋ณต๊ตฌ๋ ์ฌ์๋ ์ ๋ต์ด ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.
๋ํ ์ ์ด๊ฐ ์คํจํ๊ฑฐ๋ ์์ธ๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ์ ๋ํ ์ฌ์ด๋์ดํํธ๋ฅผ ๋ช
ํํ ์ ์ํด์ผ ํฉ๋๋ค. StateMachineListener
๋ฑ์ ํ์ฉํด์ผ ํ์ฃ .
โฑ๏ธ ์ฌํ : ๊ฒฐ์ ์ธ์ ๊ด๋ฆฌ ์์
๊ทธ๋ผ ๋ง์ฝ์ ์ด๋ฐ ์๊ตฌ์ฌํญ์ด ์๋ค๊ณ ์๊ฐ ํด๋ณผ๊น์?
๊ฑฐ๋ ์น์ธ์ ์๋ฒ ์๊ฐ ๊ธฐ์ค์ผ๋ก 3๋ถ ๊ฐ ์ ํจํด์ผ ํ๋ค.
๋ฉ๋ฆฌ ๊ฐ ๊ฒ๋ ์์ด ์ผํ๋ชฐ์์ XX ํ์ด ๋ฑ์ผ๋ก ๊ฒฐ์ ํ ๋, ๋ช ๋ถ ์์ ๊ฒฐ์ ๊ฐ ์ด๋ค์ง์ง ์์ผ๋ฉด ๋ค์ ์์ฒญ์ ํด์ผ ํ์ฃ .
์ฐ๋ฆฌ๊ฐ ๊ฑฐ๋ ์์ฒญ์ ํ๋ ์์ ์์ State Machine ์ด ํน์ ๊ฑฐ๋ ID ์ ๋ํด ์ด๊ธฐํ๋๊ณ , 3๋ถ ์์ ๊ฑฐ๋๋ฅผ ์น์ธํ๊ฒ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
์๋ฒ ์ ์ฅ์์ ๋ฐ์ดํฐ๋ฅผ ์ด๋๊ฐ์ ์ ์ฅ ํด ๋์ด์ผ ๊ฒ ์ฃ . ์ผ๋ฐ์ ์ผ๋ก RDB ๋ฅผ ์ธ ์ ์๊ฒ ์ง๋ง, ๊ฒฐ์ ์์ฒญ์ด ๋๊ท๋ชจ๋ก ๋ค์ด์ค๊ฒ ๋๋ค๋ฉด ์ด๋จ๊น์? ์ฝ๊ธฐ/์ฐ๊ธฐ ๋ณ๋ชฉ์ด ์ผ์ด๋ ์๋ ์์ต๋๋ค.
Redis
๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ (RAM) ์ ์ฌ๋ ค๋๊ณ ๋์ํฉ๋๋ค. ํ์ง๋ง RDB ๋ ๋์คํฌ (ํํ ๋งํ๋ SSD, HDD) ์ ๊ธฐ๋ฐํ๊ธฐ ๋๋ฌธ์ ์ฝ๊ธฐ/์ฐ๊ธฐ ์ฑ๋ฅ์ ์ ํ์ด ๊ฑธ๋ฆด ์ ์์ฃ .
๋๋์ ์์ฒญ์ด ๋ค์ด์ค๋ ๊ฒฝ์ฐ ํนํ RDB ๋ง์ผ๋ก๋ ๋์์ ๋ค์ด์ค๋ ์์ฒญ์ ๋ํด ์ฐ๊ธฐ ์์ฒญ์ด ๋ค์ด๊ฐ๋ ๊ฒฝ์ฐ ๋ฝ (๋ค๋ฅธ ์ฐ๊ธฐ ์์ฒญ์ด ๋งํ๋ ๊ฑธ ์๋ฏธํฉ๋๋ค.)์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
ํ์ง๋ง Redis
๋ ํน์ key ๊ฐ์ ํ ๋น ๋ ๋ฐ์ดํฐ๋ง ๋ณ๊ฒฝํ๋ฉด ๋์ฃ . ๊ฒ๋ค๊ฐ TTL(๋ง๋ฃ์๊ฐ) ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค. ๋ง๋ฃ์๊ฐ์ด ์ง๋๋ฉด ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ญ์ ์ฒ๋ฆฌ ํ ์ ์์ฃ . RDB ๋ Scheduler ๋ฑ์ ํตํด ์ฃผ๊ธฐ์ ์ผ๋ก ์ด๋ฐ ๋ฐ์ดํฐ๋ค์ ์ง์์ค์ผ ํ ์ ์์ต๋๋ค.
์ง๊ธ ๊ฐ์ ๊ฒฐ์ ์ฒ๋ฆฌ์ ๊ฐ์ด ์ผ์์ ์ด๊ณ ๋น๋ฒํ ๋ณ๊ฒฝ๋๋ ์ํ ๋ฐ์ดํฐ๋ Redis
๊ฐ ์ข ๋ ์ ํฉํ๋ค๊ณ ํ ์ ์์ต๋๋ค. ๋ฌผ๋ก RDB๋ผ๊ณ ๋ถ๊ฐ๋ฅํ ๊ฑด ์๋๋๋ค. ์์ ๋ง์๋๋ฆฐ ์ํฉ์ ๋ํด ์ถฉ๋ถํ ๋์ ๊ฐ๋ฅํ ํธ๋ํฝ์ด๋ผ๋ฉด ์ฐ์ RDB๋ก ๋ก์ง์ ๊ตฌํ ํด ๋ณด๋๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ฃ .
ํญ์ ์ํํ์ ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์!
๋ง์ Redis ๋ฅผ ๋์ ํ๋ค๊ณ ํด๋ ๋ชจ๋ ๊ฒ ํด๊ฒฐ๋์ง๋ ์์ต๋๋ค.
Redis ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ํ์ํ ๊ณต์๋ ๋ค์ฃ . ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ ค๋๋ค๋ ๊ฑด, ํ๋ก์ธ์ค๊ฐ ์ฃฝ์ผ๋ฉด (ํํ ํ๋ก๊ทธ๋จ์ด ์ฃฝ์๋ค๊ณ ํ์ฃ ) ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ ์ค๋ ์ ์์ต๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ํด๋ฌ์คํฐ๋ง์ ํ๊ณค ํ๋๋ฐ...์ด๊ฒ๋ ๊ฒฐ๊ตญ ์์ง๋์ด๋ง ๋น์ฉ์ด์ฃ ...ํ์ง๋ง ํธ๋ํฝ์ด ๋์ด๋ฌ๋ค๋ฉด ๊ทธ ๋งํผ ๊ณ ๊ฐ๋ค์ ๋์ํด์ผ ํ์์์?
๋ง์น ์๋น์ด ์ ๋๋ฉด ์ง์์ ๋ฝ๊ณ , ํ ์ด๋ธ์ ๋๋ฆฌ๊ณ ์ฅ๋น๋ฅผ ๋์ ํ๋ ๋ฑ...์๋น์ค๋ ์ํฉ์ ๋ฐ๋ผ ์ธ ๋๊ตฌ๊ฐ ๋ฌ๋ผ์ง๋ ๊ฒ ๊ฐ์์.
fun requestPayment(paymentId: String) {
val machine = stateMachineFactory.getStateMachine(paymentId)
machine.start()
machine.sendEvent(PaymentEvent.REQUEST)
persister.persist(machine, paymentId)
// Redis์ ๊ฑฐ๋ ์ํ ์ ์ฅ (TTL: 3๋ถ)
redisTemplate.opsForValue().set("payment:$paymentId", "PROCESSING", Duration.ofMinutes(3))
}
stateMachine ์ด ์ด๊ธฐํ ๋๋ ์์ ์์ Redis ์ paymentId
ํค๊ฐ์ผ๋ก stateMachine ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค. 3๋ถ TTL ์ ์ง์ ํ ์ ์์ฃ .
fun approvePayment(paymentId: String) {
val machine = stateMachineFactory.getStateMachine(paymentId)
persister.restore(machine, paymentId)
if (machine.state.id == PaymentState.PROCESSING) {
machine.sendEvent(PaymentEvent.APPROVE)
persister.persist(machine, paymentId)
// Redis TTL ์ ๊ฑฐ
redisTemplate.delete("payment:$paymentId")
}
}
์น์ธ์ด ๋ง๋ฌด๋ฆฌ๋๋ฉด Redis ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์์ค๋๋ค. ๋ง์ฝ 3๋ถ ์์ ์น์ธ์ด ๋์ง ์๋๋ค๋ฉด ์์ฐ์ค๋ฝ๊ฒ Redis ์์ ์์์ ์ง์์ฃผ์ฃ .
๋ง์ฝ 3๋ถ์ด ์ง๋์ ์ ํจ์๊ฐ์ด ๋ง๋ฃ๊ฐ ๋๋ฉด Redis ์ Keyspace Notification ๊ธฐ๋ฅ์ ์ธ ์ ์์ต๋๋ค. TTL ๋ง๋ฃ ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ์ State Machine ์ ์๋์ผ๋ก EXPIRED ์ํ๋ก ์ฒ๋ฆฌํ ์ ์์ฃ .
@Configuration
class RedisExpiredEventListener(
private val stateMachineFactory: StateMachineFactory<PaymentState, PaymentEvent>
) {
@Bean
fun messageListenerAdapter(): MessageListenerAdapter {
return MessageListenerAdapter(ExpiredKeyEventListener(stateMachineFactory))
}
@Bean
fun redisMessageListenerContainer(
connectionFactory: RedisConnectionFactory,
listenerAdapter: MessageListenerAdapter
): RedisMessageListenerContainer {
val container = RedisMessageListenerContainer()
container.setConnectionFactory(connectionFactory)
container.addMessageListener(listenerAdapter, PatternTopic("__keyevent@0__:expired"))
return container
}
}
์ฌ์ ์์ ์ ํด๋ณผ๊ฒ์. Redis ๊ฐ ๋ณด๋ด๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ์ ์๋ Config ์ฝ๋๋ฅผ ์์ฑ ํด ๋ณด๊ฒ ์ต๋๋ค.
class ExpiredKeyEventListener(
private val stateMachineFactory: StateMachineFactory<PaymentState, PaymentEvent>
) : MessageListener {
override fun onMessage(message: Message, pattern: ByteArray?) {
val key = String(message.body)
// ํค ๋ค์ด๋ฐ ์์: "payment:PAYMENT_123"
if (key.startsWith("payment:")) {
val paymentId = key.removePrefix("payment:")
val machine = stateMachineFactory.getStateMachine(paymentId)
machine.start()
machine.sendEvent(PaymentEvent.EXPIRED)
}
}
}
๊ฑฐ๋ ์ธ์ ์ ๋ณด๊ฐ TTL ์ด ์ง๋์ ๋ง๋ฃ ์ฒ๋ฆฌ๊ฐ ๋์๋ค๋ฉด, Redis ์์ Spring ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ฒ ๋ฉ๋๋ค. ์ด ๋ฉ์์ง๊ฐ ์ ๋ฌ ๋์์ ๋ ํธ๋ค๋ฌ์๊ฒ ๋ง๋ฃ ์ฒ๋ฆฌ ๋ก์ง์ ํ ๋น์์ผ์ค ์ ์์ฃ .
๐ช Outro
์ง๊ธ๊น์ง Finite State Machine ์ ๋ํ ์ปดํจํฐ๊ณตํ ์ด๋ก ์ง์, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์ฌ์ฉํ๋ Spring State Machine ์ ๋ํด ๋ฅ๋ค์ด๋ธ ํด ๋ณด์์ต๋๋ค.
์ฒ์์๋ ์ค๋ฌด ํด์ ๋ํด ์ค๋ช ํ๋ ค๊ณ ํ๋ค๋ณด๋ ๊ธฐ๋ฐ ์ง์์ ๋ํ ์ดํด๊ฐ ํ์ํ๋ค๊ณ ์๊ฐ์ด ๋ค์ด์ ๊ธ์ ์ฐ๊ธฐ ์์ํ์ด์. ์ด์ฉ๋ค๊ฐ ์ปดํ์ผ๋ฌ ์ด๋ก ๊น์ง ๋์๋๋ฐ, ํ๋ ์์ํฌ ํ๋ํ๋๊ฐ ์ฌ์ค์ ์จ์ด์๋ ์ด๋ก ์ง์๋ค๋ก ์ผ๋งฅ์ํต ํ๋ค๋ ๋ง์ ํ๊ณ ์ถ์์ต๋๋ค.
์ํ๊ฐ ๋ง์์ง๊ณ , ํ๋ฆ์ด ๊ผฌ์ด๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ด ๋ฉ์ด๋ฆฌ์ฒ๋ผ ๋ชฐ๋ฆฌ๋ ๋๋์ด ๋ ๋ค๋ฉด ํ ๋ฒ์ฏค FSM์ผ๋ก ๊ทธ๋ ค๋ณด๊ณ , Spring State Machine์ ๋์ ํด๋ณด๋ ๊ฑธ ์ถ์ฒ๋๋ฆฝ๋๋ค.
์ง๊ธ๊น์ง ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.