Top Banner
Flux Architecture with JavaFX Manuel Mauky @manuel_mauky
85

Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

May 22, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Flux Architecturewith JavaFX

Manuel Mauky@manuel_mauky

Page 2: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Manuel Mauky

Software Developer at Saxonia Systems AG

Living in Görlitz, Germany

JUG-Leader of JUG Görlitz

- Frontend Development (JSF, JavaFX, JavaScript)- Functional Programming

Page 3: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

What is Flux?

“Flux is the application architecture that Facebook uses for building client-side web applications.”

https://facebook.github.io/flux/

Page 4: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

What is Flux?

- Frontend architecture pattern

Page 5: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

What is Flux?

- Frontend architecture pattern

- Core idea: unidirectional data flow

Page 6: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

What is Flux?

- Frontend architecture pattern

- Core idea: unidirectional data flow

- Goal: easier understanding of what is happening in the

application

Page 7: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store - application state- logic- represents a business unit

Page 8: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

data flow

- View visualizes data from the Store

- When the data in the Store changes the View will update itself accordingly

Page 9: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

data flow

Page 10: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

data flow

Action - View generates “Actions” based on user interaction

- Action has a type and (optional) payload data

- similar to Command Pattern

Page 11: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Example: Actions

{type: "CREATE_USER_ACTION",payload: {

username: "Luise",email: "[email protected]"

}}

Page 12: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

Action

Dispatcher

- Dispatcher passes all Actions to all Stores

- Each Store decides if and how it will react to actions

Page 13: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Flux Architecture

- Store: no "setters" - can't be manipulated from the outside- explicit modelling of business actions- Dispatcher works synchronously: Actions are handled one at a time- Optional: dependencies between Stores → order of action handling can be

controlled

Page 14: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

Action

Dispatcher

ActionCreator

- ActionCreator: reusable function that creates actions

- used by View

Flux: Details

Page 15: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Example: ActionCreator

const createUser = (username, email) => {dispatch({

type: "CREATE_USER_ACTION",payload: {

username: username,email: email

}});

};

Page 16: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

How to handle async interactions? Like REST requests?

Store

View

Action

Dispatcher

ActionCreator

Page 17: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

How to handle async interactions? Like REST requests?

Store

View

Action

Dispatcher

ActionCreator Server

request

response

Page 18: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

How to handle async interactions? Like REST requests?

ActionCreator can be asynchronous

1. Dispatch Action "FETCH_DATA_STARTED"2. Get data from Server3. When data arrives → dispatch Action: "FETCH_DATA_SUCCESSFUL"4. If timeout or error happens → dispatch Action that represents error:

"FETCH_DATA_FAIL_TIMEOUT"

Page 19: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

const fetchUsers = () => {dispatch({type: "FETCH_USERS_STARTED"});

fetch("http://my.api.example.com/users").then(response => response.json).then(json => dispatch({

type: "FETCH_USERS_SUCCESSFUL",payload: json

}),error => dispatch({

type: "FETCH_USERS_FAILED"})

);};

Page 20: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

Actions

Dispatcher

Store Store

View

View View

View

View

View

View

Page 21: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

Action

Dispatcher

Page 22: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Store

View

Dispatcher

Action

Page 23: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Short introduction: React.JS

Page 24: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

var React = require("react");

var HelloWorld = React.createClass({render: function() {

return (<div>

<p>Hello World!</p></div>

);}

});

Page 25: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

import React from "react";

class HelloWorld extends React.Component {render() {

return (<div>

<p>Hello World!</p></div>

)}

}

Page 26: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

import React from "react";

const HelloWorld = () => (<div>

<p>Hello World!</p></div>

);

Page 27: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

import React from "react";

const HelloWorld = () => (<div>

<p>Hello World!</p></div>

);

// Usage<HelloWorld />

Page 28: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

import React from "react";

const HelloWorld = (props) => (<div>

<p>Hello {props.subject}</p></div>

);

// Usage<HelloWorld subject="World"/>

Page 29: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

class Hellos extends React.Component {render () {

<ul><li><HelloWorld subject="World" /><li><HelloWorld subject="Moon" /><li><HelloWorld subject="Sun" />

</ul>}

};

Composition

Page 30: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

class Greeter extends React.Component {constructor() {

this.state = { counter: 0 }}

count() {const oldValue = this.state.counter;this.setState({ counter: oldValue + 1 });

}render() {

return (<div>

<p>Value: {this.state.counter}</p><button onClick={this.count}>+</button>

</div>)

}}

Page 31: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

React.JS

- every state change leads to rerendering of the whole component (incl. subcomponents)

- kind of functional programming- easy programming model

Page 32: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

React.JS

- Virtual-DOM- not the "real" DOM is rerendered

but only the virtual DOM- efficient diff algorithm calculates

minimal necessary "real" DOM operations

- every state change leads to rerendering of the whole component (incl. subcomponents)

- kind of functional programming- easy programming model

Page 33: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Flux with React.JS

- parent component registers ChangeListener on Store- in the ChangeListener:

- get data from Store- pass data to setState method- component gets rerendered

Store

View

ChangeListener

Page 34: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Flux with JavaFX?

Page 35: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Naive Implementation: Do it the same way

Problems:

- JavaFX has no Virtual-DOM/Virtual-SceneGraph (at least there is no such API for developers)

- complete rerendering on every change is slow and inefficient- not fully declarative

Page 36: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

JavaFX is not fully declarativeReact:

const list = () => (<ul>

<li>Hello</li><li>World</li>

</ul>)

JavaFX:

<VBox fx:controller="Controller"><ListView fx:id="myList" />

</VBox>

class Controller {@FXML private ListView myList;

public void initialize() {myList.getItems().add("Hello");myList.getItems().add("World");

}}

Page 37: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Naive Implementation: Do it the same way

Problems:

- JavaFX has no Virtual-DOM/Virtual-SceneGraph (at least there is no such API for developers)

- complete rerendering on every change is slow and inefficient- not fully declarative

However:

- JavaFX is ready for Reactive Programming- data binding- reactive streams (RxJavaFX or ReactFX) // "ReactFX" has nothing to do with "React.JS"

Page 38: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Idea

- Stores use properties internally

- Stores provide read-only properties to the outside world

- View binds to read-only properties of the Store

- Action as classes (Command Pattern)

- Dispatcher as reactive stream

- Stores subscribe to Dispatcher stream

Page 39: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Example: Counter

Page 40: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class CounterStore {

private IntegerProperty counter = new SimpleIntegerProperty();

public ReadOnlyIntegerProperty counterValue() {return counter;

}}

Page 41: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class CounterView {

@FXMLprivate Label valueLabel;

@Injectprivate CounterStore store;

public void initialize() {valueLabel.textProperty().bind(store.counterValue());

}}

Page 42: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class IncreaseAction implements Action {

private final int amount;

public IncreaseAction(int amount) {this.amount = amount;

}

public int getAmount() {return amount;

}// equals & hashcode

}

Page 43: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

import org.reactfx.EventSource;import org.reactfx.EventStream;

public class Dispatcher {

private EventSource<Action> actionStream = new EventSource<>();

public void dispatch(Action action) {actionStream.push(action);

}

public EventStream<Action> getActionStream() {return actionStream;

}}

Page 44: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class CounterView implements View {

...

@FXMLpublic void increaseButtonPressed () {

Dispatcher.getInstance().dispatch(new IncreaseAction(1));}

}

Page 45: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class CounterStore {

private IntegerProperty counter = new SimpleIntegerProperty();

public CounterStore() {Dispatcher.getInstance()

.getActionStream()

.filter(a -> a.getClass().equals(IncreaseAction.class))

.map(a -> (IncreaseAction) a) // cast is needed

.subscribe(this::increase);}

private void increase(IncreaseAction action) {counter.set(counter.get() + action.getAmount());

}

public ReadOnlyIntegerProperty counterValue() {return counter;

}}

Page 46: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public abstract class Store {

protected <T extends Action> void subscribe(Class<T> type, Consumer<T> consumer) {

Dispatcher.getInstance().getActionStream().filter(a -> a.getClass().equals(type)).map(a -> (T) a).subscribe(consumer);

}}

Page 47: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

public class CounterStore extends Store {

private IntegerProperty counter = new SimpleIntegerProperty();

public CounterStore() {subscribe(IncreaseAction.class, this::increase);

}

private void increase(IncreaseAction action) {counter.set(counter.get() + action.getAmount());

}

public ReadOnlyIntegerProperty counterValue() {return counter;

}}

Page 48: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

@Testpublic void test() {

// givenassertThat(store.counter()).hasValue(0);

// whenDispatcher.getInstance().dispatch(new IncreaseAction(1));

// thenassertThat(store.counter()).hasValue(1);

}

Page 49: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Details, Benefits & Difficulties

Page 50: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Example: Todo List app

Page 51: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CheckBox behavior

Page 52: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

click

CheckBox behavior

when all items are checked,

the top checkbox should switch too

Page 53: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

clickCheckBox behavior

When the top checkbox is clicked,

all items should be checked/unchecked

Page 54: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CheckBox behavior

Page 55: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

click

CheckBox behavior

When all items are checked and

a single checkbox is clicked...

Page 56: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CheckBox behavior

When all items are checked and

a single checkbox is clicked,

the top checkbox should switch to unchecked

Page 57: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Top checkbox combines two tasks:

- shows status of items- manipulate status of all items

CheckBox behavior

Page 58: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

How to build this only by looking at the state?

CheckBox behavior

Page 59: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

How to build this only by looking at the state?

Flux: 2 distinct action types:

- ClickTopCheckboxAction- ClickItemCheckboxAction

CheckBox behavior

Page 60: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Stateful Views?

Page 61: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

- delete button is only visible on mouse over

Stateful Views?

Page 62: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

- delete button is only visible on mouse over- OnMouseOverAction? - OnMouseOverFinishedAction?

Stateful Views?

Page 63: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

- delete button is only visible on mouse over- OnMouseOverAction? - OnMouseOverFinishedAction?

or simply:

deleteButton.visibleProperty()

.bind(root.hoverProperty);

Stateful Views?

Page 64: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

Page 65: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening

Page 66: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening- Find out where a bug is located:

- Given a state in the Store: does the UI render correctly?- Given a state: when an action is incoming, does the state change as expected?- Given an user interaction: Is the correct action dispatched?

Page 67: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening- Find out where a bug is located:

- Given a state in the Store: does the UI render correctly?- Given a state: when an action is incoming, does the state change as expected?- Given an user interaction: Is the correct action dispatched?

- Easy testing of frontend code

Page 68: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening- Find out where a bug is located:

- Given a state in the Store: does the UI render correctly?- Given a state: when an action is incoming, does the state change as expected?- Given an user interaction: Is the correct action dispatched?

- Easy testing of frontend code- Undo/Redo is easier to implement

Page 69: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening- Find out where a bug is located:

- Given a state in the Store: does the UI render correctly?- Given a state: when an action is incoming, does the state change as expected?- Given an user interaction: Is the correct action dispatched?

- Easy testing of frontend code- Undo/Redo is easier to implement- Event Sourcing is easy to implement

Page 70: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Benefits

- No cascading updates → easier reasoning what's happening- Find out where a bug is located:

- Given a state in the Store: does the UI render correctly?- Given a state: when an action is incoming, does the state change as expected?- Given an user interaction: Is the correct action dispatched?

- Easy testing of frontend code- Undo/Redo is easier to implement- Event Sourcing is easy to implement- more functional development style (not fully functional though)

Page 71: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Similar Ideas

Page 72: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

Command Query Responsibility Segregation

Page 73: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

CommandModel

Frontend

QueryModel

Page 74: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

CommandModel

Frontend

QueryModel

Commands

Page 75: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

CommandModel

Frontend

QueryModel

Commands

Events

EventStore

Page 76: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

CommandModel

Frontend

QueryModel

Commands

Events

EventStore

Page 77: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

CommandModel

Frontend

QueryModel

Commands

Events

EventStore

Page 78: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

CQRS + Event Sourcing

Similarities:

- command pattern- unidirectional data flow

Differences:

- CQRS is an architecture pattern for whole application. Flux is "just" UI- stricter separation between "Changing Data" and "Showing Data"- other purposes: scaling different parts of application

Page 79: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Redux

Page 80: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Redux

- more functional version of Flux- Single Store contains whole state- Pure reducer function: (oldState, action) -> newState- really cool with React.JS

Page 81: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Redux

- more functional version of Flux- Single Store contains whole state- Pure reducer function: (oldState, action) -> newState- really cool with React.JS- However:

- Java isn't a functional language- immutable data structures missing :-(- declarative UI missing

Page 82: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Open Questions / Research to be done

- Virtual-SceneGraph? - Promising: https://github.com/tferi/templateFX

- declarative UI's for JavaFX inspired by React

- Only Scala at the moment

Page 83: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Open Questions / Research to be done

- Virtual-SceneGraph? - Promising: https://github.com/tferi/templateFX

- declarative UI's for JavaFX inspired by React

- Only Scala at the moment

- Use functional languages? Groovy? Kotlin? Frege?

Page 84: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

TodoMvcFX

- Like original TodoMVC but for JavaFX- Same application with different frameworks- Compare frameworks and patterns- https://github.com/lestard/todomvcFX- Contributions are welcome!

Page 85: Flux Architecture - RainFocus · Flux Architecture - Store: no "setters" - can't be manipulated from the outside - explicit modelling of business actions - Dispatcher works synchronously:

Q & A

Manuel Mauky

[email protected]://lestard.eu

@manuel_mauky

Example Code:https://github.com/lestard/FluxFX