From: James Barrett on
Hi, I posted my questions to comp.patterns, but seeing that the recent
posts seem to be spam, I wanted to try posting here. I hope this is not
off topic, but I rally would like to discuss this.

I've been reading up on Design patterns from
various sources, including the GoF as well as some web sites and I'm
not sure at all which ones best fit my scenario. I am confused about how
to handle multiple States that can be active at the same time. Maybe I'm
making this more complicated that it really is, but I want to understand
the patterns and how they work.

I'll use an example of a game entity to explain my scenario.
Suppose I have a Creature class. I create a
State called Roam so that a creature object can move around aimlessly.
Now suppose the creature becomes Poisoned. The
poison will continue to alter the behavior of the creature over time. So
I create a State called Poisoned. I am confused about how to handle
these two states concurrently, because the creature can still Roam while
Poisoned. Even more complicated is the fact that eventually the creature
could move into a Hunting State. So then it would be Hunting while
Poisoned. How is this kind of scenario usually handled? Should Poisoned
be a unique State? Or maybe Poisoned falls under a completely different
design pattern? Maybe Decorator, or Flyweight, Or could I have nested
States? Should my creature class have multiple State pointers to handle
these States? Or should I create a RoamWhilePoisoned State and a
HuntingWhilePoisoned State? Or would Poisoned merely be a boolean
property of each State class? I'm really not sure how to proceed.

The more I think about it, the more I am leaning towards a linked-list
style of pattern for my States (Decorator?), where each state contains a
pointer to the next state. Adding a new state means it gets added to the
pointer in the last State in the list. Calling State->Execute() would
then run it's own logic and then call nextState->Execute(). Transitions
would be tricky, I would have to un-link the state being removed, and
link in the new state.

Would that be the way to do it? What are the pros and cons of doing it
this way? Is this an actual pattern as defined by the GoF or is this
really a combination of patterns?

Thanks,

Jim
From: Daniel T. on
James Barrett <xucaen(a)comcast.net> wrote:

> I've been reading up on Design patterns from various sources,
> including the GoF as well as some web sites and I'm not sure at all
> which ones best fit my scenario. I am confused about how to handle
> multiple States that can be active at the same time. Maybe I'm
> making this more complicated that it really is, but I want to
> understand the patterns and how they work.

You may very well be making it more complicated, but maybe not. :-)

> I'll use an example of a game entity to explain my scenario.
> Suppose I have a Creature class. I create a State called Roam so
> that a creature object can move around aimlessly. Now suppose the
> creature becomes Poisoned. The poison will continue to alter the
> behavior of the creature over time. So I create a State called
> Poisoned. I am confused about how to handle these two states
> concurrently, because the creature can still Roam while Poisoned.
> Even more complicated is the fact that eventually the creature
> could move into a Hunting State. So then it would be Hunting while
> Poisoned. How is this kind of scenario usually handled? Should
> Poisoned be a unique State? Or maybe Poisoned falls under a
> completely different design pattern?

The state pattern works well when you have a class where is seems that
in every method you are deciding behavior based on a particular field or
set of fields. To modify your example... Let's say we have a Creature
class and they can be drugged, there are a number of different drugs,
each with its own effect on the creatures behavior, multiple drugs have
added effect, and you want to be able to add new drugs easily in the
future... Would such a scenario fit what you are thinking about?

> Maybe Decorator, or Flyweight, Or could I have nested States?

Decorator is something that outsiders add to the object to change how it
reacts to stimuli. Flyweight is generally good when you are going to
have a large number of objects but they will be in just a few states
(and once created they don't change state.) I don't think Decorator
would be approprate. Flyweight might be approprate, but I don't think it
answers the question at hand...

> Should my creature class have multiple State pointers to handle
> these States? Or should I create a RoamWhilePoisoned State and a
> HuntingWhilePoisoned State? Or would Poisoned merely be a boolean
> property of each State class? I'm really not sure how to proceed.

As always, that depends... A situation where you have to add multiple
classes everytime you want to add a conceptual state is probably not
best (i.e., When I add the "Molting" state, will I then have to add a
"RoamWhileMolting", "RoamWhilePoisendAndMolting",
"HuntingWhilePoisendAndMolting", &c.?) Same with the boolean property of
each State class. Are you having to add a new boolean property to
multiple classes every time you add a state?

> The more I think about it, the more I am leaning towards a
> linked-list style of pattern for my States (Decorator?),

Sounds more like a chain of responsibility...

> where each state contains a pointer to the next state. Adding a new
> state means it gets added to the pointer in the last State in the
> list. Calling State->Execute() would then run it's own logic and
> then call nextState->Execute(). Transitions would be tricky, I
> would have to un-link the state being removed, and link in the new
> state.

Well, using the example I provided. Let's say the creature moves, and
how far it moves depends in part on what drugs are affecting it, some
make it go faster, some make it go slower... I would be inclined to do
something like this:

[Creature]<>--->*[Drug]

Where Drug has a bunch of sub-classes, one for each type of drug. The
creature would iterate through all the drugs affecting it, calling
each.affectSpeed( baseSpeed );

> Would that be the way to do it? What are the pros and cons of doing
> it this way? Is this an actual pattern as defined by the GoF or is
> this really a combination of patterns?

The idea you are thinking of would be a combination of State and Chain
of Responsibility I think.
From: James Barrett on
Stefan Ram wrote:
> James Barrett writes:
>> I am confused about how to handle multiple States that can be
>> active at the same time.
>
> A system might be in a single state at any instant of time.
>

That's what I always thought. So, perhaps my Creature example by having
Roam and Poisoned at the same time are not states at all.


> The set of all states of a system usually has more than
> one element, because otherwise the concept of state is useless.
>

I'm not sure what that means.


> A state is like a value, so it usually is not said to
> be �active�. I take this �active� to mean that this
> is the state of its system at the current instance.
>

Yes, that is what I meant, the state at the current instance. I
apologize for not using better terms.


> But you can always rename your states to �substates� and
> investigate a new set of states that is the power set
> of the set of substate. Then, a state { s(0), s(1), ... s(n-1) }
> is a set of substates.

Are you saying that I could have a set of substates, and that the set
itself is considered to be a single state? I think that when one of the
substates transitions, I would need to search the set for the substate,
end that substate, and then remove it from the set. Then I would need to
add the new substate to the set.


>
> class Creature
> { private boolean isHunting;
> private boolean isRoaming;
> ... }
>
> I do not get the problem. Is something wrong with this
> simple approach?


I am learning how to do this in an Object Oriented way. Using boolean
variables is not very extenisble. I would need to change Creature every
time I added a new substate. By using objects as substates, Creature
never has to be changed again when new substates are added.


>
> But you should try to keep things as simple as possible and
> refrain from run-time flexibility whenever a static approach
> is sufficient.

If states or substates are going to transition randomly or transition
based on user input, would I not want a dynamic run-time approach?

>
> This is one approach to a field known as �object
> oriented design�.
>

Yes, I have heard of that somewhere, but can't seem to recall where. ;-)

(joking)


Thank you Stefan, you have given me something new to think about.
Perhaps my Creature example is not an example of State at all, but
rather some other design pattern. I would like to implement some type of
pluggable objects so that the system can be extended later without
changing existing code. Do you think another design pattern would fit my
example?

Thanks!

Jim

From: Patrick May on
James Barrett <xucaen(a)comcast.net> writes:
> I'll use an example of a game entity to explain my scenario.
> Suppose I have a Creature class. I create a State called Roam so
> that a creature object can move around aimlessly. Now suppose the
> creature becomes Poisoned. The poison will continue to alter the
> behavior of the creature over time. So I create a State called
> Poisoned. I am confused about how to handle these two states
> concurrently, because the creature can still Roam while
> Poisoned. Even more complicated is the fact that eventually the
> creature could move into a Hunting State. So then it would be
> Hunting while Poisoned. How is this kind of scenario usually
> handled? Should Poisoned be a unique State? Or maybe Poisoned falls
> under a completely different design pattern? Maybe Decorator, or
> Flyweight, Or could I have nested States? Should my creature class
> have multiple State pointers to handle these States? Or should I
> create a RoamWhilePoisoned State and a HuntingWhilePoisoned State?
> Or would Poisoned merely be a boolean property of each State class?
> I'm really not sure how to proceed.

What are you trying to achieve with these states? If your goal
is to allow the addition of new states and new behavior based on those
states without modification of the Creature class, to respect the Open
Closed Principle, in other words, then it would make sense to maintain
an extensible set of states associated with each Creature instance.
New functionality can then just check the state, or property, list to
determine the appropriate behavior.

A more interesting question is how to modify existing behavior
based on new states that didn't exist when the original behavior was
implemented. For example, if Poisoned is a new possible attribute of
a Creature and if poisoned creatures are less successful when hunting,
the hunt() method needs to somehow take that into account.

Solving this in the general case is non-trivial. Your focus on
states suggests that you may be driving your design from a data
structure perspective. If that's the case, you might get some insight
by focusing on the behaviors of your system and introducing state-like
attributes only as and when required by the desired behavior.

Regards,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc. | Large scale, mission-critical, distributed OO
| systems design and implementation.
pjm(a)spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA)
From: James Barrett on
Patrick May wrote:

> Solving this in the general case is non-trivial. Your focus on
> states suggests that you may be driving your design from a data
> structure perspective.

My focus seems to be on State because I thought this was a State
problem. I am beginning to wonder if my example is in fact an example of
State or something else.

> If that's the case, you might get some insight
> by focusing on the behaviors of your system and introducing state-like
> attributes only as and when required by the desired behavior.
>

So in other words, modify the Creature class and/or existing State
classes to add new behaviors? I'm concerned that if I introduce some new
behaviors later, I will have many classes to modify.

I think my biggest confusion is deciding what pattern or structure it is
that controls behavior when there seem to be more than one State
(property or attribute?) controlling that behavior. I keep reading that
you can have only one State at a time, but that seem to be not true. So
either there is more to State than what I have read, or my example is
not one of State. Is Poisoned really a State? I can see that in the
future there could be others like Hungry, Injured, Sad, Angry.. and
possibly more. Are those really States or what are they?


Jim