SlideShare a Scribd company logo
“Basically Redux”
Cody Engel
@POTUS404
Senior Engineer
@POTUS404
Redux Basics
@POTUS404Redux Basics
Actions
Actions are payloads of information that send
data from your application to your store. They
are the only source of information for the
store. Actions do not describe how the actions
will change the state.
https://redux.js.org/basics/actions
@POTUS404Redux Basics
Actions
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
@POTUS404Redux Basics
Reducers
Reducers specify how the application's state
changes in response to actions sent to the
store. Remember that actions only describe
what happened, but don't describe how the
application's state changes.
https://redux.js.org/basics/reducers
@POTUS404Redux Basics
Reducers
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
@POTUS404Redux Basics
The Store
The Store brings the actions and reducers
together. It holds the application’s state and
allows state to be updated and observed on.
You’ll only ever have one store in a Redux
application.
https://redux.js.org/basics/store
@POTUS404Redux Basics
Data Flow
Redux follows a strict unidirectional data flow.
This means data in your systems follows a
predictable path which is easier to
understand.
https://redux.js.org/basics/data-flow
@POTUS404Redux Basics
Data Flow
Actions Reducers Store
State Tree Updated
@POTUS404
Algebraic Data
Types
@POTUS404Algebraic Data Types
Product Type
A product type is a structure made up of
multiple other types.
@POTUS404Algebraic Data Types
Product Type
data class Gumball(
val size: GumballSize,
val color: GumballColor
)
@POTUS404Algebraic Data Types
Sum Type
A structure used to hold a value that could
take on several different, but fixed types.
@POTUS404Algebraic Data Types
Sum Type
sealed class GumballSize {
object Small : GumballSize()
object Medium : GumballSize()
object Large : GumballSize()
}
@POTUS404
Pure Functions
@POTUS404Pure Functions
Pure Functions
A pure function is a function where the return
value is only determined by its input values,
without observable side effects.
@POTUS404Pure Functions
fun add(left: Int, right: Int): Int {
return left + right
}
Pure Functions
@POTUS404Pure Functions
fun giveMeAGumball(
gumballSize: GumballSize,
gumballColor: GumballColor
): Gumball {
return Gumball(gumballSize, gumballColor)
}
Pure Functions
@POTUS404
Finite-state
Machines
@POTUS404Finite-state Machine
A finite state machine is one that has a
limited or finite number of possible states.
Finite-state Machines
@POTUS404Finite-state Machines
@POTUS404
• How many gumballs are left?
• Is it currently dispensing?
Gumball Machine
States
Finite-state Machines
@POTUS404
REDUCE!
@POTUS404REDUCE!
fun main(args: Array<String>) {
val gumballMachine = GumballMachine()
while(true) {
if (gumballMachine.hasGumballs) {
println("Purchased a ${gumballMachine.buyGumball()}")
} else {
println("Sorry, no more gumballs.")
print("Would you like to refill the gumball machine? y/n: ")
if (readLine() == "y") {
gumballMachine.refill()
println()
} else {
return
}
}
}
}
Gumball Machine Usage
@POTUS404REDUCE!
fun main(args: Array<String>) {
val gumballMachine = GumballMachine()
while(true) {
if (gumballMachine.hasGumballs) {
println("Purchased a ${gumballMachine.buyGumball()}")
} else {
println("Sorry, no more gumballs.")
print("Would you like to refill the gumball machine? y/n: ")
if (readLine() == "y") {
gumballMachine.refill()
println()
} else {
return
}
}
}
}
Gumball Machine Usage
@POTUS404REDUCE!
fun main(args: Array<String>) {
val gumballMachine = GumballMachine()
while(true) {
if (gumballMachine.hasGumballs) {
println("Purchased a ${gumballMachine.buyGumball()}")
} else {
println("Sorry, no more gumballs.")
print("Would you like to refill the gumball machine? y/n: ")
if (readLine() == "y") {
gumballMachine.refill()
println()
} else {
return
}
}
}
}
Gumball Machine Usage
@POTUS404REDUCE!
fun main(args: Array<String>) {
val gumballMachine = GumballMachine()
while(true) {
if (gumballMachine.hasGumballs) {
println("Purchased a ${gumballMachine.buyGumball()}")
} else {
println("Sorry, no more gumballs.")
print("Would you like to refill the gumball machine? y/n: ")
if (readLine() == "y") {
gumballMachine.refill()
println()
} else {
return
}
}
}
}
Gumball Machine Usage
@POTUS404REDUCE!
fun main(args: Array<String>) {
val gumballMachine = GumballMachine()
while(true) {
if (gumballMachine.hasGumballs) {
println("Purchased a ${gumballMachine.buyGumball()}")
} else {
println("Sorry, no more gumballs.")
print("Would you like to refill the gumball machine? y/n: ")
if (readLine() == "y") {
gumballMachine.refill()
println()
} else {
return
}
}
}
}
Gumball Machine Usage
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
The Gumball Machine
class GumballMachine(private val timeToDispense: Long = 50) {
object Gumball {
override fun toString() = "$color Gumball"
private val color
get() = when(Random().nextInt(8) + 1) {
1 -> "Blue"
2 -> "Red"
3 -> "Green"
4 -> "Yellow"
5 -> "Pink"
6 -> "Purple"
7 -> "Orange"
else -> "White"
}
}
val hasGumballs
get() = state.remainingGumballs > 0
private val gumballReducer = GumballReducer()
private var state = GumballState()
fun buyGumball(): Gumball {
state = gumballReducer.reduce(state, GumballAction.BuyGumball)
Thread.sleep(timeToDispense)
state = gumballReducer.reduce(state, GumballAction.Dispensed)
return Gumball
}
fun refill() {
state = gumballReducer.reduce(state, GumballAction.RefillGumballs)
}
}
@POTUS404REDUCE!
sealed class GumballAction : Action {
object BuyGumball : GumballAction()
object RefillGumballs : GumballAction()
object Dispensed : GumballAction()
}
The Gumball Actions
@POTUS404REDUCE!
data class GumballState(
val remainingGumballs: Int = 100,
val isDispensing: Boolean = false
) : State
The Gumball State
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState {
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState{
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState {
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState {
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState {
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404REDUCE!
class GumballReducer : Reducer<GumballState, GumballAction> {
override fun reduce(state: GumballState, action: GumballAction): GumballState {
return when(action) {
is GumballAction.BuyGumball -> {
if (state.isDispensing) {
throw IllegalStateException(“…”)
} else if (state.remainingGumballs <= 0) {
throw IllegalStateException(“…”)
}
state.copy(
remainingGumballs = state.remainingGumballs - 1,
isDispensing = true
)
}
is GumballAction.RefillGumballs -> state.copy(
remainingGumballs = 100,
isDispensing = false
)
is GumballAction.Dispensed -> state.copy(isDispensing = false)
}
}
}
The Gumball Reducer
@POTUS404
RxJava
@POTUS404RxJava
Observable.fromPublisher<CompanyAction> { subscriber ->
0.until(320).map {
if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition,
Employee.employee)
}.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() }
}
.reduceWith({ Company("ActiveCampaign") }, { prevState, action ->
when(action) {
is CompanyAction.Hire -> {
val employees = prevState.employees.toMutableList()
employees.add(action.employee)
prevState.copy(employees = employees)
}
is CompanyAction.Add -> {
val requisitions = prevState.requisitions.toMutableList()
requisitions.add(action.requisition)
prevState.copy(requisitions = requisitions)
}
}
})
.subscribe { state ->
println("These numbers are most likely inaccurate.")
println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.")
println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.")
println("Here is the raw state output:")
println(state)
}
@POTUS404RxJava
Observable.fromPublisher<CompanyAction> { subscriber ->
0.until(320).map {
if (it % 11 == 0) CompanyAction.Add(Requisition.requisition)
else CompanyAction.Hire(Requisition.requisition, Employee.employee)
}
.forEach { subscriber.onNext(it) }
.also { subscriber.onComplete() }
}
.reduceWith({ Company("ActiveCampaign") }, { prevState, action ->
when(action) {
is CompanyAction.Hire -> {
val employees = prevState.employees.toMutableList()
employees.add(action.employee)
prevState.copy(employees = employees)
}
is CompanyAction.Add -> {
val requisitions = prevState.requisitions.toMutableList()
requisitions.add(action.requisition)
prevState.copy(requisitions = requisitions)
}
}
})
.subscribe { state ->
println("These numbers are most likely inaccurate.")
println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.")
println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.")
println("Here is the raw state output:")
println(state)
}
@POTUS404RxJava
Observable.fromPublisher<CompanyAction> { subscriber ->
0.until(320).map {
if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee)
}.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() }
}
.reduceWith({ Company("ActiveCampaign") }, { prevState, action ->
when(action) {
is CompanyAction.Hire -> {
val employees = prevState.employees.toMutableList()
employees.add(action.employee)
prevState.copy(employees = employees)
}
is CompanyAction.Add -> {
val requisitions = prevState.requisitions.toMutableList()
requisitions.add(action.requisition)
prevState.copy(requisitions = requisitions)
}
}
})
.subscribe { state ->
println("These numbers are most likely inaccurate.")
println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.")
println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.")
println("Here is the raw state output:")
println(state)
}
@POTUS404RxJava
Observable.fromPublisher<CompanyAction> { subscriber ->
0.until(320).map {
if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee)
}.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() }
}
.reduceWith({ Company("ActiveCampaign") }, { prevState, action ->
when(action) {
is CompanyAction.Hire -> {
val employees = prevState.employees.toMutableList()
employees.add(action.employee)
prevState.copy(employees = employees)
}
is CompanyAction.Add -> {
val requisitions = prevState.requisitions.toMutableList()
requisitions.add(action.requisition)
prevState.copy(requisitions = requisitions)
}
}
})
.subscribe { state ->
println("These numbers are most likely inaccurate.")
println("ActiveCampaign has ${state.requisitions.size} job openings
with around ${state.employees.size} employees.")
println("There are ${state.employees.filter { it.name == "Cody" }.size}
employees named Cody.")
println("Here is the raw state output:")
println(state)
}
These numbers are most likely inaccurate.
ActiveCampaign has 30 job openings with around 290 employees.
There are 19 employees named Cody.
Here is the raw state output:
Company(name=ActiveCampaign,
requisitions=[Requisition(name=Full Stack Engineer, department=Engineering),
…)
@POTUS404RxJava
Cody Engel
@POTUS404
Senior Engineer
(We’re Hiring)
Thanks!

More Related Content

What's hot

The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
Baruch Sadogursky
 
DroidKnight 2018 State machine by Selaed class
DroidKnight 2018 State machine by Selaed classDroidKnight 2018 State machine by Selaed class
DroidKnight 2018 State machine by Selaed classMyeongin Woo
 
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Codemotion
 
How else can you write the code in PHP?
How else can you write the code in PHP?How else can you write the code in PHP?
How else can you write the code in PHP?
Maksym Hopei
 
Magic of Ruby
Magic of RubyMagic of Ruby
Magic of Ruby
Gabriele Lana
 
Chaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreChaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscore
Nicolas Carlo
 
Working with Groovy Collections
Working with Groovy CollectionsWorking with Groovy Collections
Working with Groovy Collections
Ted Vinke
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recap
furusin
 
Famo.us: From Zero to UI
Famo.us: From Zero to UIFamo.us: From Zero to UI
Famo.us: From Zero to UI
timjchin
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShell
Gaetano Causio
 
MongoDB With Style
MongoDB With StyleMongoDB With Style
MongoDB With Style
Gabriele Lana
 
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
indeedeng
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips
ikeyat
 
Instant Dynamic Forms with #states
Instant Dynamic Forms with #statesInstant Dynamic Forms with #states
Instant Dynamic Forms with #statesKonstantin Käfer
 
Oh Composable World!
Oh Composable World!Oh Composable World!
Oh Composable World!
Brian Lonsdorf
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
Łukasz Chruściel
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
Joe Morgan
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
Bastian Feder
 

What's hot (20)

The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
DroidKnight 2018 State machine by Selaed class
DroidKnight 2018 State machine by Selaed classDroidKnight 2018 State machine by Selaed class
DroidKnight 2018 State machine by Selaed class
 
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
 
Spock and Geb
Spock and GebSpock and Geb
Spock and Geb
 
How else can you write the code in PHP?
How else can you write the code in PHP?How else can you write the code in PHP?
How else can you write the code in PHP?
 
Magic of Ruby
Magic of RubyMagic of Ruby
Magic of Ruby
 
Chaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreChaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscore
 
Working with Groovy Collections
Working with Groovy CollectionsWorking with Groovy Collections
Working with Groovy Collections
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recap
 
Famo.us: From Zero to UI
Famo.us: From Zero to UIFamo.us: From Zero to UI
Famo.us: From Zero to UI
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShell
 
MongoDB With Style
MongoDB With StyleMongoDB With Style
MongoDB With Style
 
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips
 
Instant Dynamic Forms with #states
Instant Dynamic Forms with #statesInstant Dynamic Forms with #states
Instant Dynamic Forms with #states
 
Oh Composable World!
Oh Composable World!Oh Composable World!
Oh Composable World!
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 

Similar to Basically Redux - Android Listeners

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
Alexander Granin
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
ssuserb6c2641
 
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
Andrzej Jóźwiak
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 DevsJason Hanson
 

Similar to Basically Redux - Android Listeners (6)

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
 
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
 

Recently uploaded

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 

Recently uploaded (20)

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 

Basically Redux - Android Listeners

  • 3. @POTUS404Redux Basics Actions Actions are payloads of information that send data from your application to your store. They are the only source of information for the store. Actions do not describe how the actions will change the state. https://redux.js.org/basics/actions
  • 5. @POTUS404Redux Basics Reducers Reducers specify how the application's state changes in response to actions sent to the store. Remember that actions only describe what happened, but don't describe how the application's state changes. https://redux.js.org/basics/reducers
  • 6. @POTUS404Redux Basics Reducers function todoApp(state = initialState, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({}, state, { visibilityFilter: action.filter }) default: return state } }
  • 7. @POTUS404Redux Basics The Store The Store brings the actions and reducers together. It holds the application’s state and allows state to be updated and observed on. You’ll only ever have one store in a Redux application. https://redux.js.org/basics/store
  • 8. @POTUS404Redux Basics Data Flow Redux follows a strict unidirectional data flow. This means data in your systems follows a predictable path which is easier to understand. https://redux.js.org/basics/data-flow
  • 9. @POTUS404Redux Basics Data Flow Actions Reducers Store State Tree Updated
  • 11. @POTUS404Algebraic Data Types Product Type A product type is a structure made up of multiple other types.
  • 12. @POTUS404Algebraic Data Types Product Type data class Gumball( val size: GumballSize, val color: GumballColor )
  • 13. @POTUS404Algebraic Data Types Sum Type A structure used to hold a value that could take on several different, but fixed types.
  • 14. @POTUS404Algebraic Data Types Sum Type sealed class GumballSize { object Small : GumballSize() object Medium : GumballSize() object Large : GumballSize() }
  • 16. @POTUS404Pure Functions Pure Functions A pure function is a function where the return value is only determined by its input values, without observable side effects.
  • 17. @POTUS404Pure Functions fun add(left: Int, right: Int): Int { return left + right } Pure Functions
  • 18. @POTUS404Pure Functions fun giveMeAGumball( gumballSize: GumballSize, gumballColor: GumballColor ): Gumball { return Gumball(gumballSize, gumballColor) } Pure Functions
  • 20. @POTUS404Finite-state Machine A finite state machine is one that has a limited or finite number of possible states. Finite-state Machines
  • 22. @POTUS404 • How many gumballs are left? • Is it currently dispensing? Gumball Machine States Finite-state Machines
  • 24. @POTUS404REDUCE! fun main(args: Array<String>) { val gumballMachine = GumballMachine() while(true) { if (gumballMachine.hasGumballs) { println("Purchased a ${gumballMachine.buyGumball()}") } else { println("Sorry, no more gumballs.") print("Would you like to refill the gumball machine? y/n: ") if (readLine() == "y") { gumballMachine.refill() println() } else { return } } } } Gumball Machine Usage
  • 25. @POTUS404REDUCE! fun main(args: Array<String>) { val gumballMachine = GumballMachine() while(true) { if (gumballMachine.hasGumballs) { println("Purchased a ${gumballMachine.buyGumball()}") } else { println("Sorry, no more gumballs.") print("Would you like to refill the gumball machine? y/n: ") if (readLine() == "y") { gumballMachine.refill() println() } else { return } } } } Gumball Machine Usage
  • 26. @POTUS404REDUCE! fun main(args: Array<String>) { val gumballMachine = GumballMachine() while(true) { if (gumballMachine.hasGumballs) { println("Purchased a ${gumballMachine.buyGumball()}") } else { println("Sorry, no more gumballs.") print("Would you like to refill the gumball machine? y/n: ") if (readLine() == "y") { gumballMachine.refill() println() } else { return } } } } Gumball Machine Usage
  • 27. @POTUS404REDUCE! fun main(args: Array<String>) { val gumballMachine = GumballMachine() while(true) { if (gumballMachine.hasGumballs) { println("Purchased a ${gumballMachine.buyGumball()}") } else { println("Sorry, no more gumballs.") print("Would you like to refill the gumball machine? y/n: ") if (readLine() == "y") { gumballMachine.refill() println() } else { return } } } } Gumball Machine Usage
  • 28. @POTUS404REDUCE! fun main(args: Array<String>) { val gumballMachine = GumballMachine() while(true) { if (gumballMachine.hasGumballs) { println("Purchased a ${gumballMachine.buyGumball()}") } else { println("Sorry, no more gumballs.") print("Would you like to refill the gumball machine? y/n: ") if (readLine() == "y") { gumballMachine.refill() println() } else { return } } } } Gumball Machine Usage
  • 29. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 30. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 31. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } }
  • 32. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 33. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 34. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 35. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 36. @POTUS404REDUCE! The Gumball Machine class GumballMachine(private val timeToDispense: Long = 50) { object Gumball { override fun toString() = "$color Gumball" private val color get() = when(Random().nextInt(8) + 1) { 1 -> "Blue" 2 -> "Red" 3 -> "Green" 4 -> "Yellow" 5 -> "Pink" 6 -> "Purple" 7 -> "Orange" else -> "White" } } val hasGumballs get() = state.remainingGumballs > 0 private val gumballReducer = GumballReducer() private var state = GumballState() fun buyGumball(): Gumball { state = gumballReducer.reduce(state, GumballAction.BuyGumball) Thread.sleep(timeToDispense) state = gumballReducer.reduce(state, GumballAction.Dispensed) return Gumball } fun refill() { state = gumballReducer.reduce(state, GumballAction.RefillGumballs) } }
  • 37. @POTUS404REDUCE! sealed class GumballAction : Action { object BuyGumball : GumballAction() object RefillGumballs : GumballAction() object Dispensed : GumballAction() } The Gumball Actions
  • 38. @POTUS404REDUCE! data class GumballState( val remainingGumballs: Int = 100, val isDispensing: Boolean = false ) : State The Gumball State
  • 39. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState { return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 40. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState{ return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 41. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState { return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 42. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState { return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 43. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState { return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 44. @POTUS404REDUCE! class GumballReducer : Reducer<GumballState, GumballAction> { override fun reduce(state: GumballState, action: GumballAction): GumballState { return when(action) { is GumballAction.BuyGumball -> { if (state.isDispensing) { throw IllegalStateException(“…”) } else if (state.remainingGumballs <= 0) { throw IllegalStateException(“…”) } state.copy( remainingGumballs = state.remainingGumballs - 1, isDispensing = true ) } is GumballAction.RefillGumballs -> state.copy( remainingGumballs = 100, isDispensing = false ) is GumballAction.Dispensed -> state.copy(isDispensing = false) } } } The Gumball Reducer
  • 46. @POTUS404RxJava Observable.fromPublisher<CompanyAction> { subscriber -> 0.until(320).map { if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee) }.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() } } .reduceWith({ Company("ActiveCampaign") }, { prevState, action -> when(action) { is CompanyAction.Hire -> { val employees = prevState.employees.toMutableList() employees.add(action.employee) prevState.copy(employees = employees) } is CompanyAction.Add -> { val requisitions = prevState.requisitions.toMutableList() requisitions.add(action.requisition) prevState.copy(requisitions = requisitions) } } }) .subscribe { state -> println("These numbers are most likely inaccurate.") println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.") println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.") println("Here is the raw state output:") println(state) }
  • 47. @POTUS404RxJava Observable.fromPublisher<CompanyAction> { subscriber -> 0.until(320).map { if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee) } .forEach { subscriber.onNext(it) } .also { subscriber.onComplete() } } .reduceWith({ Company("ActiveCampaign") }, { prevState, action -> when(action) { is CompanyAction.Hire -> { val employees = prevState.employees.toMutableList() employees.add(action.employee) prevState.copy(employees = employees) } is CompanyAction.Add -> { val requisitions = prevState.requisitions.toMutableList() requisitions.add(action.requisition) prevState.copy(requisitions = requisitions) } } }) .subscribe { state -> println("These numbers are most likely inaccurate.") println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.") println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.") println("Here is the raw state output:") println(state) }
  • 48. @POTUS404RxJava Observable.fromPublisher<CompanyAction> { subscriber -> 0.until(320).map { if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee) }.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() } } .reduceWith({ Company("ActiveCampaign") }, { prevState, action -> when(action) { is CompanyAction.Hire -> { val employees = prevState.employees.toMutableList() employees.add(action.employee) prevState.copy(employees = employees) } is CompanyAction.Add -> { val requisitions = prevState.requisitions.toMutableList() requisitions.add(action.requisition) prevState.copy(requisitions = requisitions) } } }) .subscribe { state -> println("These numbers are most likely inaccurate.") println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.") println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.") println("Here is the raw state output:") println(state) }
  • 49. @POTUS404RxJava Observable.fromPublisher<CompanyAction> { subscriber -> 0.until(320).map { if (it % 11 == 0) CompanyAction.Add(Requisition.requisition) else CompanyAction.Hire(Requisition.requisition, Employee.employee) }.forEach { subscriber.onNext(it) }.also { subscriber.onComplete() } } .reduceWith({ Company("ActiveCampaign") }, { prevState, action -> when(action) { is CompanyAction.Hire -> { val employees = prevState.employees.toMutableList() employees.add(action.employee) prevState.copy(employees = employees) } is CompanyAction.Add -> { val requisitions = prevState.requisitions.toMutableList() requisitions.add(action.requisition) prevState.copy(requisitions = requisitions) } } }) .subscribe { state -> println("These numbers are most likely inaccurate.") println("ActiveCampaign has ${state.requisitions.size} job openings with around ${state.employees.size} employees.") println("There are ${state.employees.filter { it.name == "Cody" }.size} employees named Cody.") println("Here is the raw state output:") println(state) }
  • 50. These numbers are most likely inaccurate. ActiveCampaign has 30 job openings with around 290 employees. There are 19 employees named Cody. Here is the raw state output: Company(name=ActiveCampaign, requisitions=[Requisition(name=Full Stack Engineer, department=Engineering), …) @POTUS404RxJava