SlideShare a Scribd company logo
1 of 99
Download to read offline
The Rise Of The State
Machines
an introduction to predictable state container based architectures for
your android apps
@_mboudraa
@_mboudraa
@_mboudraa
Problem to Solve
@_mboudraa
Problem to Solve
Easy to test all the components of an app (even the UI)
@_mboudraa
Problem to Solve
Easy to test all the components of an app (even the UI)
Easy to reproduce bugs to fix them
@_mboudraa
Problem to Solve
Easy to test all the components of an app (even the UI)
Easy to update
Easy to reproduce bugs to fix them
@_mboudraa
Problem to Solve
Easy to test all the components of an app (even the UI)
Easy to update
Easy to reproduce bugs to fix them
Global Picture of what’s happening by reading the code
View
View
Controller
Action
@_mboudraa
Store
Reducer
f(AppState, Action) -> AppState
Redux / MVI
@_mboudraa
Store
Reducer
f(AppState, Action) -> AppState
Redux / MVI
What’s a Pure function?
@_mboudraa
Store
Reducer
f(AppState, Action) -> AppState
Redux / MVI
Pure
fun add(a: Int, b: Int): Int {
return a + b
}
What’s a Pure function?
@_mboudraa
Store
Reducer
f(AppState, Action) -> AppState
Redux / MVI
Pure
fun add(a: Int, b: Int): Int {
return a + b
}
fun add(a: Int, b: Int): Int {
val result = a + b
println(result)
return result
}
Not Pure
What’s a Pure function?
View
View
Controller
Action
Store
Reducer
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
New State
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
New State
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
EditText Changed
ValidateFieldsAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
SuccessfullySignedInAction
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
SuccessfullySignedInAction
@_mboudraa
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
SuccessfullySignedInAction
@_mboudraa
Store
@_mboudraa
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
SignInFailedAction
Store
View
View
Controller
Action
Reducer
Click on Sign In
SignInAction
f(AppState, Action) -> AppState
New State
View State
Side Effect
SignInAction
SignInFailedAction
@_mboudraa
@_mboudraa
Side Effect
@_mboudraa
Side Effect
They can be synchronous or asynchronous
@_mboudraa
Side Effect
They can be synchronous or asynchronous
It can return an action or nothing
@_mboudraa
Action
@_mboudraa
Action
It contains meta data
@_mboudraa
Action
It contains meta data
It will be reduced by the Store to produce a new State
@_mboudraa
Action
sealed class Action {
data class CheckFields(val username: String, val password: String) : Action()
data class AttemptLogin(val username: String, val password: String) : Action()
data class LoginError(val message: String) : Action()
data class UnexpectedError(val message: String) : Action()
}
@_mboudraa
Store
@_mboudraa
Store
It has the State of the App
@_mboudraa
Store
It has the State of the App
State is immutable
@_mboudraa
Store
It has the State of the App
Create a new State by reducing an action using the old state
f(State, Action) -> State
State is immutable
@_mboudraa
Store
It has the State of the App
Create a new State by reducing an action using the old state
f(State, Action) -> State
It dispatches actions to Side Effects after being reduced
State is immutable
@_mboudraa
Storeclass Store(defaultState: AppState) {
var currentState: AppState = defaultState
private set
fun dispatchAction(action: Action) {
currentState = reduce(currentState, action)
dispatchToSideEffects(action)
}
fun reduce(state: AppState, action: Action): AppState {
return when (action) {
is Action.CheckFields -> state.copy(canSubmit = state.email.isNotBlank())
is Action.AttemptLogin -> state.copy(isLoading = true, canSubmit = false)
is Action.LoginError -> {
state.copy(isLoading = false,
canSubmit = true,
hasLoginError = true,
loginError = action.message,
hasUnexpectedError = false)
}
is Action.UnexpectedError -> {
state.copy(isLoading = false,
canSubmit = true,
hasLoginError = false, hasUnexpectedError = false,
unexpectedError = action.message)
}
}
}
}
@_mboudraa
State
data class AppState(val email: String,
val password: String,
val canSubmit: Boolean,
val isLoading: Boolean,
val hasLoginError: Boolean,
val loginError: String?,
val hasUnexpectedError: Boolean,
val unexpectedError: String?
val isLoginSuccessful: Boolean)
@_mboudraa
View Controller
fun render(appState: AppState) {
when {
appState.isLoginSuccessful -> goto<SucessfulLoginActivity>()
else -> {
setEmail(appState.email)
setPassword(appState.password)
when {
appState.isLoading -> {
hideUnexpectedError()
hideLoginError()
displayProgesssBar()
}
appState.hasLoginError -> {
displayLoginError(appState.loginError)
}
appState.hasUnexpectedError -> {
displayUnexpectedError(appState.unexpectedError)
}
else -> {
hideUnexpectedError()
hideLoginError()
hideProgesssBar()
}
}
}
}
}
@_mboudraa
View
View
Controller
Action
@_mboudraa
Store
Reducer
f(AppState, Action) -> AppState
Redux / MVI
View
View
Controller
Action
@_mboudraa
Store
Reducer

State
f(AppState, Action) -> AppState
State Machine
State( Action) -> NextState
State Machine
View
View
Controller
Action
@_mboudraa
State Machine
State( Action) -> NextState
State Machine
State
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
ValidState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
ValidState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
ValidState
View State
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
ValidState
View State
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
EditText Changed
ValidateFieldsAction
View State
ValidState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
Click on Sign In
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
Click on Sign In
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
Click on Sign In
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
LoadingState
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
LoadingState
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
LoadingState
View State
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
LoadingState
View State
Click on Sign In
SignInAction
View
View
Controller
Action
@_mboudraa
State Machine
State
State( Action) -> NextState
View State
Click on Sign In
SignInAction
LoadingState
View
View
Controller
Action
@_mboudraa
State Machine
View State
Click on Sign In
SignInAction
LoadingState State
State( Action) -> NextState
View
View
Controller
Action
@_mboudraa
State Machine
View State
Click on Sign In
SignInAction
StateAuthenticatedState
State( Action) -> NextState
View
View
Controller
Action
@_mboudraa
State Machine
State( Action) -> NextState
View State
Click on Sign In
SignInAction
StateAuthenticatedState
@_mboudraa
Implementation
class DefaultState(private val stateMachine: StateMachine) {
fun onAction(action: Action) =
if (action is Action.CheckFields)
if (!action.username.isBlank())
stateMachine.nextState(ValidState())
}
@_mboudraa
Implementation
class ValidState(private val stateMachine: StateMachine) {
fun onAction(action: Action) =
when(action){
is Action.CheckFields-> {
if (!action.username.isBlank())
stateMachine.nextState(ValidState(stateMachine))
else
stateMachine.nextState(DefaultState(stateMachine))
}
is Action.AttemptLogin -> {
stateMachine.nexState(LoadingState(stateMachine), Action.AttemptLogin))
}
}
}
class DefaultState(private val stateMachine: StateMachine) {
fun onAction(action: Action) =
if (action is Action.CheckFields)
if (!action.username.isBlank())
stateMachine.nextState(ValidState())
}
@_mboudraa
Implementationclass DefaultState(private val stateMachine: StateMachine) {
fun onAction(action: Action) {
if (action is Action.CheckFields) {
if (!action.username.isBlank()) {
stateMachine.nextState(ValidState())
}
}
}
}
class LoadingState(private val stateMachine: StateMachine) {
fun onAction(action: Action) =
if(action is Action.AttemptLogin){
async(UI) {
val account = bg { authService.signIn(action.credentials}.await()
stateMachine.nextState(AuthenticatedState())
}
}
}
class ValidState(private val stateMachine: StateMachine) {
fun onAction(action: Action) =
when(action){
is Action.CheckFields-> {
if (!action.username.isBlank())
stateMachine.nextState(ValidState(stateMachine))
else
stateMachine.nextState(DefaultState(stateMachine))
}
is Action.AttemptLogin -> {
stateMachine.nexState(LoadingState(stateMachine), Action.AttemptLogin))
}
}
}
@_mboudraa
Sum Up
@_mboudraa
Sum Up
Pros
Cons
MVI / Redux
Easy to find bugs

Easy to maintain
Easy to add new actions
Global Picture of possible actions
Logic business is isolated in pure functions
Side Effects are isolated
ViewController need to figure out the actual state
Actions can be dispatched from anywhere

No Global Picture of the flow
@_mboudraa
Sum Up
Pros
Cons
MVI / Redux
Easy to find bugs

Easy to maintain
Easy to add new actions
Global Picture of possible actions
Logic business is isolated in pure functions
Side Effects are isolated
ViewController need to figure out the actual state
Actions can be dispatched from anywhere

No Global Picture of the flow
State Machine
Easy to find bugs

Easy to maintain
Actions are carried by the state
ViewController receive a state
Hard to add new states

No Global Picture of the flow

Business Logic and Side effects are inside the state
State are responsible for going to the next state
@_mboudraa
Sum Up
MVI / Redux State Machine
Pros
Easy to find bugs

Easy to maintain
Easy to add new actions
Global Picture of possible actions
Logic business is isolated in pure functions
Side Effects are isolated
Easy to find bugs

Easy to maintain
Actions are carried by the state
ViewController receive a state
Cons
ViewController need to figure out the actual state
Actions can be dispatch from anywhere

No Global Picture of the flow
Hard to add new states

No Global Picture of the flow

Business Logic and Side effects are inside the state
State are responsible for going to the next state
@_mboudraa
What I want!
@_mboudraa
Kotlin to the rescue
html {
title = "Droidcon Dubai"
body()
}
@_mboudraa
Kotlin to the rescue
class HTML {
var title: String
fun body() {
...
}
}
html {
title = "Droidcon Dubai"
body()
}
@_mboudraa
Kotlin to the rescue
class HTML {
var title: String
fun body() {
...
}
}
fun html(content: HTML.() -> Unit): HTML {
val html = HTML() // create the receiver object
html.content() // pass the receiver object to the lambda
return html
}
html {
title = "Droidcon Dubai"
body()
}
@_mboudraa
Demo

More Related Content

What's hot

Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
martinlippert
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
Evan Schultz
 
e computer notes - Manipulating data
e computer notes - Manipulating datae computer notes - Manipulating data
e computer notes - Manipulating data
ecomputernotes
 

What's hot (14)

Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Solid angular
Solid angularSolid angular
Solid angular
 
Knockout mvvm-m2-slides
Knockout mvvm-m2-slidesKnockout mvvm-m2-slides
Knockout mvvm-m2-slides
 
Session 2- day 3
Session 2- day 3Session 2- day 3
Session 2- day 3
 
Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1
 
Day seven
Day sevenDay seven
Day seven
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Angular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app exampleAngular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app example
 
Manipulating Magento - Meet Magento Netherlands 2018
Manipulating Magento - Meet Magento Netherlands 2018Manipulating Magento - Meet Magento Netherlands 2018
Manipulating Magento - Meet Magento Netherlands 2018
 
Chainable datasource
Chainable datasourceChainable datasource
Chainable datasource
 
e computer notes - Manipulating data
e computer notes - Manipulating datae computer notes - Manipulating data
e computer notes - Manipulating data
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular components
 

Similar to Rise of state_machines

Real World State And Notification Broker
Real World State And Notification BrokerReal World State And Notification Broker
Real World State And Notification Broker
XeDotNet
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
Mahmoud Hamed Mahmoud
 

Similar to Rise of state_machines (20)

ReSwift & Machine Learning
ReSwift & Machine LearningReSwift & Machine Learning
ReSwift & Machine Learning
 
Real World State And Notification Broker
Real World State And Notification BrokerReal World State And Notification Broker
Real World State And Notification Broker
 
From mvc to redux: 停看聽
From mvc to redux: 停看聽From mvc to redux: 停看聽
From mvc to redux: 停看聽
 
The Redux State of the Art
The Redux State of the ArtThe Redux State of the Art
The Redux State of the Art
 
The Redux State of the Art - Shem Magnezi+Limor Mekaiten, WeWork
The Redux State of the Art - Shem Magnezi+Limor Mekaiten, WeWorkThe Redux State of the Art - Shem Magnezi+Limor Mekaiten, WeWork
The Redux State of the Art - Shem Magnezi+Limor Mekaiten, WeWork
 
Unidirectional Data Flow in Swift
Unidirectional Data Flow in SwiftUnidirectional Data Flow in Swift
Unidirectional Data Flow in Swift
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 
Applications: A Series of States
Applications: A Series of StatesApplications: A Series of States
Applications: A Series of States
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
React 16: new features and beyond
React 16: new features and beyondReact 16: new features and beyond
React 16: new features and beyond
 
React redux
React reduxReact redux
React redux
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 
Hello, ReactorKit 
Hello, ReactorKit Hello, ReactorKit 
Hello, ReactorKit 
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with React
 
Flutter
FlutterFlutter
Flutter
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3
 
Growing up with Magento
Growing up with MagentoGrowing up with Magento
Growing up with Magento
 

Rise of state_machines