Click here to load reader
View
132
Download
0
Embed Size (px)
RXJAVAPROGRAMAO REATIVA FUNCIONAL COM
UBIRATAN SOARESMARO / 2016
MOTIVAO
Java8 trouxe uma API de Streams, que permite operaes comuns sobre colees como Map, Filter, Reduce
Java9 trar uma API de ReactiveStreams, adotadando muitos conceitos presentes em RxJava diretamente no JDK
Funcional Programming ajuda a escrever cdigo mais robusto e conciso de maneira geral
ERIK MEIJER
Do ponto de vista de fluxo de dados, qual a diferena entre consultar o DB e processar as posies do ponteiro do mouse ???
VELHOS PROBLEMAS SEMPRE NA MODA
Execuo orquestrada de cdigo de forma assncrona
Execuo e sincronizao de processamento concorrente
Tratamento de erros
Escalabilidade
UMA NOVA FORMA DE PENSAR
E se ao invs de buscar dados de forma assncrona, os dados chegassem at mim de forma assncrona ?
Reativo : algo que reage a um estmulo !!!
Fundamento matemtico : teoria da categorias !!!
POR QU REACTIVE PROGRAMMING
As demandas atuais tipicamente pedem aplicaes
Responsivas
Resilientes
Orientadas a eventos
Escalveis
HANS DOCKTER
Programar arte de encontrar as abstraes corretas
RELEITURA DE CONCEITOS
Pensamento em termos de fluxo de dados : eventos discretos e fluxo desses eventos
possvel reagir a eventos e combinar os mesmos
O estado do sistema deve mudar conforme a passagem de eventos no tempo
Eventos no fluxo so imutveis
Sistema que idealmente nunca bloqueia (I/O, clculos, etc)
DADOS E SINCRONICIDADE
Um valor Mltiplos valores
Sncrona T getData( ) Iterable getData( )
Assncrona Future getData( ) Observable getData( )
RELEITURA DE CONTRATOS
Iterable Observer
Obter o prximo T next( ) onNext( T )
Sinalizar erro throws Exception( ) onError( Thowable )
Saber se terminou hasNext( ) onComplete( )
PULLED WAY
PUSHED WAY
CONCEITOS BSICOS
OBSERVABLE
OBSERVER
OPERATOR
SCHEDULER
OBSERVABLE
Representa o fluxo de dados (ou eventos, ou itens emitidos)
Por padro, executa de forma sequencial (no concorrente)
Repassa cada item emitido para um observador (callback)
Pode ser associado ao conceito de source da Streams API do java8, porm seguindo push model quanto aos dados
CRIANDO OBSERVABLES (I)
Observable source = Observable.just("GOOGLE", "APPLE", "MICROSOFT");
source.subscribe(System.out::println);
GOOGLEAPPLEMICROSOFT
PROCESS FINISHED WITH EXIT CODE 0
CRIANDO OBSERVABLES (II)
Observable.fromCallable(() -> RxJava is Awesome)
.subscribe(System.out::println);
List names = Arrays.asList("Banana", "Apple", "Orange");
Observable.from(names).subscribe(System.out::println);
CRIANDO OBSERVABLES (III)
Observable.interval(1, TimeUnit.SECONDS)
.map(time -> "AT SECOND " + time)
.subscribe(System.out::println);
AT SECOND 0AT SECOND 1AT SECOND 2AT SECOND 3
WARNING : estamos roubando aqui, se voc executar esse cdigo, no ver esse log !!!!
OBSERVER
Consome o fluxo de dados
Respeita o contrato no estilo pushed data
o ponto no qual os erros flutuam : um erro que acontea durante uma operao interrompe a sequncia de emisses
Callbacks sinalizam o trmino da sequncia
Adies ao Observer Pattern do GOF
OBSERVER
public interface Observer {
}
void onCompleted();
void onError(Throwable e);
void onNext(T data);
PIPELINE DE OPERAES
Observable.from()
.flatMap()
.filter()
.map()
.observeOn()
.subscribeOn()
.subscribe();
upstream sequence
downstream sequence
Observable.zip( restApi.getAvaliableItems(), restApi.getRecommendedItems(clientId),
new ItemsResultsZipper())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List items) { } });
podemos fazer melhor ?
OPERADORES
Funes que permitem manipular a sequncia de eventos observveis, sejam os itens emitidos, seja a prpria sequncia (ou mltiplas delas)
Reactive Extensions define um enorme catlogo de operadores quanto semntica, em categorias bem definidas
CATEGORIA OPERADORES
CRIAO just( ), from( ), range( ), interval( ), defer( )
COMBINAO zip( ), merge( ), combineLatest( ), concat( )
TRANSFORMAO map( ), flatMap( ), concatMap( )
FILTRAGEM filter( ), take( ), skip( ), debounce( )
MUITO MAIS ! cache( ), replay( ), retry( ), retryWhen( )
MARBLE DIAGRAMS
A B C D E
onNext( ) chamado cinco vezes
MARBLE DIAGRAMS
A B C
1 2 3 4 5
x
I
onError( )
onCompleted( )
MAP
1 2 3 4 5
A B C D E
MAP { INT X -> CHAR Y }
FILTER
1 2 3 4 5
2 4
FILTER { INT X -> INT Y}
MERGE
1 3 5
2 4
1 2 3 4 5
MERGE
I
I
I
CONCAT
1 3 5
2 4
1 3 5 2 4
CONCAT
I
I
I
AMB
1 3 5
2 4
1 3 5
AMB
I
I
I
INTERVAL
INTERVAL {}
1 2 3 4 5
rxmarbles.comDisponvel como app Android
http://rxmarbles.com
SCHEDULER
Escalonador de trabalho entre threads distintas
Abstrao em volta de Executors ( java.util.concurrent )
Qualquer Observable pode ser produzido em um Scheduler e observado em outro
Mecanismo fundamental para aplicaes mveis
Observable.range(1, 2) .map(i -> i * 2) .observeOn(Schedulers.io()) .doOnNext(i -> System.out.println( "Emitting " + i + " on thread " + threadName())) .observeOn(Schedulers.computation()) .map(i -> i * 10) .subscribe(i -> System.out.println( "Received " + i + " on thread " + threadName()));
Emitting 2 on thread RxCachedThreadScheduler-1Received 20 on thread RxComputationThreadPool-3Emitting 4 on thread RxCachedThreadScheduler-1Received 40 on thread RxComputationThreadPool-3
sleep(3000);
Observable.just("Google", "Apple", "Microsoft", "IBM") .subscribleOn(Schedulers.computation()) .subscribe(s -> System.out.println( "Received " + s + " on thread " + threadName()));
Received Google on thread RxComputationThreadPool-1Received Apple on thread RxComputationThreadPool-1Received Microsoft on thread RxComputationThreadPool-1Received IBM on thread RxComputationThreadPool-1
sleep(3000);
NUNCIAS SOBRE SCHEDULERS (I)
Schedulers.io( ) encapsula um thread pool de tamanho varivel
Schedulers.computation( ) encapsula um thread pool de tamanho fixo
Operam sobre deamon threads
So extensveis para encapsular threads importantes, como por exemplo a UI thread do Android ou do JavaFX
Alguns factory methods de Observable j associam um scheduler sequncia (como interval( ) )
NUNCIAS SOBRE SCHEDULERS (II)
subscribeOn( ) instrui o framework sobre em qual thread os itens sero emitidos para o consumidor
observeOn( ) instrui o framework sobre quais schedulers podem operar nas etapas intermedirias do pipeline de operaes
subscribeOn( ) em geral usado uma vez no pipeline
observeOn( ) utilizado conforme a necesside de concorrncia nas etapas do pipeline
TRATAMENTO DE ERROS
Evento terminal destri a sequncia. Period.
Recuperao controlada via operadores onErrorResumeNext( ), onErrorReturn( ) e outros
Sugesto : implemente um wrapper com o retorno de onError( throwable), isso ajudar no stacktrace em casos de erro
CONCEITOS AVANADOS
FLATMAP
"Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
The FlatMap operator transforms an Observable by applying a function that you specify to each item emitted by the source Observable, where that function returns an Observable that itself emits items. FlatMap then merges the emissions of these resulting Observables, emitting these merged results as its own sequence.
This method is useful, for example, when you have an Observable that emits a series of items that themselves have Observable members or are in other ways transformable into Observables, so that you can create a new Observable that emits the complete collection of items emitted by the sub-Observables of these items. "
FLATTENING
MAPPING
List companies = Arrays.asList("Google", "Apple", "Microsoft");
List leaders = Arrays.asList("Larry", "Steve", "Bill");
Observable obs = Observable.just(companies, leaders);
Observable flat = obs.flatMap(strings -> Observable.from(strings));
flat.subscribe(System.out::println);
GoogleAppleMicrosoftLarrySteveBill
flatMap( ) desmontou 2 sequncias de items e juntou individualmente os itens de cada sequncia em uma nica sequncia final
mapeamento
MAIS SOBRE FLATMAP
flatmap( ) o mecanismo padro para encadeamento de operaes assncronas
flatma