Upload
open-knowledge-gmbh
View
458
Download
0
Embed Size (px)
Citation preview
Herbstcampus 2015 – Flux Application Architecture 2
Model View Controller im Web
ControllerModel View
ClientServer
Herbstcampus 2015 – Flux Application Architecture 3
Model View Controller im Web
ControllerModel View
ClientServer
DB ROUTER HTML
HTML
Herbstcampus 2015 – Flux Application Architecture 4
Model View Controller im Web
ControllerModel View
ClientServer
DB ROUTER HTML
HTML
Business
Logik
Herbstcampus 2015 – Flux Application Architecture 5
Model View Controller im Web
• Applikationsstatus: Entitäten der DB
• Statusänderung: • Per URL
• Per Form-Submit
• Kein Status im Browser• View ist „dumm“
• HTML = Server-Status
Herbstcampus 2015 – Flux Application Architecture 6
Model View Controller im Web
http://davidatlanta.com/
Herbstcampus 2015 – Flux Application Architecture 7
Model View Controller im Web
ControllerModel View
ClientServer
DBRESTful-
Service
HTML
JavaScript
HTML
JSON
Business
Logik
Herbstcampus 2015 – Flux Application Architecture 8
Model View Controller im Web
ControllerModel View
ClientServer
DBRESTful-
Service
HTML
JavaScript
HTML
JSON
ControllerModel View
Business
Logik
Herbstcampus 2015 – Flux Application Architecture 9
Model View Controller im Web
• JavaScript-MVC – Frameworks FTW
• Back to traditional MVC
Herbstcampus 2015 – Flux Application Architecture 10
Model View Controller
Controller Model Viewupdates
queries
notifies
user actions
Herbstcampus 2015 – Flux Application Architecture 11
Model View Controller
• Model:• Verhalten und Status einer Anwendung
• View:• Visuelle Repräsentation des Models
• Controller:• Interaktionen, Manipulation des Modells
Controller Model Viewupdates
queries
notifies
user actions
Herbstcampus 2015 – Flux Application Architecture 13
MVC in JavaScript
• MV* oder MVW• MVC, MVP, MVVM..
• BackboneJS: kein Controller
• AngularJS: MVVM
• ReactJS: nur View
Herbstcampus 2015 – Flux Application Architecture 14
MVC in JavaScript
• MV* oder MVW• MVC, MVP, MVVM..
• BackboneJS: kein Controller
• AngularJS: MVVM
• ReactJS: nur View
Separation of view and logic
Herbstcampus 2015 – Flux Application Architecture 15
MVC in JavaScript
Model View
Controller, Router, ..
observer
Herbstcampus 2015 – Flux Application Architecture 16
MVC in JavaScript
• Und außerdem:
• Entity-State
• Nicht mehr Vordergründig
• View braucht eigenen State
• UI-State
• Server-State
Herbstcampus 2015 – Flux Application Architecture 18
MVC – Facebooks‘ Probleme
Model View
View
View
View
Model
Model
Model
Controller
Herbstcampus 2015 – Flux Application Architecture 19
MVC – Facebooks‘ Probleme
Model View
View
View
View
Model
Model
Model
Controller Bidirektional!
Herbstcampus 2015 – Flux Application Architecture 20
MVC – Facebooks‘ Probleme
• Beispiel FB-Chat:
• View A: Liste aller Nachrichten,
ungelesene hervorgehoben
• View B: Anzahl ungelesener Nachrichten
Herbstcampus 2015 – Flux Application Architecture 21
MVC – Facebooks‘ Probleme
Model(thread model)
View
View
View
View
Model(unread thread count
model)
Model
Model
Herbstcampus 2015 – Flux Application Architecture 22
MVC – Facebooks‘ Probleme
• Komplexe Interaktionen• Einfaches Model-Update Massenänderungen
• Model triggers View, View triggers Model
• Zirkuläre Abhängigkeiten
• Kein Raum für neue Features
MVC does not scale © facebook
Herbstcampus 2015 – Flux Application Architecture 23
Flux
© fansshare.com
Excited for the
Flux-solution???
Herbstcampus 2015 – Flux Application Architecture 24
Flux ist…
• Architekturvorschlag (micro-architecture)• Fokus: Frontend & Webapps
• Kein Framework
• Ziel: Schwächen von MVC eliminieren• Nachvollziehbare Pfade für Daten
• Änderungen leichter umzusetzen
• Bugs leichter auffindbar
Herbstcampus 2015 – Flux Application Architecture 25
Flux
• Unidirektionaler Datenfluss
Action Dispatcher Store View
Herbstcampus 2015 – Flux Application Architecture 26
Flux
• Unidirektionaler Datenfluss
• View bekommt Daten READONLY
Action Dispatcher Store View
Herbstcampus 2015 – Flux Application Architecture 27
Flux
• Unidirektionaler Datenfluss
• Datenmanipulation synchron durch Actions• Benachrichtigung von Views über Events (synchron)
Action Dispatcher Store View
Herbstcampus 2015 – Flux Application Architecture 31
Flux im Schnelldurchlauf
View
Action
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Herbstcampus 2015 – Flux Application Architecture 32
Flux im Schnelldurchlauf
View
Action
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Herbstcampus 2015 – Flux Application Architecture 33
Flux im Schnelldurchlauf
View
Action
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 34
Flux im Schnelldurchlauf
View
Action API
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 36
Flux im Detail
View
Action API
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 37
Flux - Views
• Ähnlich MVC-View • Rufen Actions auf
• Aktualisieren sich selbst
• Hören auf Stores
• View vs. Controller-View• Controller-View: Kleber zw.
Store und Kind-ViewsState
Store
View View
Controller-View
Herbstcampus 2015 – Flux Application Architecture 38
Flux - Views
var SomeView = React.createClass({
getInitialState() {
return {
loggedUser: SessionStore.getLoggedUser()
}
},
componentDidMount() {
SessionStore.addChangeListener(this.onChange);
},
onChange(){
this.setState({
loggedUser: SessionStore.getLoggedUser()
});
},
render() {
return (
<h1> this.state.loggedUser </h1>
);
}
});
Herbstcampus 2015 – Flux Application Architecture 39
Flux - Views
• Besonderheiten:
• Stores geben gesamten Status an die Views
• Komplexitätsreduzierung
• ReactJS: Virtueller DOM-Tree
• Performante Überprüfung auf Änderungen
• Best-Practice: Ein Controller-View für einen Bereich
Herbstcampus 2015 – Flux Application Architecture 40
Flux im Detail
View
Action API
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 41
Flux - Actions
• Verarbeitung von Interaktionen• Vermittlung zw.View und Store
• Action creator• Sammlung von Funktionen
• Action• POJO
• Action-Type + Payload
var action = {
actionType: TodoConstants.TODO_CREATE,
payload: {
title :"get milk",
details : "must be soja milk"
}
}
Herbstcampus 2015 – Flux Application Architecture 42
Flux - Actions
View
Action
Creator
Action
calls
creates
...
login(){
SessionActions.login();
},
render() {
return (
<button onClick={this.login}/>
);
}
var SessionActions = {
login() {
// ...
var action = {
actionType: SessionStoreConstants.LOGIN,
data: …
};
//...
}
};
Herbstcampus 2015 – Flux Application Architecture 43
Flux - Actions
View
Action
Creator
Action
calls
creates
...
login(){
SessionActions.login();
},
render() {
return (
<button onClick={this.login}/>
);
}
var SessionActions = {
login() {
// ...
var loginOnServ =
$.ajax({url: "login", type: "POST"});
loginOnServ.then((data) => {
var action = {
actionType: SessionStoreConstants.LOGIN,
data: data
}
...
});
}
};
API
Herbstcampus 2015 – Flux Application Architecture 44
Flux - Actions
• Besonderheiten• Actions über Konstanten definiert
• Übergabe von Actions an Dispatcher
• API-Zugriff erfolgt in den Actions
var SessionStoreConstants = {
LOGIN : "LOGIN",
LOGOUT : "LOGOUT“
…
};
var action = {
actionType: SessionStoreConstants.LOGIN,
data: data
});
AppDispatcher.handleAction(action);
Herbstcampus 2015 – Flux Application Architecture 45
Flux im Detail
View
Action API
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 46
Flux - Dispatcher
• Zentraler HUB der Applikation• Es gibt nur einen Dispatcher!
• Versendet (dispatches) Actions an Stores• Ähnlich zu pub/sub (JS first-class functions)
• != Controller in MVC!• Singleton
• Keinerlei Geschäftslogik, ausschließlich pub/sub
• Domänenunabhängig
Herbstcampus 2015 – Flux Application Architecture 47
Flux - Dispatcher
Payload
Dispatcher
Store Store Store
Herbstcampus 2015 – Flux Application Architecture 48
Flux - Dispatcher
var AppDispatcher = new Dispatcher();
AppDispatcher.handleAction = function(action) {
this.dispatch({
source: 'VIEW_ACTION',
action: action
});
};
var action = {
actionType: SessionStoreConstants.LOGIN,
data: data
});
AppDispatcher.handleAction(action);
Herbstcampus 2015 – Flux Application Architecture 49
Flux - Dispatcher
• Besonderheiten
• Dispatcher arbeitet synchron
• Dispatcher berücksichtigt Abhängigkeiten zw. Stores
• waitFor-Methode
• Erkennt zirkuläre Abhängigkeiten
• Implementierung von FB verfügbar
Herbstcampus 2015 – Flux Application Architecture 50
Flux im Detail
View
Action API
Dispatcher
ACTION_CONSTANT,
{PAYLOAD}
Store
Dispatch {PAYLOAD}
Business logic based on action
& payload
emit change event
Update view and
children
Herbstcampus 2015 – Flux Application Architecture 51
Flux - Store
• Application state• Domain-spezifische Daten
• View state
• Businesslogik
• Registriert sich am Dispatcher
• Benachrichtigt Views (über Events)
Herbstcampus 2015 – Flux Application Architecture 52
Flux - Store
• != Model in MVC• View state
• N Domänenobjekte
• Datenfluss:
Controller-View
Store
emit event request state
Herbstcampus 2015 – Flux Application Architecture 53
Flux - Store
class SessionStore extends EventEmitter {
constructor() {
super();
this.loggedUser = null;
this.loading = false;
}
onLogin(data){
this.loading = false;
this.loggedUser = data.userName;
this.emit("change");
}
onLoad(){
this.loading = true;
this.emit("change");
}
}
Herbstcampus 2015 – Flux Application Architecture 54
Flux - Store
var sessionStore = new SessionStore();
AppDispatcher.register(function (action) {
switch(action.actionType){
case SessionStoreConstants.LOGIN:
sessionStore.onLogin(action.data);
break;
...
}
});
• Store registrieren
Herbstcampus 2015 – Flux Application Architecture 55
Flux - Store
• Besonderheiten
• Stores nur über Actions veränderbar
• Keine setter (konsistenter Status)
• Stores sollen synchron sein
• Keine API-Calls
• Einfacher Datenfluss!
• Umgang mit abgeleiteten Daten (derived data)
• Frage an viele Domänenobjekte (z.B. FB-Chat)
Herbstcampus 2015 – Flux Application Architecture 56
Flux
• Wie skaliert Flux?
ActionStore View
View
View
View
Store
Store
Store
Action
Action
Action
Dispatcher
Herbstcampus 2015 – Flux Application Architecture 57
Flux
• Wie skaliert Flux?
ActionStore View
View
View
View
Store
Store
Store
Action
Action
Action
Dispatcher
Herbstcampus 2015 – Flux Application Architecture 59
Flux ohne ReactJS
• Flux in anderen Technologien / Frameworks• Swift
• AngularJS
• Backbone
• …
• Framework auf Framework…
• Stores sagen nicht, was sich geändert hat• ReactJs-Virtual-DOM-Diff
Universal JavaScript
Herbstcampus 2015 – Flux Application Architecture 61
Lösung für alles? (1/2)
• Fluxs‘ Stärken• Viele Views, kein direkter Domain-Model-Bezug
• N-Models darstellen
• In kleinen CRUD Anwendungen?• Views passen genau auf Models
• Passende View-Technologie
Herbstcampus 2015 – Flux Application Architecture 62
Lösung für alles? (2/2)
• Flux ist gut wenn…
• Daten sich häufig ändern
• Nachvollziehbarer Datenfluss
• Views komplex sind
• Vers. Datenquellen
• Logische Abhängigkeiten
• Views stark voneinander abhängen
• Wenn a, dann auch b und c
Herbstcampus 2015 – Flux Application Architecture 63
Kritik an Flux
• FB hat MVC falsch verstanden• Facebooks‘ MVC-Grafik zu komplex
• 1 Controller?
• View generiert Datenfluss?
• Zu viele Models?
• Flux ist nicht einfacher als MVC!• Boilerplate
• Aber: erzwingt vorhersehbaren Datenfluss
Herbstcampus 2015 – Flux Application Architecture 64
Kritik an Flux
• Flux ist CQRS • Datenisolation in Layer (Stores)
• Abfrage und
Manipulation
getrennt
Herbstcampus 2015 – Flux Application Architecture 67
Flux Implementierungen
http://www.redspy.co.uk/
Herbstcampus 2015 – Flux Application Architecture 68
Flux Implementierungen
• Facebooks‘ Implementierung: Boilerplate!
• Vielzahl an Flux-Implementierungen
• Boilerplate minimieren
• Architektur erweitern & vereinfachen
• Isomorphic
• Serverside rendering
• Für andere Technologien als JS
Herbstcampus 2015 – Flux Application Architecture 69
Flux Implementierungen
• Reflux• Flux-Architektur verändern
• Fluxxor• Flux-Architektur beibehalten
Herbstcampus 2015 – Flux Application Architecture 71
Reflux
• Ziele:• Architektur vereinfachen
• Flux funktionaler & dynamischer machen
• Gemeinsamkeiten mit Flux• Views
• Actions
• Stores
• Unidirektionaler Datenfluss
• Unterschiede• Kein Dispatcher
• Keine action creators
Herbstcampus 2015 – Flux Application Architecture 72
Reflux
• Kein Dispatcher
• Action = function
• Action = listenable
• Action = Dispatcher
• Stores subscribe actions
Action(listenable)
Store(listens)
View
Herbstcampus 2015 – Flux Application Architecture 73
Reflux
• Kein Dispatcher
• Action = function
• Action = listenable
• Action = Dispatcher
• Stores subscribe actions
Action(listenable)
Store(listens)
View
Keine Action-Konstanten
Keine switch-statements
Funktionale
Programmierung
Stores can listen to Stores
Herbstcampus 2015 – Flux Application Architecture 75
Fluxxor
• Folgt exaktem Flux-Architekturvorschlag
• Mindert Boilerplate-Code
Herbstcampus 2015 – Flux Application Architecture 77
Fluxxor
Action Dispatcher Store View
var SessionStore = Fluxxor.createStore({
initialize() {
this.loggedUser = null;
this.bindActions(
"LOGIN", this.onLogin
);
},
onLogin(userName){
this.loggedUser = userName;
this.emit("change");
}
});
Herbstcampus 2015 – Flux Application Architecture 78
Fluxxor
var SessionActions = {
login(userName) {
//...
this
.dispatch("LOGIN",userName);
}
};
Action Dispatcher Store View
var SessionStore = Fluxxor.createStore({
initialize() {
this.loggedUser = null;
this.bindActions(
"LOGIN", this.onLogin
);
},
onLogin(userName){
this.loggedUser = userName;
this.emit("change");
}
});
Herbstcampus 2015 – Flux Application Architecture 79
Fluxxor
var SessionActions = {
login(userName) {
//...
this
.dispatch("LOGIN",userName);
}
};
Action Disp. Store View
var SessionStore = Fluxxor.createStore({
initialize() {
this.loggedUser = null;
this.bindActions(
"LOGIN", this.onLogin
);
},
onLogin(userName){
this.loggedUser = userName;
this.emit("change");
}
});
var LoginView = React.createClass({
mixins: [Fluxxor.StoreWatchMixin("SessionStore")],
getStateFromFlux() {
var store = this.getFlux().store("SessionStore");
return {
loginState: store.loggedUser
};
},
onLogin() {
this.getFlux().actions.SessionActions.login();
},
render() {
return (
<button onClick={this.onLogin}/>
);
}
});