GOF状态模式状态转换实现问题

发布于 2024-09-07 18:51:45 字数 295 浏览 2 评论 0原文

首先,谁能解释当状态对象没有实例变量时如何共享状态对象?

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

状态对象可以共享。 如果状态对象没有实例变量 - 即它们的状态 代表完全编码在他们的 type - 那么上下文可以共享一个 状态对象。当状态共享时 这样一来,它们本质上就是 蝇量级。

谁能解释一下这段文字吗?

其次,国家过渡决策的途径是什么?我的意思是决定传播哪个下一个状态?

请帮忙。 谢谢。

Firstly, can anyone explain how a state object can be shared when the state object has no instance variables ?

This text is taken from GOF, page 308, item 3 (consequences section):

The state object can be shared.
If state objects have no instance variabkes - that is, the state they
represent is encoded entirely in their
type - then contexts can share a
state object. When states are shared in
this way, they are essentially
flyweight.

Can anyone explain this text ?

Secondly, what are the approaches to the state transition decision? I mean the decision of which next state to propagate?

Please help.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尸血腥色 2024-09-14 18:51:45

在状态模式中,您可以使用状态对象来表示对象的状态。这些状态对象代表某种状态,但它们自己没有任何可变状态。这意味着它们永远不会改变。因此,任意数量的对象可以同时使用相同的状态对象(甚至来自不同的线程)。如果状态对象具有可变状态,其他对象将不得不担心它们的状态对象被从其他地方更改。

许多其他对象实例对一个对象实例的使用可以被视为 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;
};

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

In the state pattern you have an represent the state of an object by using state-objects. These state-objects represent a certain state, but they do not have any mutable state of their own. This means they never change. Therefore, any number of objects can use the same state-object at the same time (even from different threads). If the state-object had mutable state, other objects would have to worry about their state-object being changed from elsewhere.

The using of one object instance by many others can be seen as an instance of the flyweight-pattern.

As for the second part of your question, here is an example:

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;
};

So you basically pass a reference to the calling object to every method of your state-object. This way, the state-object is able to change the state of the caller when needed. This example might not be very beautiful, but I hope you get the idea.

若无相欠,怎会相见 2024-09-14 18:51:45

该段落基本上是说,您将状态编码为单独的类 - 那么实例类型就是“状态”,并且类不需要任何实例变量,因为它们的类型编码了您需要的所有信息。

例如,我想要三种状态“打开”、“活动”和“关闭”。我可能会定义以下类:

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

替代文字

The paragraph is basically saying that you encode your states as individual classes - then the instance type is the "state" and the classes don't need any instance variables because their type encodes all the information you need.

E.g say I want to have three states "Open", "Active" and "Closed". I might define the following classes:

abstract class State {};

class Open extends State {

  public Open() {}

}

class Active extends State {

  public Active() {}

}

class Closed extends State {

  public Closed() {}

}

--

Another option - I'd suspect this is the combination with flyweight being hinted at in the GOF text would be to create a state class which a bunch of static members (one for each state) which can then be shared -

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");

}

I had to go digging to remind myself of how all this stuff worked in detail. Kerievsky has a good description of this (I've heavily borrowed from one of his examples above!) and how the state transitions can be handled by sub-classing from the state class, to create classes that manage each transition. See "Refactoring to Patterns" (ISBN: 0321213351)

EDIT(2): His web site has a class diagram for his example - http://www.industriallogic.com/xp/refactoring/alteringConditionalsWithState.html

alt text

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文