There are three things that are certain with any software development project:
- A complete and consistent set of requirements will not be captured before the design and coding starts.
- The requirements will change during the lifetime of the project.
- The user interface is more likely to change than any other part of the system.
ember-statecharts has been created to address many of the difficulties of client-side application development. Even with an ambitious framework like
Ember.js, client-side application development can get very complex and there are several reasons for this being the case:
client-side apps are stateful - client-side apps are a system that allows users to request data from someplace and manipulate it entirely on the user's client device. Application developers' job is to manage the UI-state created by the user interacting with the requested data in their applications and make sure to always display the correct representation of that state to their users.
We are building complex reactive systems because the representation of client-side state has to react continuously to internal and external events:
Modeling this behavior is very complex if not done explicitly. The usual way to develop client-side applications though is implicit. Developers usually develop code in an ad-hoc fashion by setting properties based on
actions on components and other objects that can hold state. This implicit modeling breaks down fast even for medium-level complexity. Components that implement their behavior implicitly are hard to reason about, hard to maintain, and hard to extend. [Horrocks 99]
Discussing behavior is very difficult with other stakeholders. There's no shared language between developers, designers, and other stakeholders like product owners. Thus a lot of requirements are left unidentified in the requirements phase of a development iteration - loading-states are often forgotten and nobody on the team really can answer questions about how the application should behave when certain events have happened in the application lifecycle - "What happens when the user loses the server connection during upload?" and similar are questions that come up during development but not before. This leads to frustration on teams and missed deadlines because so much of the implicit requirements have not been accounted for during the planning phase.
A way to deal with the difficulties of client-side application development is to use
statecharts to model your application's behaviors explicitly:
The behavior of a reactive system is really the set of allowed sequences of input and output events, conditions, and actions, perhaps with some additional information such as timing constraints.
Statecharts can be modeled explicitly and are executable. Instead of relying on implicit state management, you model behavior as an executable statechart configuration that makes it impossible for your application to behave in unexpected ways.
With Statecharts it is easy to understand and change existing behavior. Statecharts are easy to reason about, refine and maintain because states in statecharts can be extended and nested.
In addition to explicitly modeling behavior statecharts can be used to visualize modeled behavior and can thus be used to close a gap in client-side application development today where it is hard to discuss application behavior with other stakeholders. Statecharts can be used as an easy-to-understand shared language between stakeholders - designers, product owners, and developers.
Statecharts can be used as a modeling tool in the requirements phase, as an implementation tool in the coding phase, and as a debugging and documentation tool in the production phase of your application.
Modeling your application behavior explicitly via
ember-statecharts will give you documentation
of your application behavior for free. Statecharts can be visualized via the XState-visualizer
and you will have an easier time understanding components and user-flows by looking at them.
Visualizing statecharts also allows you to communicate about behavior with other stakeholders - designers, product owners, and fellow developers. Because you are modeling behavior explicitly with an executable statechart in your code there is now always up-to-date documentation of how components and other parts of your app behave.
You can step through your behavior with the XState-visualizer and have discussions about how your application behaves based on a visual language that everyone understands.
ember-statecharts provides a small Ember.js-specific wrapper around the fabulous
and widely-used XState-library. All of the powerful
XState are supported. The purpose of
ember-statecharts is to
make it easy to use
XState in an Ember.js application without having
to write the same boilerplate code over and over again.
ember-statecharts is not a contender to
ember-concurrency. Both addons can be used
ember-concurrency gives you a clean API to handle async interactions in
your code and will handle cleanup when components are destroyed. After modeling
the states in your components explicitly for some time you might even come to the conclusion
that the reason why
ember-concurrency is so great is that it models async interactions
explicitly. But async interactions with APIs are not the only complex reactive behavior you will
want to model in your applications explicitly. If you want to model a complex sign-up flow for example
it might include async interaction with your backend API but you will still want to model
the rest of the sign-up flow explicitly and
ember-statecharts will help you with that.
ember-statecharts can do all the things
ember-concurrency can do, but not the other way around.
If you so desire, you can continue using
ember-concurrency in combination with
ember-statecharts, but you will be surprised how far XState's invoking promises feature will get you.
[Harel 87] D. Harel, Statecharts: a visual formalism for complex systems, Science of Computer Programming, Volume 8, Issue 3, June 1987, Pages 231-274
[Horrocks 99] I. Horrocks, Constructing the User Interface with Statecharts, Addison-Wesley, 1999