GOF州模式州过渡实施问题

时间:2010-07-02 09:37:46

标签: c++ design-patterns state transition

首先,任何人都可以解释当状态对象没有实例变量时如何共享状态对象?

本文取自GOF,第308页,第3项(后果部分):

  

可以共享状态对象。   如果状态对象没有实例变量 - 即状态变量   代表完全在他们的编码   类型 - 然后上下文可以共享一个   国家对象。当共享状态时   这样,他们基本上就是这样   轻量级。

任何人都可以解释这个文字吗?

其次,国家转型决策的方法是什么?我的意思是下一个国家的传播决定?

请帮忙。 谢谢。

2 个答案:

答案 0 :(得分:2)

段落基本上是说你将状态编码为单独的类 - 然后实例类型是“状态”,类不需要任何实例变量,因为它们的类型会编码你需要的所有信息。

例如,我想要有三个州“开放”,“活跃”和“关闭”。我可能会定义以下类:

abstract class State {};

class Open extends State {

  public Open() {}

}

class Active extends State {

  public Active() {}

}

class Closed extends State {

  public Closed() {}

}

-

另一种选择 - 我怀疑这是在GOF文本中暗示的轻量级组合将创建一个状态类,其中有一堆静态成员(每个状态一个)然后可以共享 -

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)

编辑(2):他的网站上有一个他的例子的类图 - http://www.industriallogic.com/xp/refactoring/alteringConditionalsWithState.html

alt text

答案 1 :(得分: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;
};

因此,您基本上将对调用对象的引用传递给state-object的每个方法。这样,状态对象能够在需要时更改调用者的状态。这个例子可能不是很漂亮,但我希望你能得到这个想法。