views:

52

answers:

3

How can you go about modelling an object that can have multiple simultaneous states?

For example, you could have a person that's waiting for a bus. That's one state. But they could also be reading a newspaper while waiting for the bus. Furthermore, they could be thinking about something while reading the newspaper. They could also be sniffing their nose because they have a cold. That's a four states in all taking place at the same time.

+1  A: 

When the concepts are orthogonal (independent) then they can be simply modelled as independent values, e.g.

class Person
{
   Location location; // bus stop, home etc...
   Motion motion; // sitting, walking, running
   Topic thinkingAbout;
   boolean sniffing;
   boolean blinking;
   boolean breakingWind;
}

It's reasonable that a person can do all of these at once, so there are no constraints. That is, they can be sitting/walking/running at a given location (bus stop, home, work), they can at the same time be thinking about some topic, and could also be sniffing, blinking and doing other things at the same time.

Each substate itself is exclusive - a person can only be at one place, have one kind of motion, thinking about one thing.

When there are constraints, the same model can be used, but in conjunction with a validation framework to ensure the state is valid.

For example, if we added 'boolean sneezing'. When sneezing is true, then blinking should be true also, since it's not possible to keep your eyes open while sneezing. The validation model would encode this constraint.

Thinking in terms of states, the independent values can be modelled collectively as a single state by taking the cartesian product of each substate.

mdma
+1  A: 

Use an array to store all states the object is currently in.

MrBean.states = {
    "WaitingForBus",
    "ReadingNewspaper",
    "Sniffling",
    "ThinkingAboutPaintings"
};

How you model the states is entirely upto you. The above is a simple example where states are modeled by strings, and carry zero extra information.

Anurag
+2  A: 

States are often just steps in a process. Instead of representing them as values, represent the process itself as a class, and have it make decisions on what should be done, not just tell what state it is in.

In your case you would have multiple simultaneous processes going on, so your Person class would have an instance of DailyCommuteProcess, BodyClockProcess, and so on each of which will take care of corresponding functions.

This approach (encapsulating the state and the logic that acts on a state in a separate class, as opposed to making the consuming class look at the public properties and act), is known as the Tell, Don't Ask principle.

zvolkov