Introduction to Reactive Programming
https://github.com/TechFreak/RxTalk
But First
Observer Pattern
Observer Pattern
"The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods."
Observer Pattern
Enter Reactive Programming
"Programming paradigm oriented around data flows and the propagation of change."
AKA The Excel Pattern
- You create a formula A1+B1
- A1 value is updated
- The formula is automagically updated
- Pull vs Push
Reactive extends the Observer pattern
- Observable
- Subscriber
- Subject
ReactiveX
- Group supported by Netflix, Microsoft, SoundCloud, Github, Trello and others.
-
Bindings for reactive programming available for most languages and Platforms
-
Languages:
- Java: RxJava
- Swift: RxSwift
- Kotlin: RxKotlin
- Javascript: RxJS
- Platforms:
- Cocoa: RxCocoa
- Android: RxAndroid
-
Languages:
Data flow
Observable - Subscriber
But Why?????
Concurrency is hard
- "Multithreading is always complex"
- "Callbacks have their own problems"
- "Java Futures are expensive to compose"
Ben Christensen from Netflix
Simplify Concurrency
- Turn everything into a stream of data
- Our business logic now simply "reacts" to the stream of data
- We get multi threading for free, we now simply tell in which thread our operations need to happen
Sample 1
Observable repos = githubApi.getRepos();
repos.subscribeOn(Schedulers.io()) <----- Multithreading
.observeOn(Schedulers.mainThread());
.subscribe( data-> showData(data) ); <----- Subscriber
The beauty of Reactive Programming comes when we use operators
Operators: Filter
Operators: First
Emit only the first item (or the first item that meets some condition) emitted by an Observable
Operators: Concat
Emit the emissions from two or more Observables without interleaving them
Operators:Debounce
Only emit an item from an Observable if a particular timespan has passed without it emitting another item
Operators: FlatMap
Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
Sample 2
- Implement a "search as you type" interface
- The user enters a search term into a text field and the app must start showing the results for that search two seconds after the user has finished typing
- A valid search must have more than 3 characters
Observable searchTermChanged = ......;
searchTermChanged.debounce(2, TimeUnit.SECONDS)
.filter(onTextChangeEvent -> onTextChangeEvent.text().length() > 3)
.flatMap(onTextChangeEvent -> callSearchWebService(onTextChangeEvent.text())
.subscribe(searchResults -> showSearchResults(searchResults));
Sample 3
- Implement a two level cache for offline viewing of data fetched from a web service
- First Level: the data must be cached to disk
- Second Level: the data must be cached in memory
- And finally after a period of time new data must be fetched from the server and the cache needs to be refreshed
// Our sources
Observable memory = ...;
Observable disk = ...;
Observable network = ...;
// Save data into next cache as soon as
// it starts flowing
Observable network = network.doOnNext(data -> {
saveToDisk(data);
});
Observable disk = disk.doOnNext(data -> {
cacheInMemory(data);
});
// Retrieve the first source with data
Observable source = Observable
.concat(memory, disk, network)
.first(data -> data.isUpToDate()) <-- Only allow fresh data
.subscribe(data -> doSomething(data));
Conclusions
- As always a new library/framework must be chosen carefully depending on your particular requirements
- Reactive Programming allows you to think in terms of sources of data and operations which simplifies a lot of complex use cases
Thank you!
References
Introduction to Reactive Programming
By Julián Suárez
Introduction to Reactive Programming
- 1,102