FSM
- FSM은 주로 Flying Spagetti Monster, 혹은 Finite State Machine를 의미한다.
- Flying Spagetti Monster
- 여기서는 Finite State Machine을 설명하려고 한다.
Finite State Machine
유한 상태 기계란?
- 유한 상태 기계는 자신이 취할 수 있는 유한한 갯수의 상태들을 가진다.
- 그리고 그 중에서 반드시 하나의 상태만 취한다.
- 현재 상태는 특정 조건이 되면 다른 상태로 변할 수 있다.
- 유한 상태 기계는 가능한 상태들의 집합과 각 상태들의 전이 조건으로 정의 될 수 있다.
- 상태들의 노드와 그 노드들을 연결하는 조건의 엣지로 표현할 수 있다(그래프).
전구의 예
- 전구는 ON / OFF 두가지 상태를 갖는다.
- 전구는 반드시 둘중 하나의 상태만 취한다.
- 각 상태는 특정 조건 (스위치 올림 / 내림 ) 에 따라 변한다
- 전구를 다음과 같이 정의할 수 있다.
- ON : 스위치가 올라가면 OFF로 전이
- OFF : 스위치가 내려가면 ON으로 전이
- ON : 스위치가 올라가면 OFF로 전이
유한 상태 기계를 왜 쓰는가?
- 가능한 상태들을 명확히 규정할 수 있다.
- 상태 중복을 피할 수 있다.
- 전이들을 명확하게 규정할 수 있다.
- 따라서 기계의 동작을 분명하게 규정할 수 있다.
- 프로그래밍에서 FSM에 기반한 객체를 만든다면, 안정적인 작동을 보장할 수 있다.
FSM 구현
- 기본적으로 IF, SWITCH 등의 조건분기로 나누어 작동하게 할 수 있다.
typedef enum{ON, OFF} BurbState;
typedef enum{ON, OFF} SwitchState;
class Burb
{
public:
void Transition(SwitchState switchState)
{
switch(m_State)
{
case ON :
if(switchState == OFF)
m_State = OFF;
break;
case OFF :
if(switchState == ON)
m_State = ON;
break;
}
}
private:
BurbState m_State;
}
Game에서 FSM
이걸 switch case로 작성한다고 상상해보자
- 이런 구현방식은 상태가 많아지고 조건이 복잡해 진다면 코드가 지나치게 길어지고 유지보수에 어려움을 겪을 수 있다.
- 계속해서 새로운 상태가 추가된다면 상태가 추가될 때마다 새로운 분기를 작성해야되고, 중복된 코드가 많아진다.
- 이런 문제를 해결하기위해서 State 디자인 패턴을 적용할 수 있다.
State Design Pattern
State Design Pattern 의 기본개념
- 기본적으로 객체지향의 다형성을 활용한다.
- State를 추상 클래스로 만들고 여러 상태들을 State를 상속받는 클래스로 구현한다.
- State는 각 상태들의 인터페이스를 규정하고, 실제 동작은 각 상태별로 다르게 구현된다.
- FSM의 대상 객체(Context)는 현재상태를 멤버변수로 갖고 State의 인터페이스를 활용하여 현재 상태를 동작시킨다.
- 전이 조건이 발생하면 FSM의 대상 객체는 현재 상태를 조건에 맞는 다음 상태로 바꿔준다.
State Design Pattern 구현
개념은 쉽지만 실제 복잡한 상태기계를 구현하려고 하면 걸리는 문제가 한두개가 아니다.
상태 전이 처리를 어떻게 결정할 것인가?
- Context가 상태전이를 결정하게 하면 그냥 switch case를 쓰는것과 별반 다를바 없는 코드가 나올 수 있다.
- 엄청나게 많은 전이 조건과 상응하는 상태에 대해서 전부 기술해야 되기 때문이다.
각각의 상태객체들이 자신의 상태 전이 처리에 대해 알고 있다면?
- 전체 전이 조건을 한꺼번에 복잡하게 다룰 필요가 없어진다.
- 새로운 상태를 추가할때는 그 상태객체에서 그에 해당하는 전이처리만 해주면 된다.
- 대신 상태객체가 다른 상태객체에 대해서 알고 있어야하므로, 커플링이 일어난다는 단점이 있다.
상태객체를 소멸하고 생성하는 문제
- 상태객체를 필요할 때만 생성하고 필요없으면 없앤다.
- 상태 변화가 적을 때 유용, 많으면 할당 해제에 지나친 로드
- 미리 싹 다 생성
- 로딩만 좀 길고 나중에 로드 없음.
- Context가 여러 상태 객체(포인터)들을 다 관리해야함. ( 컨터이너 필요 )
- 상태객체를 필요할 때만 생성하고 필요없으면 없앤다.
'컴퓨터 > C++' 카테고리의 다른 글
c++ 함수포인터 부터 std::function까지 (0) | 2015.03.10 |
---|---|
c++의 여러가지 생성자들 (0) | 2015.03.10 |
c++의 static 변수에 대하여 (0) | 2015.03.10 |
c++의 가상함수 (0) | 2015.03.10 |