Skip to content

203: Finite state machine pattern #1247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
115498b
Create component.urm.puml
hrighter May 6, 2020
efd1f46
Create App.java
hrighter May 6, 2020
9db533e
Add files via upload
hrighter May 6, 2020
ea1180c
Add files via upload
hrighter May 6, 2020
d725caa
Add files via upload
hrighter May 6, 2020
127527d
Add files via upload
hrighter May 6, 2020
3c35cdc
Create AppTest.java
hrighter May 6, 2020
76b3a73
Add files via upload
hrighter May 6, 2020
17e3e47
Update README.md
hrighter May 6, 2020
2424fc0
Update README.md
hrighter May 24, 2020
c4de5d4
Update pom.xml
hrighter May 24, 2020
5382562
Update App.java
hrighter May 24, 2020
ee60881
Update BjornGraphicsComponent.java
hrighter May 24, 2020
6d277bd
Update BjornInputComponent.java
hrighter May 24, 2020
d59f5aa
Update BjornPhysicsComponent.java
hrighter May 24, 2020
ae15aab
Update Component.java
hrighter May 24, 2020
c08896a
Update App.java
hrighter May 24, 2020
adb9bda
Delete App.java
hrighter May 24, 2020
f9f9291
Delete BjornGraphicsComponent.java
hrighter May 24, 2020
6b9506c
Delete BjornInputComponent.java
hrighter May 24, 2020
cc14e60
Delete BjornPhysicsComponent.java
hrighter May 24, 2020
e18495f
Delete Component.java
hrighter May 24, 2020
14061d8
Delete GameObject.java
hrighter May 24, 2020
6e1e1aa
Delete GraphicsComponent.java
hrighter May 24, 2020
435e7fc
Delete InputComponent.java
hrighter May 24, 2020
0f586a2
Delete PhysicsComponent.java
hrighter May 24, 2020
fb39985
Create App.java
hrighter May 24, 2020
eb72310
Update App.java
hrighter May 24, 2020
b6c54b5
Update App.java
hrighter May 24, 2020
ce89d74
Create BjornGraphicsComponent.java
hrighter May 24, 2020
4565b89
Create BjornInputComponent.java
hrighter May 24, 2020
6d0da62
Create BjornPhysicsComponent.java
hrighter May 24, 2020
31cbbe1
Create Component.java
hrighter May 24, 2020
a904f00
Create GameObject.java
hrighter May 24, 2020
0a523ae
Create GraphicsComponent.java
hrighter May 24, 2020
44849ba
Create InputComponent.java
hrighter May 24, 2020
4eb0d15
Create PhysicsComponent.java
hrighter May 24, 2020
e81741b
Delete AppTest.java
hrighter May 24, 2020
0216f74
Delete UpdateTest.java
hrighter May 24, 2020
87ab3a9
Create AppTest.java
hrighter May 24, 2020
ecfd38b
Create UpdateTest.java
hrighter May 24, 2020
7b58d27
Update pom.xml
hrighter May 24, 2020
35f86a7
Merge branch 'master' into master
hrighter May 24, 2020
9dc7df8
fix errors
May 30, 2020
dc69a28
finite state machine design pattern
May 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions finite-state-machine/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: pattern
title: Finite state machine
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
title: Finite state machine
title: Finite State Machine

folder: Finite-state-machine
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
folder: Finite-state-machine
folder: finite-state-machine

permalink: /patterns/Finite-state-machine/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
permalink: /patterns/Finite-state-machine/
permalink: /patterns/finite-state-machine/

categories: Behavioral
tags:
- Decoupling
---

## Intent
It represents a mathematical model of a finite number of states and their transitions and actions,
and is an efficient programming method within a logical unit. Make the program logic clear and easy
to understand.


## Applicability
Use the Finite-state-machine pattern when
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use the Finite-state-machine pattern when
Use the Finite State Machine pattern when


* There are finite state for our model or software.


## Credits

* [State Machine Design Pattern](http://community.wvu.edu/~hhammar//rts/adv%20rts/statecharts%20patterns%20papers%20and%20%20examples/paper%20on%20state%20pattern%20B31-full.pdf)
66 changes: 66 additions & 0 deletions finite-state-machine/etc/finite-state-machine.urm.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@startuml
package com.iluwatar.finite.state.machine {
class App {
+ App()
+ main(args : String[]) {static}
}
class Context {
- state : State
+ Context(state : State)
+ getState() : State
+ request(event : Event)
+ setState(state : State)
}
class CoolState {
+ CoolState()
- Cool()
- Stop()
+ handle(context : Context, event : Event)
}
enum Event {
+ MOVING_ON_OFF {static}
+ MOVING_RUN {static}
+ valueOf(name : String) : Event {static}
+ values() : Event[] {static}
}
class OffState {
+ OffState()
- Start()
+ handle(context : Context, event : Event)
}
class OnState {
+ OnState()
- Cool()
- Stop()
+ handle(context : Context, event : Event)
}
class RunState {
+ RunState()
- cool_down()
+ handle(context : Context, event : Event)
- stop()
}
class StandState {
+ StandState()
+ handle(context : Context, event : Event)
- start_running()
- start_walking()
}
interface State {
+ handle(Context, Event) {abstract}
}
class WalkState {
+ WalkState()
+ handle(context : Context, event : Event)
- start_running()
- stop()
}
}
Context --> "-state" State
CoolState ..|> State
OffState ..|> State
OnState ..|> State
RunState ..|> State
StandState ..|> State
WalkState ..|> State
@enduml
45 changes: 45 additions & 0 deletions finite-state-machine/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

The MIT License
Copyright © 2014-2019 Ilkka Seppälä

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.23.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>finite-state-machine</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.iluwatar.finite.state.machine;

/**.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**.
/**

* This model named finite state machine model, which uses finite state machine to
* implement one thing that pull out all the states, events and actions, and manage
* the complex state migration logic uniformly.
* <p></p>
* In this demo, I create a scenario that there is a game character, who has three states.
* States: Standing;Walking;Running
* And also there are two events, which means you can create requests to control it.
* Events: MOVING_ON;MOVING_OFF
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the code however I see events such as MOVING_ON_OFF and MOVING_RUN?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe these events are not the easiest to understand. How about a different system like increasing and decreasing movement? From standing to walking to running and vice versa.

* In this demo I use state pattern to implement this FSM pattern. For the meaning of every class,
* refer to the class's Javadoc.
*/
public class App {
/**.
* Launcher of this demo.
* @param args is default for main method.
*/
public static void main(String[]args) {
var initState = new StandState();
var context = new Context(initState);

context.request(Event.MOVING_ON_OFF);
context.request(Event.MOVING_RUN);
context.request(Event.MOVING_ON_OFF);
context.request(Event.MOVING_ON_OFF);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.iluwatar.finite.state.machine;

/**.
* This class is a context for the State.
* It defines the State that we focus on.
*/
public class Context {
private State state;

/**.
* Constructor for Context.
* @param state is state data.
*/
public Context(State state) {
setState(state);
}

/**.
* getter for state.
* @return state of this context.
*/
public State getState() {
return state;
}

/**.
* setter for state.
* @param state is a state data
*/
public void setState(State state) {
this.state = state;
}

/**.
* request method for an event, then it will call handle method.
* @param event is an event.
*/
public void request(Event event) {
state.handle(this,event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.iluwatar.finite.state.machine;

/**.
* This enum event is the event for the game character.
*/
public enum Event {
//Event for the game character moving or stop moving
MOVING_ON_OFF,
//Event for the game character run.
MOVING_RUN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.iluwatar.finite.state.machine;

/**.
* A running state for the game character.
*/
public class RunState implements State {
/**.
* This method is a handler for event.
* @param context is context data.
* @param event is an event.
*/
@Override
public void handle(Context context, Event event) {
switch (event) {
case MOVING_ON_OFF:
context.setState(new StandState());
stop();
break;
case MOVING_RUN:
context.setState(new WalkState());
cool_down();
break;
default:
break;
}
}

/**.
* A method which simulates Game character stop.
*/
private void stop() {
System.out.println("Stop running! Game character is standing now!");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use logger for outputting. Check elsewhere too.

}

/**.
* A method which simulates Game character change from run to walk.
*/
private void cool_down() {
System.out.println("Stop running! Game character is walking now!");
}
}
Loading