2010-07-02 14 views
3

첫째, 상태 개체에 인스턴스 변수가 없을 때 상태 개체를 공유하는 방법을 설명 할 수 있습니까?GOF 상태 패턴 상태 전환 구현 문제

이 텍스트 GOF, 308 페이지, 항목 3 (영향 부)를 수행한다 :

상태 객체를 공유 할 수있다. 상태 객체에 인스턴스 변수가없는 경우 (즉, 이 나타내는 상태가 유형으로 완전히 인코딩 된 경우) 컨텍스트는 상태 객체를 공유 할 수 있습니다. 이런 식으로 에서 상태를 공유하면 본질적으로 플라이급입니다.

누구든지이 텍스트를 설명 할 수 있습니까?

두 번째로, 상태 전이 결정에 대한 접근 방법은 무엇입니까? 나는 다음 상태가 전파 될 결정을 의미합니까?

도와주세요. 감사합니다. .

+0

두 번째 질문에 대해 설명해 주시겠습니까? 일반적으로 주정부 시스템은 주 시스템으로 바뀌기 위해 어떤 상태로 변경해야하는지에 대한 결정을 내리지 않습니다. 그것은 상태와 그 사이의 전환을 정의하는 것뿐입니다. –

+0

BTW, 이것은 C++과는별로 관련이 없습니다. –

+0

아시다시피, 상태 패턴은 상태 전이 메소드를 정의하지 않습니다. 따라서 상태 패턴을 사용하여 상태 전이를 코딩하는 방법은 무엇입니까? 도와주세요. 감사합니다. – peterwkc

답변

2

을 당신이 대표 상태 개체를 사용하여 개체의 상태. 이러한 상태 개체 은 특정 상태 인을 나타내지 만 의 고유 한 상태를 갖지 않습니다. 이것은 그들이 절대로 바뀌지 않는다는 것을 의미합니다. 따라서 여러 객체가 동일한 상태 객체를 동시에 사용할 수 있습니다 (다른 스레드에서도 마찬가지 임). 상태 객체의 상태가 가변적 인 경우 다른 객체는 상태 객체가 다른 곳에서 변경되는 것에 대해 걱정해야합니다.

다른 많은 인스턴스에서 하나의 객체 인스턴스를 사용하면 flyweight-pattern의 인스턴스로 볼 수 있습니다.

class SomeStateMachine; 

class AbstractState { 
    // abstract baseclass for all state-classes 
    void input(const std::string & data, SomeStateMachine & caller) = 0; 
} 

class FinalState : public AbstractState { 
    FinalState * getInstance(); // always returns same instance 
} 

class InitialState : public AbstractState { 
public: 
    InitialState * getInstance(); // always returns same instance 
    void input(const std::string & data, SomeStateMachine & caller) { 
     std::cout << data << std::endl; 
     caller.m_State = FinalState::getInstance(); 
    } 
} 

class SomeStateMachine { 
public: 
    SomeStateMachine() : m_State(InitialState::getInstance()) 
    void input(const std::string & data) { 
     m_State->input(data, *this); 
    } 
private: 
    friend class InitialState; 
    AbstractState * m_State; 
}; 

그래서 당신은 기본적으로 당신의 상태 객체의 모든 메소드 호출하는 객체에 대한 참조를 전달합니다

는 질문의 두 번째 부분에 관해서는, 여기에 예입니다. 이 방법으로 상태 개체는 필요할 때 호출자의 상태를 변경할 수 있습니다. 이 예제는별로 아름답 지 않을 수도 있지만 아이디어를 얻길 바랍니다.

+0

하나의 객체 인스턴스를 다른 많은 인스턴스에서 사용하는 것은 플라이 웨이트 패턴의 인스턴스로 볼 수 있습니다. 나는 이것을 얻지 못한다. – peterwkc

+0

그러면 플라이휠 패턴을 읽어야합니다. 왜냐하면 이것이 전부입니다. –

+0

나는 플라이급을 이해하지만 나는 그것이 어떻게 상태 패턴과 관련되어 있는지 알지 못한다. – peterwkc

2

이 단락은 기본적으로 상태를 개별 클래스로 인코딩한다고 말합니다. 인스턴스 유형은 "상태"이고 클래스는 필요한 모든 정보를 인코딩하기 때문에 인스턴스 변수가 필요하지 않습니다.

예 : '열림', '활성'및 '닫힘'상태를 원합니다. -

또 다른 옵션 -이이 상태 클래스를 생성하는 것 GOF 텍스트에서 암시되고 플라이급과 조합 의심 것 무리

abstract class State {}; 

class Open extends State { 

    public Open() {} 

} 

class Active extends State { 

    public Active() {} 

} 

class Closed extends State { 

    public Closed() {} 

} 

: 나는 다음과 같은 클래스를 정의 할 수 있습니다 다음 공유 할 수의 정적 멤버 (각 상태에 대해 하나) -

public class State { 

    private string name; 

    private State(String name) { 
    this.name = name; 
    } 

    public final static State OPEN = new State("Open"); 
    public final static State ACTIVE = new State("Active"); 
    public final static State CLOSED = new State("Closed"); 

} 

나는이 모든 것들을 자세히 어떻게 작동하는지의 자신을 생각 나게 파고 가야했다. Kerievsky는 이것에 대해 잘 설명하고있다. (나는 위 예제 중 하나에서 많이 빌려왔다!) 그리고 각 전환을 관리하는 클래스를 생성하기 위해 상태 클래스를 하위 클래스로 처리하는 방법을 설명한다. "패턴에 리팩토링"(ISBN : 0321213351)를 참조하십시오

EDIT (2) : 그의 웹 사이트는 자신의 예를 들어, 클래스 다이어그램이 - 상태 패턴에서 http://www.industriallogic.com/xp/refactoring/alteringConditionalsWithState.html

alt text

+0

설명해 주셔서 감사합니다. 공유 상태 객체는 어떻습니까? – peterwkc

+0

나는 어떻게 그리고 어떤 상황에서 플라이급과 상태 패턴을 결합시킬 수 있는지 궁금합니다. – peterwkc