4

Is there a design pattern (like visitor, strategy, state, etc.), or some other design principle, for helping to design a good solution for simulating a flow in states for an entity, for example a Task entity.

A Task starts in New status, then progresses to BeingHandled status, then WaitingForApproval and then it can either be moved to Finished or NotApproved, which is essentially back to BeingHandled with additional info, saying that it is back from WaitingForApproval.

So in general we have some general flow, and then we can have some inner flow within it.

Thanks,

ashilon

Fuhrmanator
  • 11,459
  • 6
  • 62
  • 111
ashilon
  • 1,791
  • 3
  • 24
  • 41

3 Answers3

6

It's not a pattern but a concept: finite-state machine.

In summary, it's a state machine which can only have an active state in a moment in time.

Check what Wikipedia article says on its first paragraph:

A finite-state machine (FSM) or finite-state automaton (plural: automata), or simply a state machine, is a mathematical model of computation used to design both computer programs and sequential logic circuits. It is conceived as an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition; this is called a transition. A particular FSM is defined by a list of its states, and the triggering condition for each transition.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • OK good, but does this concept allow state transitions in both known order an arbitrary orders? Like I have specified that at some state, _**WaitingforApproval**_, it can either be transitioned to the next state or be transitioned to a previous state, which means that it's not always a sequential flow, it can be broken and moved back to a previous state. And i wonder where is all this knowledge of the states order is defined, and who is checking the conditions to transition to another state? is it the business object itself, i.e. the Task class or some other object? – ashilon Nov 10 '15 at 12:10
  • 2
    @ashilon You're asking too many questions and you're doing it in a comment. A state machine can go forward or backward depending on some given conditions. I mean, I don't see why a state machine can't do what you want to do. About how to store this in a durable storage, or whatever, I believe that you should ask a new question but you should perform your own investigation and ask for concrete issues :D – Matías Fidemraizer Nov 10 '15 at 14:29
  • Matias, thank you. I have now a strong believe that going with the State pattern would be the right choice for me. Cheers :) – ashilon Nov 11 '15 at 07:30
  • 1
    @ashilon State pattern is almost a state machine, you're not going to walk another road if you like more "state pattern" :D – Matías Fidemraizer Nov 11 '15 at 10:44
  • Wow, I didn't know that. I thought that they were the same thing. And so used them interchangeably. From your comments, I now realize that the State pattern is really an implementation of the State Machine concept (and correct me if I'm wrong). Thanks a lot for clarifying that. – ashilon Nov 11 '15 at 13:14
3

There is a pattern for managing statuses known as State Design Pattern - State Pattern on Wikipedia.

It basically represents the various ovals/states in a finite state machines as subclasses of a base State Class/Interface. In your case the states would be BeingHandled, WaitingForApproval, Finished, NotApproved etc.

There will be a state-handler class which will hold the current state(currentState instance variable) of the system, which will be a reference to base State Class/Interface but will hold one of the sub-states depending on the current state the system is in.

All the events which can happen on all states together will form a superset of methods in the State Base class. Those states which 'can' handle those events will write the necessary logic on invocation of those events. The rest of the events will be IllegalOperations for that state. These events basically change the currentState from one to another state in the state-handler class.

Also, note that you need to have instances of different states available for assigning to the state-handler's currentState attribute. You can make a factory for these states.

I hope I was able to explain it to you...its much easier on a whiteboard though...do let me know if anything is not clear.

To add to the above explanation, I have added a detailed article explaining state design pattern on my blog - http://www.javabrahman.com/design-patterns/state-design-pattern-in-java/

Dhruv Rai Puri
  • 1,335
  • 11
  • 20
  • Thank you Dhruv Rai Puri, your explanation is very good. But my question goes beyond the State design pattern. I was asking more in terms of architecture, what would be the right design for my problem. And by the comments so far, the State design pattern might be the most appropriate, although if it might not be the right design, then it would time wasted, and that's exactly what i'm trying to prevent. Thanks again. – ashilon Nov 10 '15 at 14:17
1

A Task starts in New status, then progresses to BeingHandled status, then WaitingForApproval and then it can either be moved to Finished or NotApproved which is essentially back to BeingHandled with additional info, saying that it is back from WaitingForApproval.

As others have mentioned, the Finite State Machine (FSM) approach is a way to model the behavior you desire. The states are basically the statuses you mentioned, but you also need to define the transitions that get the Task from one state to the next.

Before you start coding, I suggest you sketch the FSM and show it to your colleagues (or customers) to confirm that the states and transitions are consistent with how things work in the problem you're trying to solve. It's easier to change the diagram on a whiteboard than to change the code. I use PlantUML with PlantText.com to produce diagrams quickly, but a whiteboard is even quicker.

I took the liberty of starting something (I added somewhat arbitrary transitions) but it should make some sense. You might be able to remove some states, e.g., New and BeingHandled might be the same state if you can't really think of a transition that get the system from one to the other. Similarly, BeingHandled and WaitingForApproval could also be the same state if all you're doing is approving/rejecting tasks. Try to keep it as simple as possible.

Finite state machine for Task objects in PlantUML

Finally, when you're going to code this up, you don't have to use the State Pattern (as some have suggested). It adds complexity to your solution since every state is a separate class (sometimes that can be useful, but if you have a lot of states or transitions, it gets hard to maintain). FSMs have been around a long time, and can easily be coded using a two-dimensional array. Check the question at How to implement a FSM - Finite State Machine in Java or ask Google.

Community
  • 1
  • 1
Fuhrmanator
  • 11,459
  • 6
  • 62
  • 111