StateA
, StateB
클래스에는 데이터 멤버가 없습니다. 아마도 다른 주에서는 수정할 수있는 데이터 멤버가 없을 것입니다. 그럴 경우 해당 상태가 A의 서로 다른 인스턴스간에 이상하게 공유되므로 서로 다른 상태 시스템이 동시에 실행됩니다.
그래서 싱글 톤은 패턴의 문제 (전역 변경 가능 상태)의 절반을 피했습니다. 실제로 디자인을 약간만 변경하면 상태 클래스를 함수로 대체 할 수 있습니다. 함수 포인터로 인스턴스에 대한 포인터를 대체합니다. 가상 호출을 action
으로 바꾸고 현재 함수 포인터를 통해 호출합니다. 누군가가 싱글 톤을 사용하는 데 많은 번거 로움을 줄지 만 자신의 디자인이 정확하다고 확신하면이 사소한 변화를 만들어 "수정"이 디자인에 전혀 큰 변화를주지 않았 음을 알 수 있습니다.
싱글 톤 문제의 나머지 절반은 여전히 해결되지 않았으며 고정 종속성입니다.싱글 톤을 사용하면 StateA를 독립적으로 테스트하거나 현재 상태와 동일한 새 상태 머신을 라이브러리에 추가하려는 경우 유연성을 도입하기 위해 StateB를 모방 할 수 없습니다 of StateB. 당신은 그 문제를 고려할 수도 있고 고려하지 않을 수도 있습니다. 그렇게한다면, 각 주를 싱글 톤으로 만드는 것보다 일을 더 구성 가능하게 만들어야합니다.
예를 들어, 각 상태에 식별자 (문자열 또는 열거 형 멤버)를 줄 수 있고 각 식별자에 대해 A 클래스의 어딘가에 State*
을 등록 할 수 있습니다. 그런 다음 StateB, StateA의 singleton 인스턴스로 넘기지 않고 이 상태 기계의 "상태 B"을 나타내는 데 사용되는 모든 상태 개체로 전환 할 수 있습니다.. 그러면 특정 인스턴스에 대한 테스트 모의가 될 수 있습니다. 시스템 당 한 번 상태 당 new
으로 전화를 걸지 만 상태 변경 당 한 번은 전화하지 않습니다.
실제로 이것은 디자인에서와 마찬가지로 클래스 A의 전략 패턴입니다. 그러나 상태 시스템을 앞으로 이동시키는 단일 전략을 가지지 않고 상태가 변경됨에 따라 지속적으로이를 대체하는 것보다는 시스템이 통과하는 상태마다 동일한 인터페이스를 사용하는 하나의 전략이 있습니다. C++의 또 다른 옵션은 전략 대신 정책 기반 디자인 (형태)을 사용하는 것입니다. 그런 다음 각 상태는 객체 (런타임에 설정)보다는 클래스 (템플릿 인수로 제공됨)에 의해 처리됩니다. 따라서 상태 머신의 동작은 컴파일시 (현재 디자인에서와 같이) 고정되지만 StateB 클래스를 변경하거나 대체하지 않고 템플릿 인수를 변경하여 구성 할 수 있습니다. 그런 다음 new
을 호출 할 필요가 없습니다. 상태 시스템에서 각 상태의 단일 인스턴스를 데이터 멤버로 만들고 그 중 하나에 대한 포인터를 사용하여 현재 상태를 나타내며 가상으로 호출합니다. 전에. 정책 기반 설계는 일반적으로 가상 호출을 필요로하지 않습니다. 일반적으로 별도의 정책은 완전히 독립적이지만, 여기서는 공통 인터페이스를 구현하고 런타임에 이들 사이에서 선택하기 때문입니다.
이 모든 것은 A가 유한 상태 집합을 알고 있다고 가정합니다. 이것은 현실적이지 않을 수 있습니다 (예를 들어, A는 임의의 수의 임의 상태를 허용해야하는 다목적 프로그래머블 상태 시스템을 나타낼 수 있습니다). 이 경우 상태를 구축 할 방법이 필요합니다. 먼저 StateA 인스턴스와 StateB 인스턴스를 만듭니다. 각 상태에는 하나의 이탈 경로가 있으므로 각 상태 객체에는 새 상태에 대한 포인터 인 하나의 데이터 멤버가 있어야합니다. 따라서 상태를 생성 한 후 StateA 인스턴스를 StateB 인스턴스에 "다음 상태"로 설정하거나 StateB 인스턴스에 StateB 인스턴스를 "다음 상태"로 설정합니다. 마지막으로 A의 현재 상태 데이터 멤버를 StateA의 인스턴스로 설정하고 실행을 시작합니다. 이렇게하면 종속성의 순환 그래프를 작성하므로 메모리 누수를 방지하기 위해 참조 계산 이외의 특별한 리소스 처리 방법을 사용해야 할 수도 있습니다.
"두 개의 상태 머신을 병렬로 실행하려면 어떻게해야합니까?" 상태 머신은 싱글 톤이 아닙니다. * 상태 *는 싱글 톤입니다. 그러나 위의 디자인에서 상태 머신은 A입니다. 우리는 원하는만큼 인스턴스를 생성 할 수 있습니다. –
@Steve Jessop- 내 관심사는 상태 머신 상태가 일종의 상태를 필요로하는 싱글 톤 (예를 들어, 네트워크 프로토콜의 컨트롤 인 경우 상태는 IP 주소 등을 저장해야 할 수도 있음) 인 경우 상태가 싱글 톤 (singleton)으로되어있어 서로를 파괴적으로 간섭하지 않고 여러 상태 시스템을 가질 수 없습니다. 아마 내가 분명히 했어야했는데 ... 세부 사항을 깨닫기 전에이 점을 많이 썼다. :-) – templatetypedef