Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactive and Functional Programming

Reactive and Functional Programming

Reactive and Functional Programming
Tales of failure and learning

Slides from my talk at Software Craftsmanship Florianópolis (Sept. 2, 2017). The talk contains some lessons learned during my experience with learning and evolving with Reactive Programming, Functional Programming and RxJava.

David Tiago Conceição

September 02, 2017
Tweet

More Decks by David Tiago Conceição

Other Decks in Programming

Transcript

  1. Asynchronous code • Callbacks someObject.longNetworkOperation( new NetworkOperationCallback() { void onOperationResult(Result

    result) { updateScreen(result); } void onSomethingWentWrong(WhatWentWrong what) { showError(what); } });
  2. Asynchronous code • Callbacks someObject.longNetworkOperation( new NetworkOperationCallback(){ void onOperationResult(Result result){

    anotherObject.doAnotherLongOperation( result, new NetworkOperationCallback(){ void onOperationResult(Result result){ finallyShowTheResult(result); ...
  3. Asynchronous code • Callbacks someObject.longNetworkOperation( new NetworkOperationCallback(){ void onOperationResult(Result result){

    anotherObject.doAnotherLongOperation( result, new NetworkOperationCallback(){ void onOperationResult(Result result){ finallyShowTheResult(result); } void onSomethingWentWrong(WhatWentWrong what){ showError(what); } } } void onSomethingWentWrong(WhatWentWrong what){ showError(what); } });
  4. Asynchronous code • Callbacks someObject.longNetworkOperation( new NetworkOperationCallback(){ void onOperationResult(Result result){

    anotherObject.doAnotherLongOperation( result, new NetworkOperationCallback(){ void onOperationResult(Result result){ runOnUiThread(new Runnable(){ void run(){ finallyShowTheResult(result); } }); } void onSomethingWentWrong(WhatWentWrong what){ runOnUiThread(new Runnable(){ showError(what); }); } } } void onSomethingWentWrong(WhatWentWrong what){ showError(what); } });
  5. Asynchronous code • Callbacks someObject.longNetworOperation( new NetworkOperationCallback(){ void onOperationResult(Result result){

    anotherObject.doAnotherLongOperation( result, new NetworkOperationCallback(){ void onOperationResult(Result result){ runOnUiThread(new Runnable(){ void run(){ finallyShowTheResult(result); } }); } void onSomethingWentWrong(WhatWentWrong what){ runOnUiThread(new Runnable(){ showError(what); }); } } } void onSomethingWentWrong(WhatWentWrong what){ showError(what); } }); https://storage.googleapis.com/material-design/publish/material_v_11/assets/0Bzhp5Z4wHba3NnpEM2lLc0NKd1U/notifications_templates_04_progress.png
  6. Asynchronous code • AsyncTasks private class NetworkOperation extends AsyncTask<Input, Integer,

    Long> { protected Long doInBackground(Input... inputs) { return someLongNetworkOperation(inputs); } protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } }
  7. Asynchronous code • IntentService public class NetworkService extends IntentService {

    @Override protected void onHandleIntent(Intent workIntent) { longNetworkOperation(workIntent); } }
  8. Reactive Extensions “An API for asynchronous programming with observable streams.”

    “The Observer pattern done right.” http://reactivex.io/
  9. RxJava • Creating an Observable Single.fromCallable(() -> { return someNetworkOperation();})

    .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  10. RxJava • Creating an Observable Single.fromCallable(() -> { return someNetworkOperation();

    }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  11. RxJava • Creating an Observable Single.fromCallable(() -> { return someNetworkOperation();

    }) .flatMap(networkResult -> { return anotherNetworkOperation(networkResult); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  12. RxJava • Creating an Observable compositeDisposable = new CompositeDisposable(); //

    ... compositeDisposable.add(createStream()); // ... compositeDisposable.clear(); https://storage.googleapis.com/material-design/publish/material_v_11/assets/0Bzhp5Z4wHba3NnpEM2lLc0NKd1U/notifications_templates_04_progress.png
  13. RxJava • Create Single.fromCallable(() -> { return someNetworkOperation();}) .subscribeWith(new DisposableSingleObserver<NetworkResult>()

    { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  14. RxJava • Combine Single.fromCallable(() -> { return someNetworkOperation(); }) .flatMap(networkResult

    -> { return anotherNetworkOperation(networkResult); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  15. RxJava • Listen Single.fromCallable(() -> { return someNetworkOperation(); }) .flatMap(networkResult

    -> { return anotherNetworkOperation(networkResult); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  16. RxJava • Stream Single.fromCallable(() -> { return someNetworkOperation(); }) .flatMap(networkResult

    -> { return anotherNetworkOperation(networkResult); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSingleObserver<NetworkResult>() { public void onSuccess(NetworkResult result) { updateScreen(result); } public void onError(Throwable e) { showError(e); } });
  17. Growing Strong • Start composing ◦ Large streams composed by

    smaller • Less logic • More data flow
  18. Growing Strong class SomeNetworkClass { Observable<NetworkResponse> longNetworkOperation(Parameters parameters){ // Compose

    networkParameters return NetworkLibrary.createNetworkRequest(networkParameters); } } // ... someNetworkInstance.longNetworkOperation(parameters) .doOnNext(Cache::saveToCache) .subscribeWith( // subscriber ...
  19. Growing Strong class SomeNetworkClass { Observable<NetworkResponse> longNetworkOperation(Parameters parameters){ // Compose

    networkParameters return NetworkLibrary.createNetworkRequest(networkParameters); } } // ... someNetworkInstance.longNetworkOperation(parameters) .doOnNext(Cache::saveToCache) .subscribeWith( // subscriber ...
  20. Race Conditions moviesRemoteRepository.getUpcoming(currentPageCount) .map(new Function<Movie, Movie>() { public Movie apply(Movie

    movie) throws Exception { return MovieUtil.mapMovieFields( movie, imageConfiguration, genres); } }) .toList() //...
  21. Race conditions moviesRemoteRepository.getUpcoming(currentPageCount) .map(new Function<Movie, Movie>() { public Movie apply(Movie

    movie) throws Exception { return MovieUtil.mapMovieFields( movie, imageConfiguration, genres); } }) .toList() //...
  22. Reactive Extensions “ReactiveX is a combination of the best ideas

    from the Observer pattern, the Iterator pattern, and functional programming.” http://reactivex.io/
  23. Functional Programming • Mathematical concepts • High order functions •

    Immutability • Lambdas • Monads • Pure functions
  24. Pure Functions • Output determined by the input • No

    side effects • An input generates always the same output
  25. Pure Functions • Easily processed in parallel ◦ Highly scalable

    • Independent Streams • Easy to read, maintain and test
  26. Handling errors • onError invalidates the stream • Error as

    state • Propagate an error state • Avoids invalidation
  27. How to know more? • ReactiveX reactivex.io • RxJava for

    Android App Development oreilly.com/programming/free/rxjava-for-android-app-development.csp • Reactive Programming on Android with RxJava leanpub.com/reactiveandroid • Managing State with RxJava by Jake Wharton www.youtube.com/watch?v=0IKHxjkgop4 • Object-Oriented vs. Functional Programming oreilly.com/programming/free/object-oriented-vs-functional-programming.csp
  28. Thank you! David Tiago Conceição Android Developer @ Involves Android

    Dev BR @davidtiagoconceicao twitter.com/@davidtiagocon github.com/davidtcdeveloper Slides