{"id":17274483,"url":"https://github.com/idugalic/axon-statemachine-demo","last_synced_at":"2025-10-08T15:32:43.380Z","repository":{"id":56145846,"uuid":"249190301","full_name":"idugalic/axon-statemachine-demo","owner":"idugalic","description":"Axon Finite State Machine Demo","archived":false,"fork":false,"pushed_at":"2024-08-26T17:33:52.000Z","size":51,"stargazers_count":10,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-27T22:07:13.290Z","etag":null,"topics":["axonframework","ddd","fsm","oop","spring-boot"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idugalic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-22T13:34:19.000Z","updated_at":"2023-06-15T02:19:10.000Z","dependencies_parsed_at":"2022-08-15T13:31:24.312Z","dependency_job_id":null,"html_url":"https://github.com/idugalic/axon-statemachine-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idugalic%2Faxon-statemachine-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idugalic%2Faxon-statemachine-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idugalic%2Faxon-statemachine-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idugalic%2Faxon-statemachine-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idugalic","download_url":"https://codeload.github.com/idugalic/axon-statemachine-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248846333,"owners_count":21170951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axonframework","ddd","fsm","oop","spring-boot"],"created_at":"2024-10-15T08:54:01.784Z","updated_at":"2025-10-08T15:32:43.301Z","avatar_url":"https://github.com/idugalic.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [projects](http://idugalic.github.io/projects)/axon-statemachine-demo\n\nThis demo application demonstrate the usage of inheritance and polymorphism for making the concept of the finite state machine more explicit in your design.\n\n### Procedural way\nTake for example the concept of `Order` which is demonstrated in this example. The `Order` aggregate usually transition through many states, lets name some: NEW/CREATED, PAYED, DELIVERED. \nThe intuitive approach that comes into mind first is to handle states \u0026 transitions through simple `if else`. \nBut this approach does not scale, with every new state / transition addition / deletion, you need to change the big block of `if else / switch` statements that drive the whole logic.\n\n### `State` pattern\nState pattern is one of the behavioural design patterns devised by Gang Of Four. In this pattern, the concerned object holds internal state which can change \u0026 the object’s behaviour changes accordingly.\nThis pattern is better than the basic `if else / switch` based approach in the way that here you think about decomposing your application process into states \u0026 divide behaviours into multiple states, but since transitions are implicitly handled by states themselves, this method is not scalable and in real life you might end up violating `Open Closed — Open for extension \u0026 closed for Modification`.\n\n### Finite State Machines\nFinite State Machines (FSM, or in the context of this post, simply \"State Machines\") are a methodology for modeling the behavior of an entity with an established lifecycle. The lifecycle is defined by an enumerated set of states known at the time of implementation (this is where the term \"finite\" comes from).\n\n- For our `Order` we will use `Order*Created*` state aggregate. This is initial state and adding items to an order (for example) can only happen in this state. You are able to Cancel, and transit to `Order*Canceled*`.\n\n- Each state can transition between zero-or-more possible states, including returning to previous states. State transitions are executed by external stimuli (commands/events).\n\n- From `Order*Created*` you can transition to `Order*Payed*`. In `Order*Payed*` state you should not be able to add more items to the order, so these command handlers will be omitted in this case. You are able to Cancel, and transit to `Order*Canceled*`\n\n- From `Order*Payed*` you can transition to `Order*Delivered*`. In `Order*Delivered*` state you should NOT be able to add more items to the order, so these command handlers will be omitted in this case. You are NOT able to Cancel (`OrderCancellationRefusedEvent`)\n\n![Order State Machine](.assets/state-machine.svg)\n\n```puml\n@startuml\nskinparam state {\n  StartColor DarkGreen\n  EndColor DarkRed\n  BackgroundColor LightBlue\n  BackgroundColor\u003c\u003cWarning\u003e\u003e Olive\n  BorderColor Red\n}\nhide empty description\n\n[*] --\u003e OrderCreated\nOrderCreated --\u003e OrderPaid\nOrderCreated --\u003e OrderCanceled\nOrderPaid -\u003e OrderDelivered\nOrderPaid -\u003e OrderCanceled\nOrderDelivered --\u003e [*]\nOrderCanceled --\u003e [*]\n@enduml\n```\n\nThe [Finite-State-Machine pattern](https://en.wikipedia.org/wiki/Finite-state_machine) is a formalization of an entity's life cycle and thus, forces us to think about our models in terms of behavior. The consequence is that we tend to design better systems when we use the pattern. The process of discovery helps us identify the behaviors of each state. Behaviors expand into actions or \"intents\" clients can request from the entity. State transitions indicate events that need to be published.\n\nAxon Framework fits very good here. Some of the Axon features used in this demo are:\n\n - [aggregate polymorphism](https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate-polymorphism)\n - [aggregate creation from another aggregate](https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate-creation-from-aggregate)\n - [`markDeleted()`](https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate#aggregate-lifecycle-operations)\n \nEach transition will mark the current aggregate (state) instance as deleted and it will create a new instance of the next aggregate (state).\nTransition is explicit, and Axon may improve this by extending the API with transition concept, to make our life easier in the future.\n \n## Development\n\nThis project is driven using [maven].\n\n### Run Axon Server\n\nYou can [download](https://download.axoniq.io/axonserver/AxonServer.zip) a ZIP file with AxonServer as a standalone JAR. This will also give you the AxonServer CLI and information on how to run and configure the server.\n\nAlternatively, you can run the following command to start AxonServer in a Docker container:\n\n```\n$ docker run -d --name axonserver -p 8024:8024 -p 8124:8124 axoniq/axonserver\n```\n\n### Run locally\n\nYou can run the following command to start your project locally:\n\n```\n$ ./mvnw spring-boot:run\n```\n\n### Run tests\n\nThis project comes with some rudimentary tests as a good starting\npoint for writing your own. Use the following command to execute the\ntests using Maven:\n\n```\n$ ./mvnw test\n```\n\n## References\n\n- https://rclayton.silvrback.com/use-state-machines\n- https://en.wikipedia.org/wiki/Finite-state_machine\n---\nCreated with :heart: by [Ivan Dugalic](https://idugalic.github.io/)\n\n[maven]: https://maven.apache.org/ (Maven)\n[axon]: https://axoniq.io/ (Axon)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidugalic%2Faxon-statemachine-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidugalic%2Faxon-statemachine-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidugalic%2Faxon-statemachine-demo/lists"}