-
Notifications
You must be signed in to change notification settings - Fork 17
Home
Welcome to the grox wiki!
Grox comes with 2 samples to demonstrate how to use it w/o Rx java. Please refer to the samples for a concrete example of how to use Grox.
Grox terminology is highly & freely inspired by Redux, Flux and this nice scholar article.
A state can be any Java class (typically a pojo).
A state describes the state of your Application / UI. It is the model that describes what should be represented on screen. Grox doesn't not impose any constraint of any kind on the state classes. Though, we highly recommend using a solution to use immutable states as they provide with more safety and a better traceability of state changes (see the README for alternatives).
Developers can organize their state as desired. For instance, it can be a good idea for a complex application to split the state into UI State, App State, etc.
States are stored in stores, and manipulated by actions.
In Grox, an action in charge of a single task:
produce a new state out of an old state
We strongly recommend that actions are pure functions: they should:
- be testable;
- be side-effect free (no network calls, no I/O, etc...);
- not have dependencies or their dependencies should be pure;
Grox actions are similar to Redux actions.
Grox actions are passed to the store via the Store#dispatch()
method.
A store basically holds the state and provides a listener for state changes (in Grox-Rx, this listener becomes an observable).
The store will:
- hold a reference to the current state (you should avoid copying it so that the store is the single source of truth).
- provide a
dispatch
methods that accepts actions. Each action will produce a new state that will become the new current state. The old state is discarded (you can still save it for history purposes using middlewares for instance). - notify listeners (or an Rx-Observable) of state changes.
Stores also accept middlewares.
A command is a sequence of actions. As opposed to actions, commands:
- can have side effects
- are not pure, generally speaking
- are used to perform app's duties such as I/O, heavy computation relying on dependencies, etc.
In Grox, we decided to implement commands using Rx. Commands are a simple Observable, i.e. a sequence of actions over time.
We don't provide a Rx-free implementations of commands. Though their interface would be pretty simple, we decided not to include such an Rx-free implementation as it would not be useful in real world apps (and lead to duplicate maintenance). But for specification purposes, here is what a command has to do:
public interface Command {
/** Notifies an action listener of all actions to be performed during the sequence. */
void toActions(ActionListener actionListener);
/** Allows to cancel the sequence at any point in time. */
void cancel();
}
Middlewares are part of a store infrastructure and add some capabilities to store. Typical examples include:
- logging states and state changes
- logging actions
- implement undo/redo or time travel debugging
- crash reporting
- state persistence
Middlewares are organized as a chain, very similar to the interceptor chain of OkHttp. Each interceptor is called in turn when an action is executed.
The order of execution of the middlewares matches the order in which they are added to a store: if a store is defined as: new Store(initalState, middleware1, middleware2)
, then the following sequence will take place for each action being dispatched by the store:
- middleware1 until the call to
chain#proceed
- middleware2 until the call to
chain#proceed
action# execute
- middleware2 after the call to
chain#proceed
- middleware1 after the call to
chain#proceed
Middlewares are very similar to Redux middlewares.