SlideShare ist ein Scribd-Unternehmen logo
1 von 163
Downloaden Sie, um offline zu lesen
Unidirectional data flow
on Android
… using Kotlin
@CesarValiente@CesarValiente
Who is this guy?
Image Placeholder
César Valiente
Android Engineer @Microsoft
Android Google Developer Expert (GDE)
@CesarValiente@CesarValiente
Unidirectional?
A B
Unidirectional?
A B
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
Can we have more steps?
A
B
Z
C D E
…
History
Flux Redux
Flux and Redux
Flux and Redux
Architectures based in unidirectional data flows.
Flux and Redux
Architectures based in unidirectional data flows.
We start in A and we finish in A.
Flux and Redux
Architectures based in unidirectional data flows.
We start in A and we finish in A.
Global app state. State has everything the App needs.
Flux
View
Action
Dispatcher
Store
Flux
DISPATCHER STORE VIEW
ACTION
Flux
DISPATCHER STORE VIEW
ACTION
Flux
DISPATCHER STORE VIEW
ACTION
Flux
DISPATCHER STORE VIEW
ACTION
Flux
DISPATCHER STORE VIEW
ACTION
Flux
ACTION DISPATCHER STORE VIEW
ACTION
Flux
ACTION DISPATCHER STORE VIEW
ACTION
Redux
Actions
Reducers
Store
Middleware (optional).
Redux
REDUCER VIEW
ACTION
STORE
Redux
REDUCER VIEW
ACTION
STORE
Redux
REDUCER VIEW
ACTION
STORE
Redux
REDUCER VIEW
ACTION
STORE
Redux
ACTION REDUCER VIEW
ACTION
STORE
Redux
ACTION REDUCER VIEW
ACTION
STORE
Why?(are we following this approach)
We use a mix of both
We use a mix of both
We have actions that describe what we want to do.
We use a mix of both
We have actions that describe what we want to do.
We have store.
We use a mix of both
We have actions that describe what we want to do.
We have store.
We have dispatcher that dispatch actions and new states.
Subscribers are subscribed to it.
We use a mix of both
We have actions that describe what we want to do.
We have store.
We have dispatcher that dispatch actions and new states.
Subscribers are subscribed to it.
We have reducers. Given an action return a new state.
We use a mix of both
We have actions that describe what we want to do.
We have store.
We have dispatcher that dispatch actions and new states.
Subscribers are subscribed to it.
We have reducers. Given an action return a new state.
We have middleware that extends our model (persistence, network, etc.)
We use a mix of both
We have actions that describe what we want to do.
We have store.
We have dispatcher that dispatch actions and new states.
Subscribers are subscribed to it.
We have reducers. Given an action return a new state.
We have middleware that extends our model (persistence, network, etc.)
We have ControllerView (we are in Android though :-) ).
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER MIDDLEWARE
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER MIDDLEWARE
STORE
Action
State
User interaction
UI Data
Optional Action
Our approach
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER MIDDLEWARE
STORE
Action
State
User interaction
UI Data
Optional Action
Dependencies
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
MIDDLEWARE
MIDDLEWARE
STORE
Dependencies
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
MIDDLEWARE
MIDDLEWARE
STORE
ANDROID
NO FRAMEWORK DEPENDENCIES
Dependencies
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
MIDDLEWARE
MIDDLEWARE
STORE
ANDROID
NO FRAMEWORK
DEPENDENCIES
ANDROID
NO FRAMEWORK DEPENDENCIES
Dependencies
ACTION
REDUCER
VIEW CONTROLLER-VIEW
STATE DISPATCHER ACTION DISPATCHER
MIDDLEWARE
MIDDLEWARE
STORE
ANDROID
KUnidirectional
KUnidirectional
OSS App created to show this architecture
on Android.
KUnidirectional
OSS App created to show this architecture
on Android.
A simple item list.
KUnidirectional
OSS App created to show this architecture
on Android.
A simple item list.
Everything is unidirectional.
KUnidirectional
OSS App created to show this architecture
on Android.
A simple item list.
Everything is unidirectional.
No external libraries, just Kotlin + Android.
View
View
Are Activities and Fragments.
View
Are Activities and Fragments.
It receives data from the ControllerView and uses it to update it self.
View
Are Activities and Fragments.
It receives data from the ControllerView and uses it to update it self.
It communicates with the ControllerView through an interface.
View
Are Activities and Fragments.
It receives data from the ControllerView and uses it to update it self.
We instantiate rest of the components here.
It communicates with the ControllerView through an interface.
ControllerView
ControllerView
“Man in the middle” between UI and everything else.
ControllerView
“Man in the middle” between UI and everything else.
Powered presenter.
ControllerView
“Man in the middle” between UI and everything else.
Powered presenter.
1 Activity/1Fragment -> 1 Controller-View.
ControllerView
“Man in the middle” between UI and everything else.
Powered presenter.
1 Activity/1Fragment -> 1 Controller-View.
Dispatches actions.
ControllerView
“Man in the middle” between UI and everything else.
Powered presenter.
1 Activity/1Fragment -> 1 Controller-View.
Dispatches actions.
Subscribes to state changes.
abstract class ControllerView(

protected val actionDispatcher: ActionDispatcher,

protected val stateDispatcher: StateDispatcher)

: Application.ActivityLifecycleCallbacks, Subscriber<State> {

protected fun <T : Action> dispatch(action: T) {

actionDispatcher.dispatch(action)

}



override fun onNext(data: State) {

if (isActivityRunning) handleState(state)

}



abstract fun handleState(state: State)

}
Action
Action
Are the intentions, what we want to do.
Action
Are the intentions, what we want to do.
They have metadata.
Action
Are the intentions, what we want to do.
They have metadata.
They will be reduced and/or applied.
sealed class Action

sealed class UpdateAction : Action() {

data class ReorderItemsAction(val items: List<Item>) : UpdateAction()



data class UpdateItemAction(val localId: String,

val text: String?,

val color: Color) : UpdateAction()



data class UpdateFavoriteAction(
val localId: String, val favorite: Boolean) : UpdateAction()



data class UpdateColorAction(
val localId: String, val color: Color) : UpdateAction()

}

Dispatcher
Dispatcher
Used to dispatch data. An action or a new state.
Dispatcher
Used to dispatch data. An action or a new state.
Subscribers subscribe to it, listening for a new action or state.
Dispatcher
Used to dispatch data. An action or a new state.
Subscribers subscribe to it, listening for a new action or state.
Subscribers can unsubscribe.
DISPATCHER
STATE DISPATCHER ACTION DISPATCHER
DISPATCHER
STATE DISPATCHER ACTION DISPATCHER
DISPATCHER
abstract class Dispatcher<T> {

private val subscriptions = ArrayList<Subscriber<T>>()



fun subscribe(subscriber: Subscriber<T>): Boolean =

subscriptions.add(subscriber)



fun unsubscribe(subscriber: Subscriber<T>): Boolean =

subscriptions.remove(subscriber)



fun isEmpty(): Boolean =

subscriptions.isEmpty()



open fun dispatch(data: T) =

subscriptions.forEach { it.onNext(data) }



fun isSubscribed(subscriber: Subscriber<T>): Boolean {

val isSubscribed = subscriptions.find { it == subscriber }

return isSubscribed != null

}

}
Store
Store
It has the State of the app.
Store
Is subscribed to handle Actions.
It has the State of the app.
Store
Is subscribed to handle Actions.
It will use its Reducers to reduce an Action and dispatch a new State.
It has the State of the app.
State
enum class Navigation {

ITEMS_LIST,

EDIT_ITEM

}

data class ItemsListScreen(

val items: List<Item> = emptyList())



data class EditItemScreen(val currentItem: Item = Item())



data class State(

val itemsListScreen: ItemsListScreen = ItemsListScreen(),

val editItemScreen: EditItemScreen = EditItemScreen(),

val navigation: Navigation = Navigation.ITEMS_LIST)
State is immutable.
Store Action Subscriber
open class StoreActionSubscriber(actionDispatcher: ActionDispatcher,

val stateDispatcher: StateDispatcher)

: ActionSubscriber(actionDispatcher) {


override fun reduce(action: Action) {

val currentState = stateDispatcher.state

val newState = when (action) {

is CreationAction -> CreationReducer.reduce(action, currentState)

is UpdateAction -> UpdateReducer.reduce(action, currentState)

is ReadAction -> ReadReducer.reduce(action, currentState)

is DeleteAction -> DeleteReducer.reduce(action, currentState)

is NavigationAction -> NavigationReducer.reduce(action, currentState)

}

stateDispatcher.dispatch(newState)

}

}
Reducer
Reducer
Reduces an action to create a new state.
Reducer
Reduces an action to create a new state.
Reduces every part of the state independently.
Reducer
Reduces an action to create a new state.
Reduces every part of the state independently.
The resulted new state will be dispatched.
REDUCER
STORE
ACTION
CURRENT STATE
REDUCER
STORE
ACTION
CURRENT STATE
REDUCER
STORE
ACTION NEW STATE
CURRENT STATE
abstract class Reducer<in T : Action> {



open fun reduce(action: T, currentState: State) =

with(currentState) {

currentState.copy(

itemsListScreen = reduceItemsListScreen(action, itemsListScreen),

editItemScreen = reduceEditItemScreen(action, editItemScreen),

navigation = reduceNavigation(action, navigation)

)

}
open fun reduceItemsListScreen(action: T, itemsListScreen: ItemsListScreen) =

itemsListScreen.copy(
items = reduceItemsCollection(action, itemsListScreen.items))



open fun reduceItemsCollection(action: T, currentItems: List<Item>) =

currentItems.findAndMap(

find = { shouldReduceItem(action, it) },

map = { changeItemFields(action, it) })
open fun reduceEditItemScreen(action: T, editItemScreen: EditItemScreen) =

editItemScreen.copy(

currentItem = reduceCurrentItem(
action, editItemScreen.currentItem))



open fun reduceCurrentItem(action: T, currentItem: Item) =

if (shouldReduceItem(action, currentItem))
changeItemFields(action, currentItem)

else currentItem

open fun shouldReduceItem(action: T, currentItem: Item) = false



open fun changeItemFields(action: T, currentItem: Item) = currentItem



open fun reduceNavigation(action: T, currentNavigation: Navigation) = currentNavigation


}
Models
STORE
STORE
MODELS
Models
STORE
STORE
MODELS
PRESENTATION
STORE MODELS +
EXTENSIONS
Models
STORE
STORE
MODELS
PRESENTATION
STORE MODELS +
EXTENSIONS
Models
PERSISTENCE
PERSISTENCE
MODELS
MAPPER
enum class Color {

RED, YELLOW, GREEN, BLUE, WHITE

}



data class Item(

val localId: String = generateLocalId(),

val text: String? = null,

val favorite: Boolean = false,

val color: Color = Color.WHITE,

val position: Long = object : PositionsFactory {}.newPosition())
Store Models
enum class Color {

RED, YELLOW, GREEN, BLUE, WHITE

}



@RealmClass

open class Item() : RealmModel {

constructor(localId: String, text: String?, favorite: Boolean = false,

colorEnum: Color = Color.WHITE, position: Long) : this() {

this.localId = localId

this.text = text

this.favorite = favorite

this.color = colorEnum.name

this.position = position

}
Persistence Models
@PrimaryKey open var localId: String = ""

open var text: String? = null

open var favorite: Boolean = false

@Ignore private var colorEnum: Color = Color.WHITE

open var color: String = colorEnum.name

open var position: Long = 0



fun getColorAsEnum(): Color = Color.valueOf(color)



fun setColorAsEnum(color: Color) {

this.color = color.name

}
//Equals and hashcode since Realm doesn’t allow data classes
}
Persistence Models (2)
import com.cesarvaliente.kunidirectional.persistence.Color as PersistenceColor

import com.cesarvaliente.kunidirectional.persistence.Item as PersistenceItem

import com.cesarvaliente.kunidirectional.store.Color as StoreColor

import com.cesarvaliente.kunidirectional.store.Item as StoreItem
Mapper
fun StoreItem.toPersistenceItem(): PersistenceItem =

with(this) {

PersistenceItem(localId, text, favorite, color.toPersistenceColor(), position)

}



fun StoreColor.toPersistenceColor(): PersistenceColor =

when (this) {

StoreColor.BLUE -> PersistenceColor.BLUE

StoreColor.GREEN -> PersistenceColor.GREEN

StoreColor.RED -> PersistenceColor.RED

StoreColor.WHITE -> PersistenceColor.WHITE

StoreColor.YELLOW -> PersistenceColor.YELLOW

}
Presentation models?
fun Color.toColorResource(): Int =

when (this) {

RED -> R.color.red

YELLOW -> R.color.yellow

GREEN -> R.color.green

BLUE -> R.color.blue

WHITE -> R.color.white

}



fun Item.getStableId(): Long = this.localId.hashCode().toLong()
Middleware
Middleware
We can have as much middleware as we want.
Middleware
We can have as much middleware as we want.
Middleware is subscribed listening for Actions.
Middleware
We can have as much middleware as we want.
Middleware is subscribed listening for Actions.
Middleware can return a new Action after “apply” the previous one.
ACTION DISPATCHER
ACTION DISPATCHER
MIDDLEWARE 1
ACTION DISPATCHER
MIDDLEWARE 1
ACTION DISPATCHER
MIDDLEWARE 1
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE 2
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE 2
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE 2
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE N
MIDDLEWARE 2
.
.
.
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE N
MIDDLEWARE 2
.
.
.
ACTION DISPATCHER
MIDDLEWARE 1
MIDDLEWARE N
MIDDLEWARE 2
.
.
.
Threading?
VIEW STORE PERSISTENCE
MIDDLEWARE
Threading?
VIEW STORE PERSISTENCE
MIDDLEWARE
UI Thread
Threading?
VIEW STORE PERSISTENCE
MIDDLEWARE
UI Thread Store Thread
Threading?
VIEW STORE PERSISTENCE
MIDDLEWARE
UI Thread Store Thread
Persistence
Thread
(MiddlewareN Thread)
Testing?
Testing?
UI tests on Presentation layer (View).
Testing?
UI tests on Presentation layer (View).
Unit tests + Integration tests on our ControllerViews.
Testing?
UI tests on Presentation layer (View).
Unit tests + Integration tests on our ControllerViews.
Acceptance tests in our Persistence layer (middleware).
Testing?
UI tests on Presentation layer (View).
Unit tests + Integration tests on our ControllerViews.
Acceptance tests in our Persistence layer (middleware).
Unit tests in our Store layer.
Demo time(1)!
Demo time(1)!
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(1)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(1)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
EMPTY ITEM
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(1)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
EMPTY ITEM
SAVE ITEM NEW ITEM
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(1)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
EMPTY ITEM
SAVE ITEM NEW ITEM
TO NOTE LIST NAVIGATION UPDATED
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(1)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
EMPTY ITEM
SAVE ITEM NEW ITEM
TO NOTE LIST NAVIGATION UPDATED
FETCH LIST
ITEMS
LIST ITEMS
FETCH LIST
ITEMS
LIST ITEMS
Action
State
Demo time(2)!
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
Action
State
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
CURRENT ITEM
Action
State
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
CURRENT ITEM
CHANGE COLOR CURRENT ITEM x 6
Action
State
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
CURRENT ITEM
SAVE ITEM ITEM UPDATED
CHANGE COLOR CURRENT ITEM x 6
Action
State
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
CURRENT ITEM
SAVE ITEM ITEM UPDATED
TO NOTE LIST NAVIGATION UPDATED
CHANGE COLOR CURRENT ITEM x 6
Action
State
Demo time(2)!
OPEN EDIT ITEM NAVIGATION UPDATED
FETCH ITEM
DETAILS
CURRENT ITEM
SAVE ITEM ITEM UPDATED
TO NOTE LIST NAVIGATION UPDATED
FETCH LIST
ITEMS
LIST ITEMS
CHANGE COLOR CURRENT ITEM x 6
Action
State
Demo time(3)!
Demo time(3)!
SET AS FAVORITE ITEM UPDATED x 3
Action
State
Demo time(4)!
Demo time(4)!
Demo time(4)!
REORDER ITEMS UPDATED x 2
Action
State
Demo time(5)!
Demo time(5)!
Action
State
DELETE ITEM ITEMS UPDATED x 2
Last demo!
The cool thing of middleware
in this architecture with
decoupled elements.
? @CesarValiente@CesarValiente
Thanks!
@CesarValiente@CesarValiente
Useful Links
KUnidirectional app: https://github.com/CesarValiente/KUnidirectional
KUnidirectional demo videos: https://goo.gl/PIfjr5
Flux: https://facebook.github.io/flux/
Redux: http://redux.js.org/
Flux on Android: https://github.com/lgvalle/android-flux-todo-app
License
(cc) 2017 César Valiente.
Some rights reserved.
This document is distributed under the Creative
Commons Attribution-ShareAlike 3.0 license, available in
http://creativecommons.org/licenses/by-sa/3.0/
Image licenses
Flux and Redux images are property of Facebook.
Emojis by Emoji One (CC-BY): http://emojione.com/

Weitere ähnliche Inhalte

Ähnlich wie Cesar Valiente "Unidirectional architecture on Android with Kotlin"

ReSwift & Machine Learning
ReSwift & Machine LearningReSwift & Machine Learning
ReSwift & Machine LearningRodrigo Leite
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android AppsGil Irizarry
 
HIT3328 - Chapter04 - Complex Interactions
HIT3328 - Chapter04 - Complex InteractionsHIT3328 - Chapter04 - Complex Interactions
HIT3328 - Chapter04 - Complex InteractionsYhal Htet Aung
 
Me and my importers
Me and my importersMe and my importers
Me and my importersDonny Wals
 
iOS Architectures
iOS ArchitecturesiOS Architectures
iOS ArchitecturesHung Hoang
 
Behavioral Design Patterns
Behavioral Design PatternsBehavioral Design Patterns
Behavioral Design PatternsLidan Hifi
 
MongoDB Mobile
MongoDB Mobile MongoDB Mobile
MongoDB Mobile MongoDB
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in AndroidRobert Cooper
 
Postgres Conf Keynote: What got you here WILL get you there
Postgres Conf Keynote: What got you here WILL get you therePostgres Conf Keynote: What got you here WILL get you there
Postgres Conf Keynote: What got you here WILL get you thereAnant Jhingran
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Databricks
 
TKU行動APP開發管理實務 - ListView & Custom Adapter
TKU行動APP開發管理實務 - ListView & Custom AdapterTKU行動APP開發管理實務 - ListView & Custom Adapter
TKU行動APP開發管理實務 - ListView & Custom AdapterXavier Yin
 
Programming the Physical World with Device Shadows and Rules Engine
Programming the Physical World with Device Shadows and Rules EngineProgramming the Physical World with Device Shadows and Rules Engine
Programming the Physical World with Device Shadows and Rules EngineAmazon Web Services
 
Três conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsTrês conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsGuilherme Rambo
 
Hello, ReactorKit 
Hello, ReactorKit Hello, ReactorKit 
Hello, ReactorKit Suyeol Jeon
 
Cloud Roundtable | Amazon Web Services: Key = Iteration
Cloud Roundtable | Amazon Web Services: Key = IterationCloud Roundtable | Amazon Web Services: Key = Iteration
Cloud Roundtable | Amazon Web Services: Key = IterationCodemotion
 
Types Working for You, Not Against You
Types Working for You, Not Against YouTypes Working for You, Not Against You
Types Working for You, Not Against YouC4Media
 
HIT3328 - Chapter03 - Simple Interactive Apps
HIT3328 - Chapter03 - Simple Interactive AppsHIT3328 - Chapter03 - Simple Interactive Apps
HIT3328 - Chapter03 - Simple Interactive AppsYhal Htet Aung
 

Ähnlich wie Cesar Valiente "Unidirectional architecture on Android with Kotlin" (20)

ReSwift & Machine Learning
ReSwift & Machine LearningReSwift & Machine Learning
ReSwift & Machine Learning
 
Thinking in react
Thinking in reactThinking in react
Thinking in react
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android Apps
 
Software-defined Networks as Databases
Software-defined Networks as DatabasesSoftware-defined Networks as Databases
Software-defined Networks as Databases
 
HIT3328 - Chapter04 - Complex Interactions
HIT3328 - Chapter04 - Complex InteractionsHIT3328 - Chapter04 - Complex Interactions
HIT3328 - Chapter04 - Complex Interactions
 
Me and my importers
Me and my importersMe and my importers
Me and my importers
 
Functional Reactive Programming
Functional Reactive ProgrammingFunctional Reactive Programming
Functional Reactive Programming
 
iOS Architectures
iOS ArchitecturesiOS Architectures
iOS Architectures
 
Behavioral Design Patterns
Behavioral Design PatternsBehavioral Design Patterns
Behavioral Design Patterns
 
MongoDB Mobile
MongoDB Mobile MongoDB Mobile
MongoDB Mobile
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
Postgres Conf Keynote: What got you here WILL get you there
Postgres Conf Keynote: What got you here WILL get you therePostgres Conf Keynote: What got you here WILL get you there
Postgres Conf Keynote: What got you here WILL get you there
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
 
TKU行動APP開發管理實務 - ListView & Custom Adapter
TKU行動APP開發管理實務 - ListView & Custom AdapterTKU行動APP開發管理實務 - ListView & Custom Adapter
TKU行動APP開發管理實務 - ListView & Custom Adapter
 
Programming the Physical World with Device Shadows and Rules Engine
Programming the Physical World with Device Shadows and Rules EngineProgramming the Physical World with Device Shadows and Rules Engine
Programming the Physical World with Device Shadows and Rules Engine
 
Três conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus appsTrês conceitos que farão a diferença nos seus apps
Três conceitos que farão a diferença nos seus apps
 
Hello, ReactorKit 
Hello, ReactorKit Hello, ReactorKit 
Hello, ReactorKit 
 
Cloud Roundtable | Amazon Web Services: Key = Iteration
Cloud Roundtable | Amazon Web Services: Key = IterationCloud Roundtable | Amazon Web Services: Key = Iteration
Cloud Roundtable | Amazon Web Services: Key = Iteration
 
Types Working for You, Not Against You
Types Working for You, Not Against YouTypes Working for You, Not Against You
Types Working for You, Not Against You
 
HIT3328 - Chapter03 - Simple Interactive Apps
HIT3328 - Chapter03 - Simple Interactive AppsHIT3328 - Chapter03 - Simple Interactive Apps
HIT3328 - Chapter03 - Simple Interactive Apps
 

Mehr von IT Event

Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...IT Event
 
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"IT Event
 
Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...IT Event
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "IT Event
 
Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"IT Event
 
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"IT Event
 
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"IT Event
 
Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"IT Event
 
Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"IT Event
 
Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"IT Event
 
James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"IT Event
 
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...IT Event
 
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"IT Event
 
Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"IT Event
 
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"IT Event
 
Наш ответ Uber’у
Наш ответ Uber’уНаш ответ Uber’у
Наш ответ Uber’уIT Event
 
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"IT Event
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"IT Event
 
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...IT Event
 
Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"IT Event
 

Mehr von IT Event (20)

Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
Denis Radin - "Applying NASA coding guidelines to JavaScript or airspace is c...
 
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
Sara Harkousse - "Web Components: It's all rainbows and unicorns! Is it?"
 
Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
 
Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"Konstantin Krivlenia - "Continuous integration for frontend"
Konstantin Krivlenia - "Continuous integration for frontend"
 
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
Illya Klymov - "Vue.JS: What did I swap React for in 2017 and why?"
 
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
Evgeny Gusev - "A circular firing squad: How technologies drag frontend down"
 
Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"Vladimir Grinenko - "Dependencies in component web done right"
Vladimir Grinenko - "Dependencies in component web done right"
 
Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"Dmitry Bartalevich - "How to train your WebVR"
Dmitry Bartalevich - "How to train your WebVR"
 
Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"Aleksey Bogachuk - "Offline Second"
Aleksey Bogachuk - "Offline Second"
 
James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"James Allardice - "Building a better login with the credential management API"
James Allardice - "Building a better login with the credential management API"
 
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...Fedor Skuratov "Dark Social: as messengers change the market of social media ...
Fedor Skuratov "Dark Social: as messengers change the market of social media ...
 
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
Андрей Зайчиков "Архитектура распределенных кластеров NoSQL на AWS"
 
Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"Алексей Рагозин "Java и linux борьба за микросекунды"
Алексей Рагозин "Java и linux борьба за микросекунды"
 
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
Volodymyr Lyubinets "Introduction to big data processing with Apache Spark"
 
Наш ответ Uber’у
Наш ответ Uber’уНаш ответ Uber’у
Наш ответ Uber’у
 
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"Александр Крашенинников "Hadoop High Availability: опыт Badoo"
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
 
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
Анатолий Пласковский "Миллионы карточных платежей за месяц, или как потерять ...
 
Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"Mete Atamel "Resilient microservices with kubernetes"
Mete Atamel "Resilient microservices with kubernetes"
 

Kürzlich hochgeladen

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

Kürzlich hochgeladen (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Cesar Valiente "Unidirectional architecture on Android with Kotlin"