首先,谁能解释当状态对象没有实例变量时如何共享状态对象?
本文摘自 GOF,第 308 页,第 3 项(后果部分):
状态对象可以共享。如果状态对象没有实例变量——也就是说,它们所代表的状态完全以其类型编码——那么上下文可以共享一个状态对象。当以这种方式共享状态时,它们本质上是轻量级的。
谁能解释这段文字?
其次,状态转换决策的方法是什么?我的意思是决定传播哪个下一个状态?
请帮忙。谢谢。
首先,谁能解释当状态对象没有实例变量时如何共享状态对象?
本文摘自 GOF,第 308 页,第 3 项(后果部分):
状态对象可以共享。如果状态对象没有实例变量——也就是说,它们所代表的状态完全以其类型编码——那么上下文可以共享一个状态对象。当以这种方式共享状态时,它们本质上是轻量级的。
谁能解释这段文字?
其次,状态转换决策的方法是什么?我的意思是决定传播哪个下一个状态?
请帮忙。谢谢。
该段落基本上是说您将状态编码为单独的类 - 然后实例类型是“状态”并且类不需要任何实例变量,因为它们的类型编码了您需要的所有信息。
例如说我想要三个状态“打开”、“活动”和“关闭”。我可能会定义以下类:
abstract class State {};
class Open extends State {
public Open() {}
}
class Active extends State {
public Active() {}
}
class Closed extends State {
public Closed() {}
}
--
另一种选择-我怀疑这是与GOF文本中暗示的flyweight的组合,将创建一个状态类,其中可以共享一堆静态成员(每个状态一个)-
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
在状态模式中,您可以使用状态对象来表示对象的状态。这些状态对象代表某种状态,但它们自己没有任何可变状态。这意味着他们永远不会改变。因此,任意数量的对象可以同时使用同一个状态对象(即使来自不同的线程)。如果状态对象具有可变状态,则其他对象将不得不担心它们的状态对象从其他地方被更改。
许多其他对象对一个对象实例的使用可以看作是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;
};
因此,您基本上将对调用对象的引用传递给您的状态对象的每个方法。这样,状态对象能够在需要时更改调用者的状态。这个例子可能不是很漂亮,但我希望你能明白。