views:

101

answers:

2

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.

+2  A: 

Hi

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

Paddy Fagan
Thanks for your explanation. How about the shared state object ?
peterwkc
I wonder how and in what situation we can combine flyweight with state pattern.
peterwkc
A: 

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.

Space_C0wb0y
The using of one object instance by many others can be seen as an instance of the flyweight-pattern.I don't get this.
peterwkc
Then you should read up on the flywheigt pattern, because that is what it is all about.
Space_C0wb0y
I understand flyweight but i don;t know how it is related to state pattern.
peterwkc
Flyweight is about sharing one big object between many small ones. The big one does not have mutable state, so there are no conflicts.
Space_C0wb0y