首先,任何人都可以解释当状态对象没有实例变量时如何共享状态对象?
本文取自GOF,第308页,第3项(后果部分):
可以共享状态对象。 如果状态对象没有实例变量 - 即状态变量 代表完全在他们的编码 类型 - 然后上下文可以共享一个 国家对象。当共享状态时 这样,他们基本上就是这样 轻量级。
任何人都可以解释这个文字吗?
其次,国家转型决策的方法是什么?我的意思是下一个国家的传播决定?
请帮忙。 谢谢。
答案 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
答案 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的每个方法。这样,状态对象能够在需要时更改调用者的状态。这个例子可能不是很漂亮,但我希望你能得到这个想法。