You are on page 1of 178

Conhea mais da Caelum.

Cursos Online
www.caelum.com.br/online
Blog Caelum
blog.caelum.com.br
Newsletter
www.caelum.com.br/newsletter
Facebook
www.facebook.com/caelumbr
Twitter
twitter.com/caelum
Casa do Cdigo
Livros para o programador
www.casadocodigo.com.br
Sobre esta apostila
Esta apostila da Caelumvisa ensinar de uma maneira elegante, mostrando apenas o que necessrio e quando
necessrio, no momento certo, poupando o leitor de assuntos que no costumam ser de seu interesse em
determinadas fases do aprendizado.
A Caelum espera que voc aproveite esse material. Todos os comentrios, crticas e sugestes sero muito
bem-vindos.
Essa apostila constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o site para
novas verses e, ao invs de anexar o PDF para enviar a um amigo, indique o site para que ele possa sempre
baixar as ltimas verses. Voc pode conferir o cdigo de verso da apostila logo no fnal do ndice.
Baixe sempre a verso mais nova em: www.caelum.com.br/apostilas
Esse material parte integrante do treinamento Laboratrio Java com Testes, JSF, Web Services e Design
Patterns e distribudo gratuitamente exclusivamente pelo site da Caelum. Todos os direitos so reservados
Caelum. A distribuio, cpia, revenda e utilizao para ministrar treinamentos so absolutamente vedadas.
Para uso comercial deste material, por favor, consulte a Caelum previamente.
www.caelum.com.br

Sumrio
Tornando-se um desenvolvedor pragmtico
. O que realmente importante? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. A importncia dos exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Tirando dvidas e referncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Para onde ir depois? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
O modelo da bolsa de valores, datas e objetos imutveis
. A bolsa de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Candlesticks: O Japo e o arroz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. O projeto Tail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. O projeto Argentum: modelando o sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Trabalhando com dinheiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Palavra chave fnal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Imutabilidade de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Trabalhando com datas: Date e Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: o modelo do Argentum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Resumo dirio das Negociaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: fbrica de Candlestick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Testes Automatizados
. Nosso cdigo est funcionando corretamente? . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: testando nosso modelo sem frameworks . . . . . . . . . . . . . . . . . . . . . . . . .
. Defnindo melhor o sistema e descobrindo mais bugs . . . . . . . . . . . . . . . . . . . . . . . .
. Testes de Unidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. JUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Anotaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. JUnit, convenes e anotao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: migrando os testes do main para JUnit . . . . . . . . . . . . . . . . . . . . . . . . . .
. Vale a pena testar classes de modelo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: novos testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Para saber mais: Import Esttico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Mais exerccios opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Discusso em aula: testes so importantes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Trabalhando com XML
. Os dados da bolsa de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. O formato XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Lendo XML com Java de maneira difcil, o SAX . . . . . . . . . . . . . . . . . . . . . . . . . . .
i
. XStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Lendo o XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Discusso em aula: Onde usar XML e o abuso do mesmo . . . . . . . . . . . . . . . . . . . . . .
Test Driven Design - TDD
. Separando as candles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Vantagens do TDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Identifcando negociaes do mesmo dia . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Separando os candles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Acessando um Web Service
. Integrao entre sistemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Consumindo dados de um Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Criando o cliente Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Nosso cliente Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Discusso em aula: Como testar o cliente do web service? . . . . . . . . . . . . . . . . . . . . .
Introduo ao JSF e Primefaces
. Desenvolvimento desktop ou web? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Caractersticas do JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Instalando o Tomcat e criando o projeto . . . . . . . . . . . . . . . . . . . . . . . . .
. A primeira pgina com JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Interagindo com o modelo: Managed Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Recebendo informaes do usurio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Os primeiros componentes JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. A lista de negociaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Formatao de Data com JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: p:dataTable para listar as Negociaes do Web Service . . . . . . . . . . . . . . . . .
. Para saber mais: paginao e ordenao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccio opcional: adicione paginao e ordenao tabela . . . . . . . . . . . . . . . . . . . .
Refatorao: os Indicadores da bolsa
. Anlise Tcnica da bolsa de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Indicadores Tcnicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. As mdias mveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: criando indicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Refatorao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Primeiras refatoraes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Refatoraes maiores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Discusso em aula: quando refatorar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Grfcos interativos com Primefaces
ii
. Por que usar grfcos? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Grfcos com o Primefaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Propriedades para personalizar o grfco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Defnio do modelo do grfco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Isolando a API do Primefaces: baixo acoplamento . . . . . . . . . . . . . . . . . . . . . . . . . .
. Para saber mais: Design Patterns Factory Method e Builder . . . . . . . . . . . . . . . . . . . .
. Exerccios: Grfcos com Primefaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Aplicando Padres de projeto
. Nossos indicadores e o design pattern Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: refatorando para uma interface e usando bem os testes . . . . . . . . . . . . . . . .
. Exerccios opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Indicadores mais elaborados e o Design Pattern Decorator . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Indicadores mais espertos e o Design Pattern Decorator . . . . . . . . . . . . . . .
A API de Refection
. Escolhendo qual grfco plotar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: permitindo que o usurio escolha o grfco . . . . . . . . . . . . . . . . . . . . . . .
. Montando os indicadores dinamicamente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Introduo a Refection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Por que refection? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Constructor, Field e Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Melhorando nosso ArgentumBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: indicadores em tempo de execuo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Melhorando a orientao a objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Apndice Testes de interface com Selenium
. Introduo ao teste de aceitao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Como funciona? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Trabalhando com diversos testes de aceitao . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. Para saber mais: Confgurando o Selenium em casa . . . . . . . . . . . . . . . . . . . . . . . . .
. Exerccios: Teste com Selenium . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ndice Remissivo
Verso: ..
iii
C
Tornando-se um desenvolvedor pragmtico
Na maioria dos casos, as pessoas, inclusive os facnoras, so muito mais ingnuas e simples do que
costumamos achar. Alis, ns tambm.
Fiodr Dostoivski, em Irmos Karamazov
Por que fazer esse curso?
. Oqcv v nvntmvN1v :mvon1nN1v:
Voc j passou pelo FJ- e, quem sabe, at pelo FJ-. Agora chegou a hora de codifcar bastante para pegar
os truques e hbitos que so os grandes diferenciais do programador Java experiente.
Pragmtico aquele que se preocupa com as questes prticas, menos focado em ideologias e tentando
colocar a teoria pra andar.
Esse curso temcomo objetivo trazer uma viso mais prtica do desenvolvimento Java atravs de uma experi-
ncia rica em cdigo, onde exercitaremos diversas APIS e recursos do Java. Vale salientar que as bibliotecas
emsi no so os pontos mais importantes do aprendizado neste momento, mas simas boas prticas, a cultura
e um olhar mais amplo sobre o design da sua aplicao.
Os design patterns, as boas prticas, a refatorao, a preocupao com o baixo acoplamento, os testes de uni-
dade (tambm conhecidos como testes unitrios) e as tcnicas de programao (idiomismos) so passados
com afnco.
Para atingir tal objetivo, esse curso baseia-se fortemente em artigos, blogs e, em especial, na literatura que se
consagrou como fundamental para os desenvolvedores Java. Aqui citamos alguns desses livros:
http://blog.caelum.com.br////livros-escolhendo-a-trindade-do-desenvolvedor-java/
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Somamos a esses mais dois livros, que sero citados no decorrer do curso, e infuenciaram muito na elabo-
rao do contedo que queremos transmitir a vocs. Todos os cinco so:
Efective Java, Joshua Bloch
Livro de um dos principais autores das maiores bibliotecas do Java SE (como o java.io e o java.util),
arquiteto chefe Java na Google atualmente. Aqui ele mostra como enfrentar os principais problemas e
limitaes da linguagem. Uma excelente leitura, dividido em mais de tpicos de a pginas cada,
em mdia. Entre os casos interessantes est o uso de factory methods, os problemas da herana e do
protected, uso de colees, objetos imutveis e serializao, muitos desses abordados e citados aqui
no curso.
Design Patterns, Erich Gamma et al
Livro de Erich Gamma, por muito tempo lder do projeto Eclipse na IBM, e mais outros trs autores,
o que justifca terem o apelido de Gang of Four (GoF). Uma excelente leitura, mas cuidado: no saia
lendo o catlogo dos patterns decorando-os, mas concentre-se especialmente em ler toda a primeira
parte, onde eles revelam um dos princpios fundamentais da programao orientada a objetos:
Evite herana, prefra composio e Programe voltado s interfaces e no implementao.
Refactoring, Martin Fowler
Livro do cientista chefe da ToughtWorks. Um excelente catlogo de como consertar pequenas falhas
do seu cdigo de maneira sensata. Exemplos clssicos so o uso de herana apenas por preguia,
uso do switch em vez de polimorfsmo, entre dezenas de outros. Durante o curso, faremos diversos
refactoring clssicos utilizando do Eclipse, muito mais que o bsico rename.
Pragmatic Programmer, Andrew Hunt
As melhores prticas para ser um bom desenvolvedor: desde o uso de versionamento, ao bom uso do
logging, debug, nomenclaturas, como consertar bugs, etc.
Te mythical man-month, Frederick Brooks
Umlivro que fala dos problemas que encontramos no dia a dia do desenvolvimento de sofware, numa
abordagemmais gerencial. Aqui h, inclusive, o clssico artigo No Silver Bullet, que afrma que nunca
haver uma soluo nica (uma linguagem, ummtodo de desenvolvimento, umsistema operacional)
que se adeque sempre a todos os tipos de problema.
. A :mvon1XNc:n oos vxvncc:os
um tanto desnecessrio debater sobre a importncia de fazer exerccios, porm neste curso especfco eles
so vitais: como ele focado em boas prticas, alguma parte da teoria no est no texto - e passado no
decorrer de exerccios.
Captulo - Tornando-se um desenvolvedor pragmtico - A importncia dos exerccios - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
No se assuste, h muito cdigo aqui nesse curso, onde vamos construir uma pequena aplicao que l um
XML com dados da bolsa de valores e plota o grfco de candlesticks, utilizando diversas APIs do Java SE e
at mesmo bibliotecas externas.
. T:nnNoo ov:ons v nvvvnINc:ns
Para tirar dvidas dos exerccios, ou de Java em geral, recomendamos o frum do site do GUJ (http://www.
guj.com.br/) , onde sua dvida ser respondida prontamente.
Fora isso, sinta-se vontade para entrar em contato com seu instrutor e tirar todas as dvidas que tiver
durante o curso.
Voc pode estar interessado no livro TDD no mundo real, da editora Casa do Cdigo:
http://www.tddnomundoreal.com.br/
. Pnnn oNov :n ovvo:s:
Se voc se interessou pelos testes, design e automao, recomendamos os cursos online de testes da Caelum:
http://www.caelum.com.br/curso/online/testes-automatizados/
O FJ- indicado para ser feito antes ou depois deste curso, dependendo das suas necessidades e do seu
conhecimento. Ele o curso que apresenta o desenvolvimento Web com Java e seus principais ferramentas
e frameworks.
Depois destes cursos, que constituem a Formao Java da Caelum, indicamos dois outros cursos, da Forma-
o Avanada:
http://www.caelum.com.br/formacao-java-avancada/
O FJ- aborda Hibernate e JPA e o FJ- envolve JSF , Facelets e CDI. Ambos vo passar por tecnologias
hoje bastante utilizadas no desenvolvimento server side para web, e j na verso do Java EE .
Captulo - Tornando-se um desenvolvedor pragmtico - Tirando dvidas e referncias - Pgina
C
O modelo da bolsa de valores, datas e objetos
imutveis
Primeiro aprenda cincia da computao e toda a teoria. Depois desenvolva um estilo de programao. E a
esquea tudo e apenas hackeie."
George Carrette
O objetivo do FJ- aprender boas prticas da orientao a objetos, do design de classes, uso correto dos
design patterns, princpios de prticas geis de programao e a importncia dos testes de unidade.
Dois livros que so seminais na rea sero referenciados por diversas vezes pelo instrutor e pelo material:
Efective Java, do Joshua Bloch, e Design Patterns: Elements of Reusable Object-Oriented Sofware, de Erich
Gamma e outros (conhecido Gang of Four).
. A notsn ov vntonvs
Poucas atividades humanas exercem tanto fascnio quanto o mercado de aes, assunto abordado exaus-
tivamente em flmes, livros e em toda a cultura contempornea. Somente em novembro de , o total
movimentado pela BOVESPA foi de R , bilhes. Destes, o volume movimentado por aplicaes home
broker foi de R , bilhes.
Neste curso, abordaremos esse assunto que, hoje emdia, chega a ser cotidiano desenvolvendo uma aplicao
que interpreta os dados de um XML, trata e modela eles em Java e mostra grfcos pertinentes.
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. CnNotvs1:cs: O JnvXo v o nnnoz
Yodoya Keian era um mercador japons do sculo . Ele se tornou rapidamente muito rico, dadas as suas
habilidades de transporte e precifcao do arroz, uma mercadoria em crescente produo em consumo no
pas. Sua situao social de mercador no permitia que ele fosse to rico dado o sistema de castas da poca e,
logo, o governo confscou todo seu dinheiro e suas posses. Depois dele, outros vieram e tentaram esconder
suas origens como mercadores: muitos tiveram seus flhos executados e seu dinheiro confscado.
Apesar da triste histria, foi em Dojima, no jardim do prprio Yodoya Keian, que nasceu a bolsa de arroz
do Japo. L eram negociados, precifcados e categorizados vrios tipos de arroz. Para anotar os preos do
arroz, desenhava-se fguras no papel. Essas fguras parecem muito com velas -- da a analogia candlestick.
Esses desenhos eram feitos em um papel feito de... arroz! Apesar de usado a sculos, o mercado ocidental s
se interessou pela tcnica dos candlesticks recentemente, no ltimo quarto de sculo.
Um candlestick indica valores: o maior preo do dia, o menor preo do dia (as pontas), o primeiro preo
do dia e o ltimo preo do dia (conhecidos como abertura e fechamento, respectivamente).
Os preos de abertura e fechamento so as linhas horizontais e dependem do tipo de candle: se for de alta, o
preo de abertura embaixo; se for de baixa, em cima. Um candle de alta costuma ter cor azul ou branca
e os de baixa costumam ser vermelhos ou pretos. Caso o preo no tenha se movimentado, o candle tem a
mesma cor que a do dia anterior.
Para calcular as informaes necessrias para a construo de um Candlestick, so necessrios os dados de
todos as negociaes (trades) de um dia. Uma Negociao possui trs informaes: o preo pelo qual foi
comprado, a quantidade de ativos e a data em que ele foi executado.
Voc pode ler mais sobre a histria dos candles em: http://www.candlestickforum.com/PPF/Parameters/_
_/candlestick.asp
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Candlesticks: O Japo e o arroz - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Apesar de falarmos que o Candlestick representa os principais valores de um dia, ele pode ser usado para
os mais variados intervalos de tempo: um candlestick pode representar minutos, ou uma semana, depen-
dendo se voc est analisando o ativo para curto, mdio ou longo prazo.
. Ovno)v1o Tn:t
A ideia do projeto Tail (Technical Analysis Indicator Library) nasceu quando um grupo de alunos da Uni-
versidade de So Paulo procurou o professor doutor Alfredo Goldman para orient-los no desenvolvimento
de um sofware para o projeto de concluso de curso.
Ele ento teve a ideia de juntar ao grupo alguns alunos do mestrado atravs de um sistema de coorientao,
onde os mestrandos auxiliariam os graduandos na implementao, modelagem e metodologia do projeto.
Somente ento o grupo defniu o tema: o desenvolvimento de um sofware open source de anlise tcnica
grafsta (veremos o que a anlise tcnica em captulos posteriores).
O sofware est disponvel no SourceForge:
http://sourceforge.net/projects/tail/
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - O projeto Tail - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Essa ideia, ainda vaga, foi gradativamente tomando a forma do projeto desenvolvido. O grupo se reunia
semanalmente adaptando o projeto, atribuindo novas tarefas e objetivos. Os graduandos tiveram a oportu-
nidade de trabalhar em conjunto com os mestrandos, que compartilharam suas experincias anteriores.
Objetivos do projeto Tail:
Implementar os componentes bsicos da anlise tcnica grafsta: srie temporal, operaes de compra
e venda e indicadores tcnicos;
Implementar as estratgias de compra e venda mais utilizadas no mercado, assim como permitir o
rpido desenvolvimento de novas estratgias;
Implementar um algoritmo genrico para determinar um momento apropriado de compra e venda de
um ativo, atravs da escolha da melhor estratgia aplicada a uma srie temporal;
Permitir que o critrio de escolha da melhor estratgia seja trocado e desenvolvido facilmente;
Criar relatrios que facilitem o estudo e a compreenso dos resultados obtidos pelo algoritmo;
Criar uma interface grfca, permitindo o uso das ferramentas implementadas de forma fcil, rpida e
de simples entendimento, mas que no limite os recursos da biblioteca;
Arquitetura orientada a objetos, como objetivo de ser facilmente escalvel e de simples entendimento;
Utilizar prticas de XP, adaptando-as conforme as necessidades do grupo.
Manter a cobertura de testes superior a ;
Analisar o funcionamento do sistema de coorientao, como objetivo estend-lo para projetos futuros.
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - O projeto Tail - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O Tail foi desenvolvido por Alexandre Oki Takinami, Carlos Eduardo Mansur, Mrcio Vinicius dos San-
tos, Tiago Garutti Ties, Paulo Silveira (mestre em Geometria Computacional pela USP e diretor da Cae-
lum), Julian Monteiro (mestre emsistemas distribudos pela USP e doutor pelo INRIA, emSophia Antipolis,
Frana) e Danilo Sato (mestre em Metodologias geis pela USP e Lead Consultant na ToughtWorks).
Esse projeto foi a primeira parceria entre a Caelum e a USP, onde a Caelum patrocinou o trabalho de con-
cluso de curso dos graduandos, hoje todos formados.
Caso tenha curiosidade voc pode acessar o CVS do projeto, utilizando o seguinte repositrio:
http://tail.cvs.sourceforge.net/viewvc/tail/
. Ovno)v1o AncvN1cm: moovtnNoo o s:s1vmn
Oprojeto Tail bastante ambicioso. Temcentenas de recursos, emespecial o de sugesto de quando comprar
e de quando vender aes. O interessante durante o desenvolvimento do projeto Tail foi que muitos dos
bons princpios de orientao a objetos, engenharia de sofware, design patterns e Programao eXtrema se
encaixaram muito bem - por isso, nos inspiramos fortemente nele como base para o FJ-.
Queremos modelar diversos objetos do nosso sistema, entre eles teremos:
Negociao - guardando preo, quantidade e data;
Candlestick - guardando as informaes do Candle, alm do volume de dinheiro negociado;
SerieTemporal - que guarda um conjunto de candles.
Essas classes formaro a base do projeto que criaremos durante o treinamento, o Argentum (do latim, di-
nheiro ou prata). As funcionalidades do sistema sero as seguintes:
Resumir Negociacoes em Candlesticks.
Nossa base sero as negociaes. Precisamos converter uma lista de negociaes em uma lista de
Candles.
Converter Candlesticks em SerieTemporal.
Dada uma lista de Candle, precisamos criar uma srie temporal.
Utilizar indicadores tcnicos
Para isso, implementar um pequeno framework de indicadores e criar alguns deles de forma a facilitar
o desenvolvimento de novos.
Gerar grfcos
Embutveis e interativos na interface grfca em Java, dos indicadores que criamos.
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - O projeto Argentum: modelando o sistema - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Para comear a modelar nosso sistema, precisamos entender alguns recursos de design de classes que ainda
no foram discutidos no FJ-. Entre eles podemos citar o uso da imutabilidade de objetos, uso de anotaes
e aprender a trabalhar e manipular datas usando a API do Java.
. TnnnntnnNoo como:Nnv:no
At agora, no paramos muito para pensar nos tipos das nossas variveis e j ganhamos o costume de auto-
maticamente atribuir valores a variveis double. Essa , contudo, uma prtica bastante perigosa!
O problema do double que no possvel especifcar a preciso mnima que ele vai guardar e, dessa forma,
estamos sujeitos a problemas de arredondamento ao fracionar valores e voltar a som-los. Por exemplo:
double cem = 100.0;
double tres = 3.0;
double resultado = cem / tres;
System.out.println(resultado);
// 33.333?
// 33.333333?
// 33.3?
Se no queremos correr o risco de acontecer um arredondamento sem que percebamos, a alternativa usar
a classe BigDecimal, que lana exceo quando tentamos fazer uma operao cujo resultado inexato.
Leia mais sobre ela na prpria documentao do Java.
. Pntnvnn cnnvv v:Nnt
A palavra chave final tem vrias utilidades. Em uma classe, defne que a classe nunca poder ter uma flha,
isso , no pode ser estendida. A classe String, por exemplo, final.
Como modifcador de mtodo, final indica que aquele mtodo no pode ser reescrito. Mtodos muito
importantes costumam ser defnidos assim. Claro que isso no necessrio declarar caso sua classe j seja
final.
Ao usarmos como modifcador na declarao de varivel, indica que o valor daquela varivel nunca poder
ser alterado, uma vez atribudo. Se a varivel for um atributo, voc tem que inicializar seu valor durante a
construo do objeto - caso contrrio, ocorre um erro de compilao, pois atributos final no so iniciali-
zados com valores default.
Imagine que, quando criamos um objeto Negociacao, no queremos que seu valor seja modifcado:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Trabalhando com dinheiro - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
class Negociacao {
private final double valor;
// getters e setters?
}
Esse cdigo no compila, nem mesmo com um setter, pois o valor fnal deveria j ter sido inicializado. Para
resolver isso, ou declaramos o valor da Negociacao direto na declarao do atributo (o que no faz muito
sentido nesse caso), ou ento populamos pelo construtor:
class Negociacao {
private final double valor;
public Negociacao(double valor) {
this.valor = valor;
}
// podemos ter um getter, mas nao um setter aqui!
}
Uma varivel static final temuma cara de constante daquela classe e, se for public static final, a pa-
rece uma constante global! Por exemplo, na classe Collections do java.util existe uma constante public
static final chamada EMPTY_LIST. conveno que constantes sejamdeclaradas letras maisculas e sepa-
radas por travesso (underscore) em vez de usar o padro camel case. Outros bons exemplos so o PI e o E,
dentro da java.lang.Math.
Isso muito utilizado, mas hoje no java para criarmos constantes costuma ser muito mais interessante
utilizarmos o recurso de enumeraes que, alm de tipadas, j possuem diversos mtodos auxiliares.
No caso da classe Negociacao, no entanto, bastar usarmos atributos fnais e tambm marcarmos a prpria
classe como fnal para que ela crie apenas objetos imutveis.
. Imc1nn:t:onov ov on)v1os
Evvvc1:vv Jnvn
Item : Minimize mutabilidade
Para que uma classe seja imutvel, ela precisa ter algumas caractersticas:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Imutabilidade de objetos - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Nenhum mtodo pode modifcar seu estado;
A classe deve ser final;
Os atributos devem ser privados;
Os atributos devem ser final, apenas para legibilidade de cdigo, j que no h mtodos que modif-
cam o estado do objeto;
Caso sua classe tenha composies com objetos mutveis, eles devem ter acesso exclusivo pela sua
classe.
Diversas classes no Java so imutveis, como a String e todas as classes wrapper. Outro excelente exemplo
de imutabilidade so as classes BigInteger e BigDecimal:
Qual seria a motivao de criar uma classe de tal maneira?
On)v1os voovmcomvnn1:tnnn scns comvos:ovs
Como o objeto imutvel, a composio interna de cada um pode ser compartilhada entre eles, j que no
h chances de algum deles mudar tais atributos. Esse compartilhamento educado possibilita fazer cache de
suas partes internas, alm de facilitar a manipulao desses objetos.
Isso pode ser encarado como o famoso design pattern Flyweight.
fcil entender os benefcios dessa prtica quando olhamos para o caso da String: objetos do tipo String
que contm exatamente o mesmo texto ou partes exatas do texto original (como no caso de usarmos o
substring) compartilham a array privada de chars!
Na prtica, o que isso quer dizer que se voc tem uma String muito longa e cria vrias outras com trechos
da original, voc no ter que armazenar os caracteres de novo para cada trecho: eles utilizaro o array de
chars da String original!
String palavra = "supercalifragilisticexpialidocious";
String inicio = palavra.substring(0, 5);
String proximas = palavra.substring(5, 10);
String outras = palavra.substring(10, 15);
String resto = palavra.substring(15);
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Imutabilidade de objetos - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Esses objetos tambm so ideais para usar como chave de tabelas de hash.
Tnnvno snvv1v
Uma das principais vantagens da imutabilidade em relao a concorrncia. Simplesmente no precisamos
nos preocupar em relao a isso: como no h mtodo que mude o estado do objeto, ento no h como
fazer duas modifcaes acontecerem concorrentemente!
On)v1os mn:s s:mvtvs
Uma classe imutvel mais simples de dar manuteno. Como no h chances de seu objeto ser modifcado,
voc tem uma srie de garantias sobre o uso daquela classe.
Se os construtores j abrangem todas as regras necessrias para validar o estado do objeto, no h preocupa-
o em relao a manter o estado consistente, j que no h chances de modifcao.
Uma boa prtica de programao evitar tocar em variveis parmetros de um mtodo. Com objetos imu-
tveis nem existe esse risco quando voc os recebe como parmetro.
Se nossa classe Negociacao imutvel, isso remove muitas dvidas e medos que poderamos ter durante o
desenvolvimento do nosso projeto: saberemos em todos os pontos que os valores da negociao so sempre
os mesmos, no corremos o risco de um mtodo que constri o candlestick mexer nos nossos atributos
(deixando ou no num estado inconsistente), alm de a imutabilidade tambm garantir que no haver pro-
blemas no caso de acesso concorrente ao objeto.
. TnnnntnnNoo comon1ns: Dn1v v CntvNonn
Se voc fez o FJ- conosco, j teve que lidar com as converses entre Date e Calendar para pegar a entrada
de data de um texto digitado pelo usurio e convert-lo para um objeto que representa datas em Java.
A classe mais antiga que representa uma data dentro do Java a Date. Ela armazena a data de forma cada
momento do tempo seja representado por um nmero - isso quer dizer, que o Date guarda todas as datas
como milissegundos que se passaram desde //.
O armazenamento dessa forma no de todo ruim, mas o problema que a API no traz mtodos que
ajudem muito a lidar com situaes do dia como, por exemplo, adicionar dias ou meses a uma data.
A classe Date no mais recomendada porque a maior parte de seus mtodos esto marcados como
deprecated, porm ela tem amplo uso legado nas bibliotecas do java. Ela foi substituda no Java . pelo
Calendar, para haver suporte correto internacionalizao e localizao do sistema de datas.
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Trabalhando com datas: Date e Calendar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
CntvNonn: vvotcXo oo Dn1v
A classe abstrata Calendar tambm encapsula um instante em milissegundos, como a Date, mas ela prov
mtodos para manipulao desse momento em termos mais cotidianos como dias, meses e anos. Por ser
abstrata, no entanto, no podemos criar objetos que so simplesmente Calendars.
Asubclasse concreta de Calendar mais usada a GregorianCalendar, que representa o calendrio usado pela
maior parte dos pases -- outras implementaes existem, como a do calendrio budista BuddhistCalendar,
mas estas so bem menos usadas e devolvidas de acordo com seu Locale.
H ainda a API nova do Java , chamada java.time, desenvolvida com base no Joda Time. Trabalharemos
aqui com Calendar por ser ainda muito mais difundida, dado que o Java muito recente. Caso voc tenha
a possibilidade de trabalhar com Java , favorea o uso da API nova.
Para obter um Calendar que encapsula o instante atual (data e hora), usamos o mtodo esttico
getInstance() de Calendar.
Calendar agora = Calendar.getInstance();
Porque no damos new diretamente em GregorianCalendar? A API do Java fornece esse mtodo esttico
que fabrica um objeto Calendar de acordo com uma srie de regras que esto encapsuladas dentro de
getInstance. Esse o padro de projeto factory, que utilizamos quando queremos esconder a maneira em
que um objeto instanciado. Dessa maneira podemos trocar implementaes devolvidas como retorno a
medida que nossas necessidades mudem.
Nesse caso algum pas que use calendrios diferente do gregoriano pode implementar esse mtodo de ma-
neira adequada, retornando o que for necessrio de acordo com o Locale confgurado na mquina.
Evvvc1:vv Jnvn
Item : Considere utilizar Factory com mtodos estticos em vez de construtores
Repare ainda que h uma sobrecarga desse mtodo que recebe Locale ou Timezone como argumento, caso
voc queira que essa factory trabalhe com valores diferentes dos valores que a JVM descobrir em relao ao
seu ambiente.
Um outro excelente exemplo de factory o DriverManager do java.sql que fabrica Connection de acordo
com os argumentos passados.
A partir de um Calendar, podemos saber o valor de seus campos, como ano, ms, dia, hora, minuto, etc.
Para isso, usamos o mtodo get que recebe uminteiro representando o campo; os valores possveis esto em
constantes na classe Calendar.
No exemplo abaixo, imprimimos o dia de hoje e o dia da semana correspondente. Note que o dia da semana
devolvido um inteiro que representa o dia da semana (Calendar.MONDAY etc):
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Trabalhando com datas: Date e Calendar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Calendar c = Calendar.getInstance();
System.out.println("Dia do Ms: " + c.get(Calendar.DAY_OF_MONTH));
System.out.println("Dia da Semana: " + c.get(Calendar.DAY_OF_WEEK));
Um possvel resultado :
Dia do Ms: 4
Dia da Semana: 5
No exemplo acima, o dia da semana representa a quinta-feira.
Da mesma forma que podemos pegar os valores dos campos, podemos atribuir novos valores a esses campos
por meio dos mtodos set.
H diversos mtodos set emCalendar. Omais geral o que recebe dois argumentos: o primeiro indica qual
o campo (usando aquelas constantes de Calendar) e, o segundo, o novo valor. Alm desse mtodo, outros
mtodos set recebem valores de determinados campos; o set de trs argumentos, por exemplo, recebe ano,
ms e dia. Vejamos um exemplo de como alterar a data de hoje:
Calendar c = Calendar.getInstance();
c.set(2011, Calendar.DECEMBER, 25, 10, 30);
// mudamos a data para as 10:30am do Natal
Outro mtodo bastante usado add, que adiciona uma certa quantidade a qualquer campo do Calendar. Por
exemplo, para uma aplicao de agenda, queremos adicionar um ano data de hoje:
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, 1); // adiciona 1 ao ano
Note que, embora o mtodo se chame add, voc pode us-lo para subtrair valores tambm; basta colocar
uma quantidade negativa no segundo argumento.
Os mtodos after e before so usados para comparar o objeto Calendar em questo a outro Calendar. O
mtodo after devolver true quando o objeto atual do Calendar representar um momento posterior ao do
Calendar passado como argumento. Por exemplo, after devolver false se compararmos o dia das crianas
com o Natal, pois o dia das crianas no vem depois do Natal:
Calendar c1 = new GregorianCalendar(2005, Calendar.OCTOBER, 12);
Calendar c2 = new GregorianCalendar(2005, Calendar.DECEMBER, 25);
System.out.println(c1.after(c2));
Analogamente, o mtodo before verifca se o momento em questo vem antes do momento do Calendar
que foi passado como argumento. No exemplo acima, c1.before(c2) devolver true, pois o dia das crianas
vem antes do Natal.
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Trabalhando com datas: Date e Calendar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Note que Calendar implementa Comparable. Isso quer dizer que voc pode usar o mtodo compareTo para
comparar dois calendrios. No fundo, after e before usam o compareTo para dar suas respostas - apenas,
fazem tal comparao de uma forma mais elegante e encapsulada.
Por ltimo, um dos problemas mais comuns quando lidamos com datas verifcar o intervalo de dias entre
duas datas que podem ser at de anos diferentes. O mtodo abaixo devolve o nmero de dias entre dois
objetos Calendar. O clculo feito pegando a diferena entre as datas em milissegundos e dividindo esse
valor pelo nmero de milissegundos em um dia:
public int diferencaEmDias(Calendar c1, Calendar c2) {
long m1 = c1.getTimeInMillis();
long m2 = c2.getTimeInMillis();
return (int) ((m2 - m1) / (24*60*60*1000));
}
Rvtnc:oNnNoo Dn1v v CntvNonn
Voc pode pegar umDate de umCalendar e vice-versa atravs dos mtodos getTime e setTime presentes na
classe Calendar:
Calendar c = new GregorianCalendar(2005, Calendar.OCTOBER, 12);
Date d = c.getTime();
c.setTime(d);
Isso faz com que voc possa operar com datas da maneira nova, mesmo que as APIs ainda usem objetos do
tipo Date (como o caso de java.sql).
Pnnn snnvn mn:s: Ctnssvs Dvvnvcn1vo v o JoonT:mv
O que fazer quando descobrimos que algum mtodo ou alguma classe no saiu bem do jeito que deveria?
Simplesmente apag-la e criar uma nova?
Essa uma alternativa possvel quando apenas o seu programa usa tal classe, mas defnitivamente no uma
boa alternativa se sua classe j foi usada por milhes de pessoas no mundo todo.
o caso das classes do Java. Algumas delas (Date, por exemplo) so repensadas anos depois de serem lana-
das e solues melhores aparecem(Calendar). Mas, para no quebrar compatibilidade comcdigos existen-
tes, o Java mantm as funcionalidades problemticas ainda na plataforma, mesmo que uma soluo melhor
exista.
Mas como desencorajar cdigos novos a usaremfuncionalidades antigas e no mais recomendadas? Aprtica
no Java para isso marc-las como deprecated. Isso indica aos programadores que no devemos mais us-las
e que futuramente, emuma verso mais nova do Java, podemsair da API (embora isso nunca tenha ocorrido
na prtica).
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Trabalhando com datas: Date e Calendar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Antes do Java , para falar que algo era deprecated, usava-se um comentrio especial no Javadoc. A partir
do Java , a anotao @Deprecated foi adicionada plataforma e garante verifcaes do prprio compilador
(que gera um warning). Olhe o Javadoc da classe Date para ver tudo que foi deprecated.
A API de datas do Java, mesmo considerando algumas melhorias da Calendar em relao a Date, ainda
muito pobre. Numa prxima verso novas classes para facilitar ainda mais o trabalho com datas e horrios
devem entrar na especifcao do Java, baseadas na excelente biblioteca JodaTime.
Para mais informaes: http://blog.caelum.com.br////jsr--date-and-time-api/ http://jcp.org/en/
jsr/detail?id=
. Exvncc:os: o moovto oo AncvN1cm
) Vamos criar o projeto fj22-argentum no Eclipse, j com o foco em usar a IDE melhor: use o atalho ctrl
+ N, que cria novo... e comece a digitar Java Project:
) Na janela que abrir em sequncia, preencha o nome do projeto como f-argentum e clique em Next:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Na prxima tela, podemos defnir uma srie de confguraes do projeto (que tambm podem ser feitas
depois, atravs do menu Build path -> Confgure build path, clicando com o boto da direita no projeto.
Queremos mudar o diretrio que conter nosso cdigo fonte. Faremos isso para organizar melhor nosso
projeto e utilizar convenes amplamente utilizadas no mercado.
Nessa tela, remova o diretrio src da lista de diretrios fonte:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Agora, na mesma tela, adicione um novo diretrio fonte, chamado src/main/java. Para isso, clique em
Create new source folder e preencha com src/main/java:
) Agora basta clicar em Finish. A estrutura fnal de seu projeto deve estar parecida com isso:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Crie a classe usando ctrl + N Class, chamada Negociacao e dentro do pacote
br.com.caelum.argentum.modelo:
) Transforme a classe em fnal e j declare os trs atributos que fazem parte de uma negociao da bolsa de
valores (tambm como fnal):
public final class Negociacao {
private final double preco;
private final int quantidade;
private final Calendar data;
}
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
No esquea de importar o Calendar!
) Vamos criar um construtor que recebe esses dados, j que so obrigatrios para nosso domnio. Em vez
de fazer isso na mo, na edio da classe, use o atalho ctrl + e comece a digitar constructor. Ele vai
mostrar uma lista das opes que contm essa palavra: escolha a Generate constructor using felds.
Alternativamente, tecle ctrl + e digite GCUF, que so as iniciais do menu que queremos acessar.
Agora, selecione todos os campos e marque para omitir a invocao ao super, como na tela abaixo.
Ateno para deixar os campos na ordem preco, quantidade, data. Voc pode usar os botes Up e
Down para mudar a ordem.
Pronto! Mande gerar. O seguinte cdigo que ser gerado:
public Negociacao(double preco, int quantidade, Calendar data) {
this.preco = preco;
this.quantidade = quantidade;
this.data = data;
}
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Agora, vamos gerar os getters dessa classe. Faa ctrl + e comece a digitar getter, as opes aparecero e
basta voc escolher generate getters and setters. sempre bom praticar os atalhos do ctrl + .
Selecione os getters e depois Finish:
) Verifque sua classe. Ela deve estar assim:
public final class Negociacao {
private final double preco;
private final int quantidade;
private final Calendar data;
public Negociacao(double preco, int quantidade, Calendar data) {
this.preco = preco;
this.quantidade = quantidade;
this.data = data;
}
public double getPreco() {
return preco;
}
public int getQuantidade() {
return quantidade;
}
public Calendar getData() {
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
return data;
}
}
) Um dado importante para termos noo da estabilidade de uma ao na bolsa de valores o volume de
dinheiro negociado em um perodo.
Vamos fazer nossa classe Negociacao devolver o volume de dinheiro transferido naquela negociao.
Na prtica, s multiplicar o preco pago pela quantidade de aes negociadas, resultando no total de
dinheiro que aquela negociao realizou.
Adicione o mtodo getVolume na classe Negociacao:
public double getVolume() {
return preco * quantidade;
}
Repare que um mtodo que parece ser um simples getter pode (e deve muitas vezes) encapsular regras de
negcio e no necessariamente refetem um atributo da classe.
) Siga o mesmo procedimento para criar a classe Candlestick. Use o ctrl + N Class para isso, marque-a
como fnal e adicione os seguintes atributos fnais, nessa ordem:
public final class Candlestick {
private final double abertura;
private final double fechamento;
private final double minimo;
private final double maximo;
private final double volume;
private final Calendar data;
}
) Use o ctrl + para gerar o construtor com os seis atributos. Ateno ordem dos parmetros no cons-
trutor:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Gere tambm os seis respectivos getters, usando o ctrl + .
A classe fnal deve fcar parecida com a que segue:
public final class Candlestick {
private final double abertura;
private final double fechamento;
private final double minimo;
private final double maximo;
private final double volume;
private final Calendar data;
public Candlestick(double abertura,double fechamento,double minimo,
double maximo, double volume, Calendar data) {
this.abertura = abertura;
this.fechamento = fechamento;
this.minimo = minimo;
this.maximo = maximo;
this.volume = volume;
this.data = data;
}
public double getAbertura() {
return abertura;
}
public double getFechamento() {
return fechamento;
}
public double getMinimo() {
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: o modelo do Argentum - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
return minimo;
}
public double getMaximo() {
return maximo;
}
public double getVolume() {
return volume;
}
public Calendar getData() {
return data;
}
}
) (opcional) Vamos adicionar dois mtodos de negcio, para que o Candlestick possa nos dizer se ele do
tipo de alta, ou se de baixa:
public boolean isAlta() {
return this.abertura < this.fechamento;
}
public boolean isBaixa() {
return this.abertura > this.fechamento;
}
. Rvscmo o:Kn:o ons Nvcoc:novs
Agora que temos as classes que representamnegociaes na bolsa de valores (Negociacao) e resumos dirios
dessas negociaes (Candlestick), falta apenas fazer a ao de resumir as negociaes de um dia em uma
candle.
A regra um tanto simples: dentre uma lista de negociaes, precisamos descobrir quais so os valores a
preencher na Candlestick:
Abertura: preo da primeira negociao do dia;
Fechamento: preo da ltima negociao do dia;
Mnimo: preo da negociao mais barata do dia;
Mximo: preo da negociao mais cara do dia;
Volume: quantidade de dinheiro que passou em todas as negociaes nesse dia;
Data: a qual dia o resumo se refere.
Algumas dessas informaes so fceis de encontrar por que temos uma conveno no sistema: quando va-
mos criar a candle, a lista de negociaes j vemordenada por tempo. Dessa forma, a abertura e o fechamento
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Resumo dirio das Negociaes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
so triviais: basta recuperar o preo , respectivamente, da primeira e da ltima negociaes do dia!
J mnimo, mximo e volume precisam que todos os valores sejam verifcados. Dessa forma, precisamos
passar por cada negociao da lista verifcando se aquele valor menor do que todos os outros que j vi-
mos, maior que nosso mximo atual. Aproveitando esse processo de passar por cada negociao, j vamos
somando o volume de cada negociao.
O algoritmo, agora, est completamente especifcado! Basta passarmos essas ideias para cdigo. Para isso,
lembremos, voc pode usar alguns atalhos que j vimos antes:
Ctrl + N: cria novo(a)...
Ctrl + espao: autocompleta
Ctrl + : resolve pequenos problemas de compilao e atribui objetos a variveis.
Emqcv ctnssv cotocnn:
Falta apenas, antes de pr em prtica o que aprendemos, decidirmos onde vai esse cdigo de criao de
Candlestick. Pense bem a respeito disso: ser que uma negociao deveria saber resumir vrios de si em
uma candle? Ou ser que uma Candlestick deveria saber gerar um objeto do prprio tipo Candlestick a
partir de uma lista de negociaes.
Em ambos os cenrios, nossos modelos tm que ter informaes a mais que, na realidade, so responsabili-
dades que no cabem a eles!
Criaremos, ento, uma classe que: dado a matria-prima, nos constri uma candle. E uma classe com esse
comportamento, que recebem o necessrio para criar um objeto e encapsulam o algoritmo para tal criao,
costuma ser chamadas de Factory.
No nosso caso particular, essa uma fbrica que cria Candlesticks, ento, seu nome fca
CandlestickFactory.
Perceba que esse nome, apesar de ser um tal Design Pattern nada mais faz do que encapsular uma lgica um
pouco mais complexa, isto , apenas aplica boas prticas de orientao a objetos que voc j vem estudando
desde o FJ-.
. Exvncc:os: vKnn:cn ov CnNotvs1:c
) Como o resumo de Negociacoes em um Candlestick um processo complicado, vamos encapsular sua
construo atravs de uma fbrica, assim como vimos a classe Calendar, porm o mtodo de fabricao
fcar numa classe a parte, o que tambm muito comum. Vamos criar a classe CandlestickFactory
dentro do pacote br.com.caelum.argentum.modelo:
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: fbrica de Candlestick - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Depois de cri-la, adicione a assinatura do mtodo constroiCandleParaData como abaixo:
public class CandlestickFactory {
// ctrl + 1 para adicionar o return automaticamente
public Candlestick constroiCandleParaData(Calendar data,
List<Negociacao> negociacoes) {
}
}
) Calcularemos o preo mximo e mnimo percorrendo todas as negociaes e achando os valores corre-
tos. Para isso, usaremos variveis temporrias e, dentro do for, verifcaremos se o preo da negociao
atual bate ou mximo. Se no bater, veremos se ele menor que o mnimo. Calculamos o volume so-
mando o volume de cada negociao em uma varivel. Podemos pegar o preo de abertura atravs de
negociacoes.get(0) e o de fechamento por negociacoes.get(negociacoes.size() - 1).
public class CandlestickFactory {
public Candlestick constroiCandleParaData(Calendar data,
List<Negociacao> negociacoes) {
double maximo = negociacoes.get(0).getPreco();
double minimo = negociacoes.get(0).getPreco();
double volume = 0;
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: fbrica de Candlestick - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
// digite foreach e d um ctrl + espao para ajudar a
// criar o bloco abaixo!
for (Negociacao negociacao : negociacoes) {
volume += negociacao.getVolume();
if (negociacao.getPreco() > maximo) {
maximo = negociacao.getPreco();
} else if (negociacao.getPreco() < minimo) {
minimo = negociacao.getPreco();
}
}
double abertura = negociacoes.get(0).getPreco();
double fechamento = negociacoes.get(negociacoes.size()-1).getPreco();
return new Candlestick(abertura, fechamento, minimo, maximo,
volume, data);
}
}
) Vamos testar nosso cdigo, criando negociaes e calculando o Candlestick, fnalmente. Crie a classe
TestaCandlestickFactory no pacote br.com.caelum.argentum.testes
public class TestaCandlestickFactory {
public static void main(String[] args) {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(39.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(42.3, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1, negociacao2,
negociacao3, negociacao4);
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(
hoje, negociacoes);
System.out.println(candle.getAbertura());
System.out.println(candle.getFechamento());
System.out.println(candle.getMinimo());
System.out.println(candle.getMaximo());
System.out.println(candle.getVolume());
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios: fbrica de Candlestick - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
}
}
O mtodo asList da classe java.util.Arrays cria uma lista dada uma array. Mas no passamos ne-
nhuma array como argumento! Isso acontece porque esse mtodo aceita varargs, possibilitando que
invoquemos esse mtodo separando a array por vrgula. Algo parecido com um autoboxing de arrays.
Evvvc1:vv Jnvn
Item : Conhea e use as bibliotecas!
A sada deve ser parecida com:
40.5
42.3
39.8
45.0
16760.0
. Exvncc:os ovc:oNn:s
)
Evvvc1:vv Jnvn
Item : Sempre reescreva o toString
Reescreva o toString da classe Candlestick. Como o toString da classe Calendar retorna uma
String bastante complexa, faa com que a data seja corretamente visualizada, usando para isso o
SimpleDateFormat. Procure sobre essa classe na API do Java.
Ao imprimir um candlestick, por exemplo, a sada deve ser algo como segue:
[Abertura 40.5, Fechamento 42.3, Mnima 39.8, Mxima 45.0,
Volume 145234.20, Data 12/07/2008]
Para reescrever um mtodo e tirar proveito do Eclipse, a maneira mais direta de dentro da classe
Candlestick, fora de qualquer mtodo, pressionar ctrl + espao.
Uma lista com todas as opes de mtodos que voc pode reescrever vai aparecer. Escolha o toString, e
ao pressionar enter o esqueleto da reescrita ser montado.
) Umdouble segue uma regra bemdefnida emrelao a contas e arredondamento, e para ser rpido e caber
em bits, no tem preciso infnita. A classe BigDecimal pode oferecer recursos mais interessantes em
um ambiente onde as casas decimais so valiosas, como um sistema fnanceiro. Pesquise a respeito.
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios opcionais - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) O construtor da classe Candlestick simplesmente muito grande. Poderamos usar uma factory, porm
continuaramos passando muitos argumentos para um determinado mtodo.
Quando construir umobjeto complicado, ou confuso, costumamos usar o padro Builder para resolver
isso. Builder uma classe que ajudar voc a construir um determinado objeto em uma srie de passos,
independente de ordem.
Evvvc1:vv Jnvn
Item : Considere usar um builder se o construtor tiver muitos parmetros!
A ideia que possamos criar um candle da seguinte maneira:
CandleBuilder builder = new CandleBuilder();
builder.comAbertura(40.5);
builder.comFechamento(42.3);
builder.comMinimo(39.8);
builder.comMaximo(45.0);
builder.comVolume(145234.20);
builder.comData(new GregorianCalendar(2012, 8, 12, 0, 0, 0));
Candlestick candle = builder.geraCandle();
Os setters aqui possuem nomes mais curtos e expressivos. Mais ainda: utilizando o padro de projeto
fuent interface, podemos tornar o cdigo acima mais conciso, sem perder a legibilidade:
Candlestick candle = new CandleBuilder().comAbertura(40.5)
.comFechamento(42.3).comMinimo(39.8).comMaximo(45.0)
.comVolume(145234.20).comData(
new GregorianCalendar(2008, 8, 12, 0, 0, 0)).geraCandle();
Para isso, a classe CandleBuilder deve usar o seguinte idiomismo:
public class CandleBuilder {
private double abertura;
// outros 5 atributos
public CandleBuilder comAbertura(double abertura) {
this.abertura = abertura;
return this;
}
// outros 5 setters que retornam this
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios opcionais - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public Candlestick geraCandle() {
return new Candlestick(abertura, fechamento, minimo, maximo,
volume, data);
}
}
Escreva um cdigo com main que teste essa sua nova classe. Repare como o builder parece bastante com
a StringBuilder, que uma classe builder que ajuda a construir Strings atravs de fuent interface e
mtodos auxiliares.
Usos vnmosos ov FtcvN1 IN1vnvncv v DSLs
Fluent interfaces so muito usadas no Hibernate, por exemplo. O jQuery, uma famosa biblioteca
de efeitos javascript, popularizou-se por causa de sua fuent interface. O JodaTime e o JMock so
dois excelentes exemplos.
So muito usadas (e recomendadas) na construo de DSLs, Domain Specifc Languages. Martin
Fowler fala bastante sobre fuent interfaces nesse timo artigo:
http://martinfowler.com/bliki/FluentInterface.html
Captulo - O modelo da bolsa de valores, datas e objetos imutveis - Exerccios opcionais - Pgina
C
Testes Automatizados
Apenas duas coisas so infnitas: o universo e a estupidez humana. E eu no tenho certeza do primeiro.
Albert Einstein
. Nosso coo:co vs1K vcNc:oNnNoo connv1nmvN1v:
Escrevemos uma quantidade razovel de cdigo no captulo anterior, meia dzia de classes. Elas funcionam
corretamente? Tudo indica que sim, at criamos um pequeno main para verifcar isso e fazer as perguntas
corretas.
Pode parecer que o cdigo funciona, mas ele tem muitas falhas. Olhemos com mais cuidado.
. Exvncc:os: 1vs1nNoo Nosso moovto svmvnnmvwons
) Ser que nosso programa funciona para um determinado dia que ocorrer apenas uma nica negociao?
Vamos escrever o teste, e ver o que acontece:
public class TestaCandlestickFactoryComUmaNegociacaoApenas {
public static void main(String[] args) {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1);
CandlestickFactory fabrica = new CandlestickFactory();
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
System.out.println(candle.getAbertura());
System.out.println(candle.getFechamento());
System.out.println(candle.getMinimo());
System.out.println(candle.getMaximo());
System.out.println(candle.getVolume());
}
}
A sada deve indicar 40.5 como todos os valores, e 4050.0 como volume. Tudo parece bem?
) Mais um teste: as aes menos negociadas podem fcar dias sem nenhuma operao acontecer. O que
nosso sistema gera nesse caso?
Vamos ao teste:
public class TestaCandlestickFactorySemNegociacoes {
public static void main(String[] args) {
Calendar hoje = Calendar.getInstance();
List<Negociacao> negociacoes = Arrays.asList();
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
System.out.println(candle.getAbertura());
System.out.println(candle.getFechamento());
System.out.println(candle.getMinimo());
System.out.println(candle.getMaximo());
System.out.println(candle.getVolume());
}
}
Rodando o que acontece? Voc acha essa sada satisfatria? Indica bem o problema?
) ArrayIndexOutOfBoundsException certamente uma pssima exceo para indicar que no teremos
Candle.
Captulo - Testes Automatizados - Exerccios: testando nosso modelo sem frameworks - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Qual deciso vamos tomar? Podemos lanar nossa prpria exception, podemos retornar null ou ainda
podemos devolver um Candlestick que possui um signifcado especial. Devolver null deve ser sempre
a ltima opo.
Vamos retornar umCandlestick que possui umvolume zero. Para corrigir o erro, vamos alterar o cdigo
do nosso CandlestickFactory.
Poderamos usar um if logo de cara para verifcar se negociacoes.isEmpty(), porm podemos tentar
algo mais sutil, sem ter que criar vrios pontos de return.
Vamos ento iniciar os valores de minimo e maximo sem usar a lista, que pode estar vazia. Mas, para nosso
algoritmo funcionar, precisaramos iniciar o maximo com um valor bempequeno, isto , menor do que o
da ao mais barata. Assim, quando percorrermos o for, qualquer valor que encontremos vai substituir
o maximo.
No caso do mximo, fcil pensar nesse valor! Qual o limite inferior para o preo de uma ao? Ser
que ele chega a ser negativo? A resposta no. Ningum vai vender uma ao por um preo negativo!
Portanto, se inicializarmos o mximo comzero, certeza que ele ser substituido na primeira iterao do
for.
Similarmente, queremos inicializar o minimo com um valor bem grande, maior do que o maior valor
possvel para o valor de uma ao. Esse um problema mais complexo, j que no existe um limitante
superior to claro para o preo de uma ao!
Qual valor colocaremos, ento? Quanto um nmero grande o sufciente? Podemos apelar para a limi-
tao do tipo que estamos usando! Se o preo um double, certamente no poderemos colocar nenhum
valor que estoure o tamanho do double. Felizmente, a classe Double conta coma constante que representa
o maior double vlido! o Double.MAX_VALUE.
Altere o mtodo constroiCandleParaData da classe CandlestickFactory:
double maximo = 0;
double minimo = Double.MAX_VALUE;
Alm disso, devemos verifcar se negociacoes est vazia na hora de calcular o preo de abertura e
fechamento. Altere novamente o mtodo:
double abertura = negociacoes.isEmpty() ? 0 : negociacoes.get(0).getPreco();
double fechamento = negociacoes.isEmpty() ? 0 :
negociacoes.get(negociacoes.size() - 1).getPreco();
Pronto! Rode o teste, deve vir tudo zero e nmeros estranhos para mximo e mnimo!
) Ser que tudo est bem? Rode novamente os outros dois testes, o que acontece?
Incrvel! Consertamos um bug, mas adicionamos outro. A situao lhe parece familiar? Ns desenvolve-
dores vivemos com isso o tempo todo: tentando fugir dos velhos bugs que continuam a reaparecer!
Captulo - Testes Automatizados - Exerccios: testando nosso modelo sem frameworks - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O teste com apenas uma negociao retorna .E como valor mnimo agora! Mas
deveria ser .. Ainda bem que lembramos de rodar essa classe, e que percebemos que esse nmero est
diferente do que deveria ser.
Vamos sempre confar em nossa memria?
) (opcional) Ser que esse erro est ligado a ter apenas uma negociao? Vamos tentar com mais negocia-
es? Crie e rode um teste com as seguintes negociaes:
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(49.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(53.3, 100, hoje);
E com uma sequncia decrescente, funciona? Por qu?
. Dvv:N:Noo mvtnon o s:s1vmn v ovsconn:Noo mn:s nccs
Segue uma lista de dvidas pertinentes ao Argentum. Algumas dessas perguntas voc no saber respon-
der, porque no defnimos muito bem o comportamento de alguns mtodos e classes. Outras voc saber
responder.
De qualquer maneira, crie um cdigo curto para testar cada uma das situaes, em um main apropriado.
) Uma negociao da Petrobras a reais, com uma quantidade negativa de negociaes vlida? E com
nmero zero de negociaes?
Em outras palavras, posso dar new em uma Negociacao com esses dados?
) Uma negociao com data nula vlida? Posso dar new Negociacao(10, 5, null)? Deveria poder?
) Um candle realmente imutvel? No podemos mudar a data de um candle de maneira alguma?
) Um candle em que o preo de abertura igual ao preo de fechamento, um candle de alta ou de baixa?
O que o sistema diz? O que o sistema deveria dizer?
) Como geramos um candle de um dia que no houve negociao? O que acontece?
) E se a ordemdas negociaes passadas ao CandlestickFactory no estiver na ordemcrescente das datas?
Devemos aceitar? No devemos?
) E se essas Negociaes forem de dias diferentes que a data passada como argumento para a factory?
. Tvs1vs ov UN:onov
Testes de unidade so testes que testam apenas uma classe ou mtodo, verifcando se seu comportamento
est de acordo com o desejado. Em testes de unidade, verifcamos a funcionalidade da classe e/ou mtodo
Captulo - Testes Automatizados - Defnindo melhor o sistema e descobrindo mais bugs - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
em questo passando o mnimo possvel por outras classes ou dependncias do nosso sistema.
UN:onov
Unidade a menor parte testvel de uma aplicao. Em uma linguagem de programao orien-
tada a objetos como o Java, a menor unidade um mtodo.
O termo correto para esses testes testes de unidade, porm o termo teste unitrio propagou-se
e o mais encontrado nas tradues.
Emtestes de unidade, no estamos interessados no comportamento real das dependncias da classe, mas em
como a classe em questo se comporta diante das possveis respostas das dependncias, ou ento se a classe
modifcou as dependncias da maneira esperada.
Para isso, quando criamos um teste de unidade, simulamos a execuo de mtodos da classe a ser testada.
Fazemos isso passando parmetros (no caso de ser necessrio) ao mtodo testado e defnimos o resultado
que esperamos. Se o resultado for igual ao que defnimos como esperado, o teste passa. Caso contrrio, falha.
A1vNXo
Muitas vezes, principalmente quandoestamos iniciandono mundo dos testes, comumcriarmos
alguns testes que testam muito mais do que o necessrio, mais do que apenas a unidade. Tais
testes se transformamemverdadeiros testes de integrao (esses simso responsveis por testar
o sistemas como um todo).
Portanto, lembre-se sempre: testes de unidade testam apenas unidades!
. JUN:1
O JUnit (junit.org) um framework muito simples para facilitar a criao destes testes de unidade e em
especial sua execuo. Ele possui alguns mtodos que tornam seu cdigo de teste bem legvel e fcil de fazer
as asseres.
Uma assero uma afrmao: alguma invariante que em determinado ponto de execuo voc quer ga-
rantir que verdadeira. Se aquilo no for verdade, o teste deve indicar uma falha, a ser reportada para o
programador, indicando um possvel bug.
medida que voc mexe no seu cdigo, voc roda novamente toda aquela bateria de testes comumcomando
apenas. Com isso voc ganha a confana de que novos bugs no esto sendo introduzidos (ou reintrodu-
zidos) conforme voc cria novas funcionalidades e conserta antigos bugs. Mais fcil do que ocorre quando
fazemos os testes dentro do main, executando um por vez.
O JUnit possui integrao com todas as grandes IDEs, alm das ferramentas de build, que vamos conhecer
Captulo - Testes Automatizados - JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
mais a frente. Vamos agora entender um pouco mais sobre anotaes e o import esttico, que vo facilitar
muito o nosso trabalho com o JUnit.
UsnNoo o JUN:1 - coNv:ccnnNoo Ctnssvn1n v svc JAR No Ect:vsv
O JUnit uma biblioteca escrita por terceiros que vamos usar no nosso projeto. Precisamos das classes do
JUnit para escrever nossos testes. E, como sabemos, o formato de distribuio de bibliotecas Java o JAR,
muito similar a um ZIP com as classes daquela biblioteca.
Precisamos ento do JAR do JUnit no nosso projeto. Mas quando rodarmos nossa aplicao, como o Java vai
saber que deve incluir as classes daquele determinado JAR junto com nosso programa? (dependncia)
aqui que o Classpath entra histria: nele que defnimos qual o caminho para buscar as classes que vamos
usar. Temos que indicar onde a JVM deve buscar as classes para compilar e rodar nossa aplicao.
H algumas formas de confgurarmos o classpath:
Confgurando uma varivel de ambiente (desaconselhado);
Passando como argumento em linha de comando (trabalhoso);
Utilizando ferramentas como Ant e Maven (veremos mais a frente);
Deixando o eclipse confgurar por voc.
No Eclipse, muito simples:
) Clique com o boto direito em cima do nome do seu projeto.
) Escolha a opo Properties.
) Na parte esquerda da tela, selecione a opo Java Build Path.
E, nessa tela:
) Java Build Path onde voc confgura o classpath do seu projeto: lista de locais defnidos que, por
padro, s vm com a mquina virtual confgurada;
) Opes para adicionar mais caminhos, Add JARs... adiciona Jars que estejam no seu projeto; Add
External JARs adiciona Jars que estejam em qualquer outro lugar da mquina, porm guardar uma
referncia para aquele caminho (ento seu projeto poder no funcionar corretamente quando colocado
em outro micro, mas existe como utilizar variveis para isso);
No caso do JUnit, por existir integrao direta com Eclipse, o processo ainda mais fcil, como veremos no
exerccio. Mas para todas as outras bibliotecas que formos usar, basta copiar o JAR e adicion-lo ao Build
Path. Vamos ver esse procedimento com detalhes quando usarmos as bibliotecas que trabalham com XML
e grfcos em captulos posteriores.
Captulo - Testes Automatizados - JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. ANo1novs
Anotao a maneira de escrever metadados na prpria classe, isto , confguraes ou outras informaes
pertinentes a essa classe. Esse recurso foi introduzido no Java .. Algumas anotaes podem ser mantidas
(retained) no .class, permitindo que possamos reaver essas informaes, se necessrio.
utilizada, por exemplo, para indicar que determinada classe deve ser processada por um framework de
uma certa maneira, evitando assim as clssicas confguraes atravs de centenas de linhas de XML.
Apesar dessa propriedade interessante, algumas anotaes servem apenas para indicar algo ao compilador.
@Override o exemplo disso. Caso voc use essa anotao em um mtodo que no foi reescrito, vai haver
um erro de compilao! A vantagem de us-la apenas para facilitar a legibilidade.
@Deprecated indica que ummtodo no deve ser mais utilizado por algummotivo e decidiramno retir-lo
da API para no quebrar programas que j funcionavam anteriormente.
@SurpressWarnings indica para o compilador que ele no deve dar warnings a respeito de determinado
problema, indicando que o programador sabe o que est fazendo. Umexemplo o warning que o compilador
do Eclipse d quando voc no usa determinada varivel. Voc vai ver que um dos quick fxes a sugesto
de usar o @SupressWarnings.
Anotaes podem receber parmetros. Existem muitas delas na API do java , mas realmente ainda mais
utilizada em frameworks, como o Hibernate , o EJB e o JUnit.
. JUN:1, coNvvNovs v nNo1nXo
Para cada classe, teremos uma classe correspondente (por conveno, com o sufxo Test) que contar todos
os testes relativos aos mtodos dessa classe. Essa classe fcar no pacote de mesmo nome, mas na Source
Folder de testes (src/test/java).
Por exemplo, para a nossa CandlestickFactory, teremos a CandlestickFactoryTest:
package br.com.caelum.argentum.modelo;
public class CandlestickFactoryTest {
public void sequenciaSimplesDeNegociacoes() {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(39.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(42.3, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1, negociacao2,
Captulo - Testes Automatizados - Anotaes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
negociacao3, negociacao4);
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
}
}
Emvez de ummain, criamos ummtodo comnome expressivo para descrever a situao que ele est testando.
Mas... como o JUnit saber que deve executar aquele mtodo? Para isso anotamos este mtodo com @Test,
que far com que o JUnit saiba no momento de execuo, por refection, de que aquele mtodo deva ser
executado:
public class CandlestickFactoryTest {
@Test
public void sequenciaSimplesDeNegociacoes() {
// ...
}
}
Pronto! Quando rodarmos essa classe como sendo um teste do JUnit, esse mtodo ser executado e a View
do JUnit no Eclipse mostrar se tudo ocorreu bem. Tudo ocorre bem quando o mtodo executado sem
lanar excees inesperadas e se todas as asseres passarem.
Uma assero uma verifcao. Ela realizada atravs dos mtodos estticos da classe Assert, importada
do org.junit. Por exemplo, podemos verifcar se o valor de abertura desse candle .:
Assert.assertEquals(40.5, candle.getAbertura(), 0.00001);
Oprimeiro argumento o que chamamos de expected, e ele representa o valor que esperamos para argumento
seguinte (chamado de actual). Se o valor real for diferente do esperado, o teste no passar e uma barrinha
vermelha ser mostrada, juntamente com uma mensagem que diz:
expected <valor esperado> but was <o que realmente deu>
Docntv v :Nvxn1o
Logo na primeira discusso desse curso, conversamos sobre a inexatido do double ao trabalhar com arre-
dondamentos. Porm, diversas vezes, gostaramos de comparar o double esperado e o valor real, sem nos
preocupar com diferenas de arredondamento quando elas so muito pequenas.
OJUnit trata esse caso adicionando umterceiro argumento, que s necessrio quando comparamos valores
double ou foat. Ele um delta que se aceita para o erro de comparao entre o valor esperado e o real.
Captulo - Testes Automatizados - JUnit, convenes e anotao - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Por exemplo, quando lidamos com dinheiro, o que nos importa so as duas primeiras casas decimais e,
portanto, no h problemas se o erro for na quinta casa decimal. Em sofwares de engenharia, no entanto,
um erro na quarta casa decimal pode ser um grande problema e, portanto, o delta deve ser ainda menor.
Nosso cdigo fnal do teste, agora com as devidas asseres, fcar assim:
public class CandlestickFactoryTest {
@Test
public void sequenciaSimplesDeNegociacoes() {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(39.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(42.3, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1, negociacao2,
negociacao3, negociacao4);
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
Assert.assertEquals(40.5, candle.getAbertura(), 0.00001);
Assert.assertEquals(42.3, candle.getFechamento(), 0.00001);
Assert.assertEquals(39.8, candle.getMinimo(), 0.00001);
Assert.assertEquals(45.0, candle.getMaximo(), 0.00001);
Assert.assertEquals(1676.0, candle.getVolume(), 0.00001);
}
}
Existem ainda outras anotaes principais e mtodos importantes da classe Assert, que conheceremos no
decorrer da construo do projeto.
. Exvncc:os: m:cnnNoo os 1vs1vs oo mn:N vnnn JUN:1
) considerada boa prtica separar as classes de testes das classes principais. Para isso, normalmente se
cria um novo source folder apenas para os testes. Vamos fazer isso:
a) Ctrl + N e comece a digitar Source Folder at que o fltro a encontre:
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
b) Preencha com src/test/java e clique Finish:
nesse novo diretrio em que voc colocar todos seus testes de unidade.
) Vamos criar um novo unit test em cima da classe CandlestickFactory. O Eclipse j ajuda bastante: com
o editor na CandlestickFactory, crie um novo (ctrl + N) JUnit Test Case.
Na janela seguinte, selecione o source folder como src/test/java. No esquea, tambm, de selecionar
JUnit.
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Ao clicar em Finish, o Eclipse te perguntar se pode adicionar os jars do JUnit no projeto.
Aanotao @Test indica que aquele mtodo deve ser executado na bateria de testes, e a classe Assert pos-
sui uma srie de mtodos estticos que realizam comparaes, e no caso de algum problema um exceo
lanada.
Vamos colocar primeiro o teste inicial:
public class CandlestickFactoryTest {
@Test
public void sequenciaSimplesDeNegociacoes() {
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(39.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(42.3, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1, negociacao2,
negociacao3, negociacao4);
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
Assert.assertEquals(40.5, candle.getAbertura(), 0.00001);
Assert.assertEquals(42.3, candle.getFechamento(), 0.00001);
Assert.assertEquals(39.8, candle.getMinimo(), 0.00001);
Assert.assertEquals(45.0, candle.getMaximo(), 0.00001);
Assert.assertEquals(1676.0, candle.getVolume(), 0.00001);
}
}
Para rodar, use qualquer um dos seguintes atalhos:
ctrl + F: roda o que estiver aberto no editor;
alt + shif + X (solte) T: roda testes do JUnit.
No se assuste! Houve a falha porque o nmero esperado do volume est errado no teste. Repare que
o Eclipse j associa a falha para a linha exata da assero e explica porque falhou:
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O nmero correto mesmo .. Adicione esse zero na classe de teste e rode-o novamente:
comum digitarmos errado no teste e o teste falhar, por isso, importante sempre verifcar a corretude
do teste, tambm!
) Vamos adicionar outro mtodo de teste mesma classe CandlestickFactoryTest, dessa vez para testar
o mtodo no caso de no haver nenhuma negociao:
@Test
public void semNegociacoesGeraCandleComZeros() {
Calendar hoje = Calendar.getInstance();
List<Negociacao> negociacoes = Arrays.asList();
CandlestickFactory fabrica = new CandlestickFactory();
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
Assert.assertEquals(0.0, candle.getVolume(), 0.00001);
}
Rode o teste com o mesmo atalho.
) E, agora, vamos para o que tem apenas uma negociao e estava falhando. Ainda na classe
CandlestickFactoryTest adicione o mtodo: (repare que cada classe de teste possui vrios mtodos
com vrios casos diferentes)
@Test
public void apenasUmaNegociacaoGeraCandleComValoresIguais() {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
List<Negociacao> negociacoes = Arrays.asList(negociacao1);
CandlestickFactory fabrica = new CandlestickFactory();
Candlestick candle = fabrica.constroiCandleParaData(hoje, negociacoes);
Assert.assertEquals(40.5, candle.getAbertura(), 0.00001);
Assert.assertEquals(40.5, candle.getFechamento(), 0.00001);
Assert.assertEquals(40.5, candle.getMinimo(), 0.00001);
Assert.assertEquals(40.5, candle.getMaximo(), 0.00001);
Assert.assertEquals(4050.0, candle.getVolume(), 0.00001);
}
Rode o teste. Repare no erro:
Captulo - Testes Automatizados - Exerccios: migrando os testes do main para JUnit - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Como consertar?
. Vntv n vvNn 1vs1nn ctnssvs ov moovto:
Faz todo sentido testar classes como a CandlestickFactory, j que existe um algoritmo nela, alguma lgica
que deve ser executada e h uma grande chance de termos esquecido algum comportamento para casos
incomuns - como vimos nos testes anteriores.
Mas as classes de modelo, Negociacao e Candlestick, tambm precisam ser testadas?
A resposta para essa pergunta um grande e sonoro sim! Apesar de serem classes mais simples elas tambm
tm comportamentos especfcos como:
) as classes Negociacao e Candlestick devem ser imutveis, isto , no devemos ser capazes de alterar
nenhuma de suas informaes depois que o objeto criado;
) valores negativos tambm no deveriam estar presentes nas negociaes e candles;
) se voc fez o opcional CandleBuilder, ele no deveria gerar a candle se os valores no tiverem sido preen-
chidos;
) etc...
Por essa razo, ainda que sejam classes mais simples, elas merecem ter sua integridade testada - mesmo
porque so os objetos que representam nosso modelo de negcios, o corao do sistema que estamos desen-
volvendo.
Captulo - Testes Automatizados - Vale a pena testar classes de modelo? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. Exvncc:os: Novos 1vs1vs
) A classe Negociacao realmente imutvel?
Vamos criar um novo Unit Test para a classe Negociacao. O processo o mesmo que fzemos para o teste
da CandlestickFactory: abra a classe Negociacao no editor e faa Ctrl + N JUnit Test Case.
Lembre-se de alterar a Source Folder para src/test/java e selecionar o JUnit .
public class NegociacaoTest {
@Test
public void dataDaNegociacaoEhImutavel() {
// se criar um negocio no dia 15...
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, 15);
Negociacao n = new Negociacao(10, 5, c);
// ainda que eu tente mudar a data para 20...
n.getData().set(Calendar.DAY_OF_MONTH, 20);
// ele continua no dia 15.
Assert.assertEquals(15, n.getData().get(Calendar.DAY_OF_MONTH));
}
}
Voc pode rodar esse teste apenas, usando o atalho (alt + shif + X T) ou pode fazer melhor e o que mais
comum, rodar todos os testes de unidade de um projeto.
Basta selecionar o projeto na View Package Explorer e mandar rodar os testes: para essa ao, o nico
atalho possvel o alt + shift + X T.
Captulo - Testes Automatizados - Exerccios: novos testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Esse teste falha porque devolvemos um objeto mutvel atravs de um getter. Deveramos ter retornado
uma cpia desse objeto para nos assegurarmos que o original permanece intacto.
Evvvc1:vv Jnvn
Item : Faa cpias defensivas quando necessrio.
Basta alterar a classe Negociacao e utilizar o mtodo clone que todos os objetos tm (mas s quem
implementa Cloneable executar com xito):
public Calendar getData() {
return (Calendar) this.data.clone();
}
Sem clone, precisaramos fazer esse processo na mo. Com Calendar relativamente fcil:
public Calendar getData() {
Calendar copia = Calendar.getInstance();
copia.setTimeInMillis(this.data.getTimeInMillis());
return copia;
}
Com outras classes, em especial as que tem vrios objetos conectados, isso pode ser mais complicado.
Captulo - Testes Automatizados - Exerccios: novos testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
L:s1ns v nnnnvs
Esse tambm um problema que ocorre muito com colees e arrays: se voc retorna uma List
que um atributo seu, qualquer um pode adicionar ou remover um elemento de l, causando
estrago nos seus atributos internos.
Os mtodos Collections.unmodifiableList(List) e outros ajudam bastante nesse trabalho.
) Podemos criar uma Negociacao com data nula? Por enquanto, podemos, mas no deveramos. Para que
outras partes do meu sistema no se surpreendammais tarde, vamos impedir que a Negociacao seja criada
se sua data estiver nula, isto , vamos lanar uma exceo.
Mas qual exceo? Vale a pena criar uma nova exceo para isso?
A exceo padro no Java para cuidar de parmetros indesejveis a IllegalArgumentException ento,
em vez de criar uma nova com a mesma semntica, vamos us-la para isso.
Evvvc1:vv Jnvn
Item : Favorea o uso das excees padres!
Antes de fazer a modifcao na classe, vamos preparar o teste. Mas o que queremos testar? Queremos
saber se nossa classe Negociacao no permite a criao do objeto e lana uma IllegalArgumentException
quando passamos null no construtor.
Ou seja, esperamos que uma exceo acontea! Para o teste passar, ele precisa dar a exceo (parece meio
contraditrio). fcil fazer isso com JUnit.
Adicione um novo mtodo naoCriaNegociacaoComDataNula na classe NegociacaoTest. Repare que
agora temos um argumento na anotao expected=IllegalArgumentException.class. Isso indica que,
para esse teste ser considerado um sucesso, uma exceo deve ser lanada daquele tipo. Caso contrrio
ser uma falha:
@Test(expected=IllegalArgumentException.class)
public void naoCriaNegociacaoComDataNula() {
new Negociacao(10, 5, null);
}
Rode os testes. Barrinha vermelha! J que ainda no verifcamos o argumento na classe Negociacao e
ainda no lanamos a exceo:
Captulo - Testes Automatizados - Exerccios: novos testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Vamos alterar a classe Negociacao, para que ela lance a exceo no caso de data nula. No construtor,
adicione o seguinte if:
public Negociacao(double preco, int quantidade, Calendar data) {
if (data == null) {
throw new IllegalArgumentException("data nao pode ser nula");
}
this.preco = preco;
this.quantidade = quantidade;
this.data = data;
}
Rode novamente os testes.
Captulo - Testes Automatizados - Exerccios: novos testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) (opcional) Nosso teste para quando no h negociaes na CandlestickFactory est verifcando apenas
se o volume zero. Ele tambm poderia verifcar que os outros valores dessa candle so zero.
Modifque o mtodo semNegociacoesGeraCandleComZeros e adicione os asserts faltantes de abertura,
fechamento, mnimo e mximo.
O teste vai parar de passar!
Corrija ele da mesma forma que resolvemos o problema para as variveis abertura e fechamento.
) (opcional) Um Candlestick pode ter preo mximo menor que o preo mnimo? No deveria.
Crie um novo teste, o CandlestickTest, da maneira que fzemos com o Negociacao. boa prtica que
todos os testes da classe X se encontrem em XTest.
Dentro dele, crie o precoMaximoNaoPodeSerMenorQueMinimo e faa um new passando argumentos que
quebrem isso. O teste deve esperar pela IllegalArgumentException.
A ideia testar se o construtor de Candlestick faz as validaes necessrias. Lembre-se que o constru-
tor recebe como argumento Candlestick(abertura, fechamento, minimo, maximo, volume, data),
portanto queremos testar se algo assim gera uma exceo (e deveria gerar):
new Candlestick(10, 20, 20, 10, 10000, Calendar.getInstance());
) (opcional) Um Candlestick pode ter data nula? Pode ter algum valor negativo?
Teste, verifque o que est errado, altere cdigo para que os testes passem! Pegue o ritmo, essa ser sua
rotina daqui para a frente.
Captulo - Testes Automatizados - Exerccios: novos testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) (opcional) Crie mais dois testes na CandlestickFactoryTest: o negociacoesEmOrdemCrescenteDeValor
e negociacoesEmOrdemDecrescenteDeValor, que devem fazer o que o prprio nome diz.
Agora eles funcionam?
. Pnnn snnvn mn:s: Imvon1 Es1K1:co
Algumas vezes, escrevemos classes que contm muitos mtodos e atributos estticos (fnais, como constan-
tes). Essas classes so classes utilitrias e precisamos sempre nos referir a elas antes de chamar um mtodo
ou utilizar um atributo:
import pacote.ClasseComMetodosEstaticos;
class UsandoMetodosEstaticos {
void metodo() {
ClasseComMetodosEstaticos.metodo1();
ClasseComMetodosEstaticos.metodo2();
}
}
Comea a fcar muito chato escrever, toda hora, o nome da classe. Para resolver esse problema, no Java .
foi introduzido o static import, que importa mtodos e atributos estticos de qualquer classe. Usando essa
nova tcnica, voc pode importar os mtodos do exemplo anterior e us-los diretamente:
import static pacote.ClasseComMetodosEstaticos.*;
class UsandoMetodosEstaticos {
void metodo() {
metodo1();
metodo2();
}
}
Apesar de voc ter importado todos os mtodos e atributos estticos da classe ClasseComMetodosEstaticos,
a classe em si no foi importada e, se voc tentasse dar new, por exemplo, ele no conseguiria encontr-la,
precisando de um import normal parte.
Um bom exemplo de uso so os mtodos e atributos estticos da classe Assert do JUnit:
import static org.junit.Assert.*;
class TesteMatematico {
@Test
void doisMaisDois() {
Captulo - Testes Automatizados - Para saber mais: Import Esttico - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
assertEquals(4, 2 + 2);
}
}
Use os imports estticos dos mtodos de Assert nos testes de unidade que voc escreveu.
. Mn:s vxvncc:os ovc:oNn:s
) Crie um teste para o CandleBuilder. Ele possui um grande erro: se s chamarmos alguns dos mtodos,
e no todos, ele construir um Candle invlido, com data nula, ou algum nmero zerado.
Faa umteste geracaoDeCandleDeveTerTodosOsDadosNecessarios que tente isso. Omtodo geraCandle
deveria lanar outra exception conhecida da biblioteca Java, a IllegalStateException, quando invocado
antes dos seus outros seis mtodos j terem sido.
O teste deve falhar. Corrija-o criando booleans que indicam se cada mtodo setter foi invocado, ou utili-
zando alguma outra forma de verifcao.
) Se voc fez os opcionais do primeiro exerccio do captulo anterior (criao do projeto e dos modelos)
voc tem os mtodos isAlta e isBaixa na classe Candlestick. Contudo, temos um comportamento no
especifcado nesses mtodos: e quando o preo de abertura for igual ao de fechamento?
Perguntando para nosso cliente, ele nos informou que, nesse caso, o candle deve ser considerado de alta.
Crie o teste quandoAberturaIgualFechamentoEhAlta dentro de CandlestickTest, verifque se isso est
ocorrendo. Se o teste falhar, faa mudanas no seu cdigo para que a barra volte a fcar verde!
) O que mais pode ser testado? Testar viciante, e aumentar o nmero de testes do nosso sistema comea
a virar um hbito divertido e contagioso. Isso no ocorre de imediato, necessrio um tempo para se
apaixonar por testes.
. D:sccssXo vmnctn: 1vs1vs sXo :mvon1nN1vs:
Captulo - Testes Automatizados - Mais exerccios opcionais - Pgina
C
Trabalhando com XML
Se eu enxerguei longe, foi por ter subido nos ombros de gigantes."
Isaac Newton
. Os onoos on notsn ov vntonvs
Como vamos puxar os dados da bolsa de valores para popular nossos candles?
Existem inmeros formatos para se trabalhar com diversas bolsas. Sem dvida XML um formato comu-
mente encontrado em diversas indstrias, inclusive na bolsa de valores.
Utilizaremos esse tal de XML. Para isso, precisamos conhec-lo mais a fundo, seus objetivos, e como
manipul-lo. Considere que vamos consumir um arquivo XML como o que segue:
<list>
<negociacao>
<preco>43.5</preco>
<quantidade>1000</quantidade>
<data>
<time>1222333777999</time>
</data>
</negociacao>
<negociacao>
<preco>44.1</preco>
<quantidade>700</quantidade>
<data>
<time>1222444777999</time>
</data>
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
</negociacao>
<negociacao>
<preco>42.3</preco>
<quantidade>1200</quantidade>
<data>
<time>1222333999777</time>
</data>
</negociacao>
</list>
Uma lista de negociaes! Cada negociao informa o preo, quantidade e uma data. Essa data composta
por um horrio dado no formato de Timestamp, e opcionalmente um Timezone.
. Ovonmn1o XML
XML (eXtensible Markup Language) uma formalizao da WC para gerar linguagens de marcao que
podem se adaptar a quase qualquer tipo de necessidade. Algo bem extensvel, fexvel, de fcil leitura e
hierarquizao. Sua defnio formal pode ser encontrada em:
http://www.w.org/XML/
Exemplo de dados que so armazenados em XMLs e que no conhecemos to bem, o formato aberto de
grfcos vetoriais, o SVG(usado pelo Corel Draw, Firefox, Inkscape, etc), e o Open Document Format (ODF),
formato usado pelo OpenOfce, e hoje em dia um padro ISO de extrema importncia. (na verdade o ODF
um ZIP que contm XMLs internamente).
A ideia era criar uma linguagem de marcao que fosse muito fcil de ser lida e gerada por sofwares, e
pudesse ser integrada as outras linguagens. Entre seus princpios bsicos, defnidos pelo WC:
Separao do contedo da formatao
Simplicidade e Legibilidade
Possibilidade de criao de tags novas
Criao de arquivos para validao (DTDs e schemas)
O XML uma excelente opo para documentos que precisam ter seus dados organizados com uma certa
hierarquia (uma rvore), com relao de pai-flho entre seus elementos. Esse tipo de arquivo difcilmente
organizado com CSVs ou properties. Como a prpria imagem do wikipedia nos trs e mostra o uso estrutu-
rado e encadeado de maneira hierrquica do XML:
Captulo - Trabalhando com XML - O formato XML - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O cabealho opcional de todo XML o que se segue:
<?xml version="1.0" encoding="ISO-8859-1"?>
Esses caracteres no devem ser usados como elemento, e devem ser escapados":
&, use &amp;
, use &apos;
, use &quot;
<, use &lt;
>, use &gt;
Voc pode, em Java, utilizar a classe String e as regex do pacote java.util.regex para criar um programa
que l um arquivo XML. Isso uma grande perda de tempo, visto que o Java, assim como quase toda e
qualquer linguagemexistente, possui uma ou mais formas de ler umXML. OJava possui diversas, vamos ver
algumas delas, suas vantagens e suas desvantagens.
. LvNoo XML comJnvn ov mnNv:nn o:vc:t, o SAX
OSAX(Simple API for XML) uma API para ler dados emXML, tambmconhecido como Parser de XML.
Um parser serve para analisar uma estrutura de dados e geralmente o que fazemos transform-la em uma
outra.
Neste processo de anlise tambm podemos ler o arquivo XML para procurar algum determinado elemento
e manipular seu contedo.
O parser l os dados XML como um fuxo ou uma sequncia de dados. Baseado no contedo lido, o parser
vai disparando eventos. o mesmo que dizer que o parser SAX funciona orientado a eventos.
Existem vrios tipos de eventos, por exemplo:
Captulo - Trabalhando com XML - Lendo XML com Java de maneira difcil, o SAX - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
incio do documento XML;
incio de um novo elemento;
novo atributo;
incio do contedo dentro de um elemento.
Para tratar estes eventos, o programador deve passar um objeto listener ao parser que ser notifcado auto-
maticamente pelo parser quando umdesses eventos ocorrer. Comumente, este objeto chamado de Handler,
Observer, ou Listener e quem faz o trabalho necessrio de processamento do XML.
public class NegociacaoHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName,
String name, Attributes attributes) throws SAXException {
// aqui voc avisado, por exemplo
// do inicio da tag "<preco>"
}
@Override
public void characters(char[] chars, int offset, int len)
throws SAXException {
// aqui voc seria avisado do inicio
// do contedo que fica entre as tags, como por exemplo 30
// de dentro de "<preco>30</preco>"
// para saber o que fazer com esses dados, voc precisa antes ter
// guardado em algum atributo qual era a negociao que estava
// sendo percorrida
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// aviso de fechamento de tag
}
}
Aclasse DefaultHandler permite que voc reescreva mtodos que vo te notifcar sobre quando umelemento
(tag) est sendo aberto, quando est sendo fechado, quando caracteres esto sendo parseados (contedo de
Captulo - Trabalhando com XML - Lendo XML com Java de maneira difcil, o SAX - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
uma tag), etc.. Voc o responsvel por saber em que posio do object model (rvore) est, e que atitude
deve ser tomada. A interface ContentHandler defne mais alguns outros mtodos.
Ccn:os:onov sonnv o SAX
Originalmente o SAX foi escrito s para Java e vem de um projeto da comunidade (http://www.
saxproject.org) , mas existem outras implementaes em C++, Perl e Python.
O SAX est atualmente na verso e faz parte do JAX-P (Java API for XML Processing).
O SAX somente sabe ler dados e nunca modifc-los e s consegue ler para frente, nunca para trs. Quando
passou um determinado pedao do XML que j foi lido, no h mais como voltar. O parser SAX no guarda
a estrutura do documento XML na memria.
Tambm no h como fazer acesso aleatrio aos itens do documento XML, somente sequencial.
Por outro lado, como os dados vo sendo analisados e transformados (pelo Handler) na hora da leitura, o
SAX ocupa pouca memria, principalmente porque nunca vai conhecer o documento inteiro e sim somente
umpequeno pedao. Devido tambma leitura sequencial, ele muito rpido comparado comos parsers que
analisam a rvore do documento XML completo.
Quando for necessrio ler um documento em partes ou s determinado pedao e apenas uma vez, o SAX
parser uma excelente opo.
S1AX - S1nvnm:Nc API von XML
StAX um projeto que foi desenvolvido pela empresa BEA e padronizado pela JSR-. Ele
mais novo do que o SAX e foi criado para facilitar o trabalho com XML. StAX faz parte do Java
SE e JAX-P.
Como o SAX, o StAX tambm l os dados de maneira sequencial. A diferena entre os dois a
forma como notifcada a ocorrncia de um evento.
No SAXtemos que registrar umHandler. o SAXque avisa o Handler e chama os mtodos dele.
Ele empurra os dados para o Handler e por isso ele um parser do tipo push, .
OStAX, ao contrrio, no precisa deste Handler. Podemos usar a API do StAXpara chamar seus
mtodos, quando e onde preciso. O cliente decide, e no o parser. ele quem pega/tira os
dados do StAX e por isso um parser do tipo pull.
O site http://www.xmlpull.org fornece mais informaes sobre a tcnica de Pull Parsing, que
tem sido considerada por muitos como a forma mais efciente de processar documentos xml.
Abiblioteca XPP a implementao emJava mais conhecida deste conceito. usada por outras
bibliotecas de processamento de xml, como o CodeHaus XStream.
Captulo - Trabalhando com XML - Lendo XML com Java de maneira difcil, o SAX - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. XS1nvnm
O XStream uma alternativa perfeita para os casos de uso de XML em persistncia, transmisso de dados e
confgurao. Sua facilidade de uso e performance elevada so os seus principais atrativos.
um projeto hospedado na Codehaus, um repositrio de cdigo open source focado em Java, que foi for-
mado por desenvolvedores de famosos projetos como o XDoclet, PicoContainer e Maven. Ogrupo patroci-
nado por empresas como a ToughWorks, BEAe Atlassian. Entre os desenvolvedores do projeto, Guilherme
Silveira da Caelum est tambm presente.
http://xstream.codehaus.org
Diversos projetos opensource, como o container de inverso de controle NanoContainer, o framework de
redes neurais Joone, dentre outros, passaram a usar XStream depois de experincias com outras bibliotecas.
O XStream conhecido pela sua extrema facilidade de uso. Repare que raramente precisaremos fazer conf-
guraes ou mapeamentos, como extremamente comum nas outras bibliotecas mesmo para os casos mais
bsicos.
Como gerar o XML de uma negociao? Primeiramente devemos ter uma referncia para o objeto. Podemos
simplesmente cri-lo e popul-lo ou ento deixar que o Hibernate faa isso.
Com a referncia negociacao em mos, basta agora pedirmos ao XStream que gera o XML correspondente:
Negociacao negociacao = new Negociacao(42.3, 100, Calendar.getInstance());
XStream stream = new XStream(new DomDriver());
System.out.println(stream.toXML(negociacao));
E o resultado :
<br.com.caelum.argentum.Negociacao>
<preco>42.3</preco>
<quantidade>100</quantidade>
<data>
<time>1220009639873</time>
<timezone>America/Sao_Paulo</timezone>
</data>
</br.com.caelum.argentum.Negociacao>
A classe XStream atua como faade de acesso para os principais recursos da biblioteca. O construtor da
classe XStream recebe como argumento um Driver, que a engine que vai gerar/consumir o XML. Aqui
voc pode defnir se quer usar SAX, DOM, DOMJ dentre outros, e com isso o XStream ser mais rpido,
mais lento, usar mais ou menos memria, etc.
Odefault do XStream usar umdriver chamado XPP, desenvolvido na universidade de Indiana e conhecido
por ser extremamente rpido (leia mais no box de pull parsers). Para us-lo voc precisa de um outro JAR
no classpath do seu projeto.
Captulo - Trabalhando com XML - XStream - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O mtodo toXML retorna uma String. Isso pode gastar muita memria no caso de voc serializar uma lista
grande de objetos. Ainda existe um overload do toXML, que alm de um Object recebe um OutputStream
como argumento para voc poder gravar diretamente num arquivo, socket, etc.
Diferentemente de outros parsers do Java, o XStreamserializa por default os objetos atravs de seus atributos
(sejam privados ou no), e no atravs de getters e setters.
Repare que o XStream gerou a tag raiz com o nome de br.com.caelum.argentum.Negociacao. Isso porque
no existe um conversor para ela, ento ele usa o prprio nome da classe e gera o XML recursivamente para
cada atributo no transiente daquela classe.
Porm, muitas vezes temos um esquema de XML j muito bem defnido, ou simplesmente no queremos
gerar um XML com cara de java. Para isso podemos utilizar um alias. Vamos modifcar nosso cdigo que
gera o XML:
XStream stream = new XStream(new DomDriver());
stream.alias("negociacao", Negociacao.class);
Essa confgurao tambm pode ser feita atravs da anotao @XStreamAlias("negociacao") em cima da
classe Negociacao.
Podemos agora fazer o processo inverso. Dado umXML que representa umbean da nossa classe Negociacao,
queremos popular esse bean. O cdigo novamente extremamente simples:
XStream stream = new XStream(new DomDriver());
stream.alias("negociacao", Negociacao.class);
Negociacao n = (Negociacao) stream.fromXML("<negociacao>" +
"<preco>42.3</preco>" +
"<quantidade>100</quantidade>" +
"</negociacao>");
System.out.println(negociacao.getPreco());
Obviamente no teremos um XML dentro de um cdigo Java. O exemplo aqui meramente ilustrativo (til
emumteste!). Os atributos no existentes fcaro como null no objeto, como o caso aqui do atributo data,
ausente no XML.
O XStreampossui uma sobrecarga do mtodo fromXML que recebe um InputStream como argumento, outro
que recebe um Reader.
JAXB oc XS1nvnm:
Avantagemdo JAXB ser uma especifcao do Java, e a do XStream ser mais fexvel e permitir
trabalhar com classes imutveis.
Captulo - Trabalhando com XML - XStream - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
@XS1nvnmAt:ns
Em vez de chamar stream.alias("negociacao", Negociacao.class);, podemos fazer essa
confgurao direto na classe Negociacao com uma anotao:
@XStreamAlias("negociacao")
public class Negociacao {
}
Para habilitar o suporte a anotaes, precisamos chamar no xstream:
stream.autodetectAnnotations(true);
Ou ento, se precisarmos processar as anotaes de apenas uma nica classe, basta indic-la,
como abaixo:
stream.processAnnotations(Negociacao.class);
Note que trabalhar com as anotaes, portanto, no nos economiza linhas de cdigo. Sua prin-
cipal vantagem manter as confguraes centralizadas e, assim, se houver mais de uma parte
na sua aplicao responsvel por gerar XMLs de ummesmo modelo, no corremos o risco de ter
XMLs incompatveis.
. Exvncc:os: LvNoo o XML
) Para usarmos o XStream, precisamos copiar seus JARs para o nosso projeto e adicion-los ao Build Path.
Para facilitar, vamos criar uma pasta lib para colocar todos os JARs que necessitarmos.
Crie uma nova pasta usando ctrl + N e comeando a digitar Folder:
Captulo - Trabalhando com XML - Exerccios: Lendo o XML - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Coloque o nome de lib e clique OK:
) Vamos pr o XStream no nosso projeto. V na pasta Caelum no seu Desktop e entre em . Localize o
arquivo do XStream:
Esse o mesmo arquivo que voc encontra para download no site do XStream, na verso minimal.
) Copie o JAR do XStream . para a pasta lib/ do Argentum e, pelo Eclipse, entre na pasta lib e d refresh
(F) nela.
Ento, selecione o JAR, clique com o boto direito e v em Build Path, Add to build path. A partir de
agora o Eclipse considerar as classes do XStream para esse nosso projeto.
Captulo - Trabalhando com XML - Exerccios: Lendo o XML - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Vamos, fnalmente, implementar a leitura do XML, delegando o trabalho para o XStream. Criamos a
classe LeitorXML dentro do pacote br.com.caelum.argentum.reader:
package br.com.caelum.argentum.reader;
// imports...
public class LeitorXML {
public List<Negociacao> carrega(InputStream inputStream) {
XStream stream = new XStream(new DomDriver());
stream.alias("negociacao", Negociacao.class);
return (List<Negociacao>) stream.fromXML(inputStream);
}
}
) Crie um teste de unidade LeitorXMLTest pelo Eclipse para testarmos a leitura do XML. Com o cursor na
classe LeitorXML, faa Ctrl + N e digite JUnit Test Case:
Lembre-se de coloc-lo na source folder src/test/java.
Para no ter de criar um arquivo XML no sistema de arquivos, podemos usar um truque interessante:
coloque o trecho do XML em uma String Java, e passe um ByteArrayInputStream, convertendo nossa
String para byte atravs do mtodo getBytes():
@Test
public void carregaXmlComUmaNegociacaoEmListaUnitaria() {
String xmlDeTeste = "..."; // o XML vai aqui!
LeitorXML leitor = new LeitorXML();
InputStream xml = new ByteArrayInputStream(xmlDeTeste.getBytes());
List<Negociacao> negociacoes = leitor.carrega(xml);
}
Use o seguinte XML de teste, substituindo a linha em negrito acima:
String xmlDeTeste = "<list>" +
" <negociacao>" +
" <preco>43.5</preco>" +
" <quantidade>1000</quantidade>" +
" <data>" +
" <time>1322233344455</time>" +
" </data>" +
" </negociacao>" +
"</list>";
Captulo - Trabalhando com XML - Exerccios: Lendo o XML - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Um teste de nada serve se no tiver suas verifcaes. Assim, no esquea de verifcar valores esperados
como:
a lista devolvida deve ter tamanho ;
a negociao deve ter preo .;
a quantidade deve ser .
) (Opcional) Crie mais alguns testes para casos excepcionais, como:
Zero negociaes;
Preo ou quantidade faltando;
Outras quantidades de negociaes (, por exemplo).
) (importante, conceitual) E o que falta agora? Testar nosso cdigo com um XML real?
muito comum sentirmos a vontade de fazer um teste maior": um teste que realmente abre um
InputStreamReader, passa o XML para o LeitorXML e depois chama a CandlestickFactory para que-
brar as negociaes em candles.
Esse teste seria um chamado teste de integrao - no de unidade. Se crissemos esse teste e ele falhasse,
seria muito mais difcil detectar o ponto de falha!
Pensar emsempre testar as menores unidades possveis nos fora a pensar emclasses menos dependentes
entre si, isto , com baixo acoplamento. Por exemplo: poderamos ter criado um LeitorXML que interna-
mente chamasse a fbrica e devolvesse diretamente uma List<Candlestick>. Mas isso faria com que o
nosso teste do leitor de XML testasse muito mais que apenas a leitura de XML (j que estaria passando
pela CandlestickFactory).
. D:sccssXo vmnctn: ONov csnn XML v o nncso oo mvsmo
Captulo - Trabalhando com XML - Discusso em aula: Onde usar XML e o abuso do mesmo - Pgina
C
Test Driven Design - TDD
Experincia sem teoria cegueira, mas teoria sem experincia mero jogo intelectual."
Immanuel Kant
. SvvnnnNoo ns cnNotvs
Agora que temos nosso leitor de XML que cria uma lista com as negociaes representadas no arquivo pas-
sado, um novo problema surge: a BOVESPA permite fazer download de um arquivo XML contendo todas
as negociaes de umativo desde a data especifcada. Entretanto, nossa CandlestickFactory est preparada
apenas para construir candles de uma data especfca.
Dessa forma, precisamos ainda quebrar a lista que contm todas as negociaes em partes menores, com
negociaes de um dia apenas, e usar o outro mtodo para gerar cada Candlestick. Essas, devem ser arma-
zenadas em uma nova lista para serem devolvidas.
Para fazer tal lgica, ento, precisamos:
passar por cada negociaes da lista original;
verifcar se continua no mesmo dia e...
...se sim, adiciona na lista do dia;
...caso contrrio:
gera a candle;
guarda numa lista de Candlesticks;
zera a lista de negociaes do dia;
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
indica que vai olhar o prximo dia, agora;
ao fnal, devolver a lista de candles;
O algoritmo no trivial e, ainda, ele depende de uma verifcao que o Java no nos d prontamente: se
continua no mesmo dia. Isto , dado que eu sei qual a dataAtual, quero verifcar se a negociao pertence a
esse mesmo dia.
Verifcar uma negociao do mesmo dia que um Calendar qualquer exige algumas linhas de cdigo, mas
veja que, mesmo antes de implement-lo, j sabemos como o mtodo isMesmoDia dever se comportar em
diversas situaes:
se for exatamente o mesmo milissegundo => true;
se for no mesmo dia, mas em horrios diferentes => true;
se for no mesmo dia, mas em meses diferentes => false;
se for no mesmo dia e ms, mas em anos diferentes => false.
Sempre que vamos comear a desenvolver uma lgica, intuitivamente, j pensamos em seu comportamento.
Fazer os testes automatizados para tais casos , portanto, apenas colocar nosso pensamento em forma de
cdigo. Mas faz-lo incrementalmente, mesmo antes de seguir com a implementao o princpio do que
chamamos de Test Driven Design (TDD).
. VnN1ncvNs oo TDD
TDD uma tcnica que consiste em pequenas iteraes, em que novos casos de testes de funcionalidades
desejadas so criados antes mesmo da implementao. Nesse momento, o teste escrito deve falhar, j que
a funcionalidade implementada no existe. Ento, o cdigo necessrio para que os testes passem, deve ser
escrito e o teste deve passar. O ciclo se repete para o prximo teste mais simples que ainda no passa.
Um dos principais benefcio dessa tcnica que, como os testes so escritos antes da implementao do
trecho a ser testado, o programador no infuenciado pelo cdigo j feito - assim, ele tende a escrever testes
melhores, pensando no comportamento em vez da implementao.
Lembremos: os testes devem mostrar (e documentar) o comportamento do sistema, e no o que uma im-
plementao faz.
Alm disso, nota-se que TDD traz baixo acoplamento, o que timo j que classes muito acopladas so
difceis de testar. Como criaremos os testes antes, desenvolveremos classes menos acopladas, isto , menos
dependentes de outras muitas, separando melhor as responsabilidades.
O TDD tambm uma espcie de guia: como o teste escrito antes, nenhum cdigo do sistema escrito
por acharmos que vamos precisar dele. Emsistemas semtestes, comumencontrarmos centenas de linhas
que jamais sero invocadas, simplesmente porque o desenvolvedor achou que algum um dia precisaria
daquele determinado mtodo.
Captulo - Test Driven Design - TDD - Vantagens do TDD - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Imagine que voc j tenha um sistema com muitas classes e nenhum teste: provavelmente, para iniciar a
criao de testes, muitas refatoraes tero de ser feitas, mas como modifcar seu sistema garantindo o funci-
onamento dele aps as mudanas quando no existem testes que garantam que seu sistema tenha o compor-
tamento desejado? Por isso, crie testes sempre e, de preferncia, antes da implementao da funcionalidade.
TDD uma disciplina difcil de se implantar, mas depois que voc pega o jeito e o hbito adquirido, pode-
mos ver claramente as diversas vantagens dessa tcnica.
. Exvncc:os: IovN1:v:cnNoo Nvcoc:novs oo mvsmo o:n
Poderamos criar uma classe LeitorXML que pega todo o XML e converte em candles, mas ela teria muita
responsabilidade. Vamos cuidar da lgica que separa as negociaes em vrios candles por datas em outro
lugar.
) Queremos ento, em nossa classe de factory, pegar uma srie de negociaes e transformar em uma lista
de candles. Para isso vamos precisar que uma negociao saiba identifcar se do mesmo dia que a
dataAtual.
Para saber, conforme percorremos todas as negociaes, se a negociao atual ainda aconteceu na mesma
data que estamos procurando, vamos usar um mtodo na classe Negociacao que faz tal verifcao.
Seguindo os princpios do TDD, comeamos escrevendo um teste na classe NegociacaoTest:
@Test
public void mesmoMilissegundoEhDoMesmoDia() {
Calendar agora = Calendar.getInstance();
Calendar mesmoMomento = (Calendar) agora.clone();
Negociacao negociacao = new Negociacao(40.0, 100, agora);
Assert.assertTrue(negociacao.isMesmoDia(mesmoMomento));
}
Esse cdigo no vai compilar de imediato, j que no temos esse mtodo na nossa classe. No Eclipse,
aperte Ctrl + em cima do erro e escolha Create method isMesmoDia.
E qual ser uma implementao interessante? Que tal simplifcar usando o mtodo equals de Calendar?
Captulo - Test Driven Design - TDD - Exerccios: Identifcando negociaes do mesmo dia - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public boolean isMesmoDia(Calendar outraData) {
return this.data.equals(outraData);
}
Rode o teste! Passa?
) Nosso teste passou de primeira! Vamos tentar mais algum teste? Vamos testar datas iguais em horas
diferentes, crie o mtodo a seguir na classe NegociacaoTest:
@Test
public void comHorariosDiferentesEhNoMesmoDia() {
// usando GregorianCalendar(ano, mes, dia, hora, minuto)
Calendar manha = new GregorianCalendar(2011, 10, 20, 8, 30);
Calendar tarde = new GregorianCalendar(2011, 10, 20, 15, 30);
Negociacao negociacao = new Negociacao(40.0, 100, manha);
Assert.assertTrue(negociacao.isMesmoDia(tarde));
}
Rode o teste. No passa!
Infelizmente, usar o equals no resolve nosso problema de comparao.
Lembre que um Calendar possui um timestamp, isso quer dizer que alm do dia, do ms e do ano, h
tambm informaes de hora, segundos etc. A implementao que compara os dias ser:
public boolean isMesmoDia(Calendar outraData) {
return
data.get(Calendar.DAY_OF_MONTH) == outraData.get(Calendar.DAY_OF_MONTH);
}
Altere o mtodo isMesmoDia na classe Negociacao e rode os testes anteriores. Passamos agora?
) O prximo teste a implementarmos ser o que garante que para dia igual, mas ms diferente, a data no
a mesma. Quer dizer: no basta comparar o campo referente ao dia do ms, ainda necessrio que seja
o mesmo ms!
Crie o mesmoDiaMasMesesDiferentesNaoSaoDoMesmoDia na classe de testes do Negociacao, veja o teste
falhar e, ento, implemente o necessrio para que ele passe. Note que, dessa vez, o valor esperado o
false e, portanto, utilizaremos o Assert.assertFalse.
) Finalmente, o ltimo teste a implementarmos ser o que garante que para dia e meses iguais, mas anos
diferentes, a data no a mesma. Siga o mesmo procedimento para desenvolver com TDD:
Escreva o teste mesmoDiaEMesMasAnosDiferentesNaoSaoDoMesmoDia;
Rode e veja que falhou;
Implemente o necessrio para faz-lo passar.
Captulo - Test Driven Design - TDD - Exerccios: Identifcando negociaes do mesmo dia - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Feito esse processo, seu mtodo isMesmoDia na classe Negociacao deve ter fcado bemparecido comisso:
public boolean isMesmoDia(Calendar outraData) {
return
this.data.get(Calendar.DAY_OF_MONTH) == outraData.get(Calendar.DAY_OF_MONTH) &&
this.data.get(Calendar.MONTH) == outraData.get(Calendar.MONTH) &&
this.data.get(Calendar.YEAR) == outraData.get(Calendar.YEAR);
}
. Exvncc:os: SvvnnnNoo os cnNotvs
) Prximo passo: dada uma lista de negociaes de vrias datas diferentes mas ordenada por data, quebrar
em uma lista de candles, uma para cada data.
Seguindo a disciplina do TDD: comeamos pelo teste!
Adicione o mtodo paraNegociacoesDeTresDiasDistintosGeraTresCandles na classe
CandlestickFactoryTest:
@Test
public void paraNegociacoesDeTresDiasDistintosGeraTresCandles() {
Calendar hoje = Calendar.getInstance();
Negociacao negociacao1 = new Negociacao(40.5, 100, hoje);
Negociacao negociacao2 = new Negociacao(45.0, 100, hoje);
Negociacao negociacao3 = new Negociacao(39.8, 100, hoje);
Negociacao negociacao4 = new Negociacao(42.3, 100, hoje);
Calendar amanha = (Calendar) hoje.clone();
amanha.add(Calendar.DAY_OF_MONTH, 1);
Negociacao negociacao5 = new Negociacao(48.8, 100, amanha);
Negociacao negociacao6 = new Negociacao(49.3, 100, amanha);
Calendar depois = (Calendar) amanha.clone();
depois.add(Calendar.DAY_OF_MONTH, 1);
Negociacao negociacao7 = new Negociacao(51.8, 100, depois);
Negociacao negociacao8 = new Negociacao(52.3, 100, depois);
List<Negociacao> negociacoes = Arrays.asList(negociacao1, negociacao2,
negociacao3, negociacao4, negociacao5, negociacao6, negociacao7,
negociacao8);
CandlestickFactory fabrica = new CandlestickFactory();
Captulo - Test Driven Design - TDD - Exerccios: Separando os candles - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
List<Candlestick> candles = fabrica.constroiCandles(negociacoes);
Assert.assertEquals(3, candles.size());
Assert.assertEquals(40.5, candles.get(0).getAbertura(), 0.00001);
Assert.assertEquals(42.3, candles.get(0).getFechamento(), 0.00001);
Assert.assertEquals(48.8, candles.get(1).getAbertura(), 0.00001);
Assert.assertEquals(49.3, candles.get(1).getFechamento(), 0.00001);
Assert.assertEquals(51.8, candles.get(2).getAbertura(), 0.00001);
Assert.assertEquals(52.3, candles.get(2).getFechamento(), 0.00001);
}
A chamada ao mtodo constroiCandles no compila pois o mtodo no existe ainda. Ctrl + e Create
method.
Como implementamos? Precisamos:
Criar a List<Candlestick>;
Percorrer a List<Negociacao> adicionando cada negociaco no Candlestick atual;
Quando achar uma negociao de um novo dia, cria um Candlestick novo e adiciona;
Devolve a lista de candles;
O cdigo talvez fque um pouco grande. Ainda bem que temos nosso teste!
public List<Candlestick> constroiCandles(List<Negociacao> todasNegociacoes) {
List<Candlestick> candles = new ArrayList<Candlestick>();
List<Negociacao> negociacoesDoDia = new ArrayList<Negociacao>();
Calendar dataAtual = todasNegociacoes.get(0).getData();
for (Negociacao negociacao : todasNegociacoes) {
// se no for mesmo dia, fecha candle e reinicia variveis
if (!negociacao.isMesmoDia(dataAtual)) {
Candlestick candleDoDia = constroiCandleParaData(dataAtual,
negociacoesDoDia);
candles.add(candleDoDia);
negociacoesDoDia = new ArrayList<Negociacao>();
dataAtual = negociacao.getData();
}
negociacoesDoDia.add(negociacao);
}
// adiciona ltimo candle
Candlestick candleDoDia = constroiCandleParaData(dataAtual,
negociacoesDoDia);
candles.add(candleDoDia);
Captulo - Test Driven Design - TDD - Exerccios: Separando os candles - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
return candles;
}
Rode o teste!
. Exvncc:os ovc:oNn:s
) E se passarmos para o mtodo constroiCandles da fbrica uma lista de negociaes que no est na
ordem crescente? O resultado vai ser candles em ordem diferentes, e provavelmente com valores erra-
dos. Apesar da especifcao dizer que os negociaes vem ordenados pela data, boa prtica programar
defensivamente em relao aos parmetros recebidos.
Aqui temos diversas opes. Uma delas , caso alguma Negociacao venha em ordem diferente da cres-
cente, lanamos uma exception, a IllegalStateException.
Crie o naoPermiteConstruirCandlesComNegociacoesForaDeOrdem e confgure o teste para verifcar que
uma IllegalStateException foi lanada. Basta usar como base o mesmo teste que tnhamos antes, mas
adicionar as negociaes com datas no crescentes.
Rode o teste e o veja falhar.
Pra isso, modifcamos o cdigo adicionando as linhas em negrito ao mtodo constroiCandles:
for (Negociacao negociacao : todasNegociacoes) {
if (negociacao.getData().before(dataAtual)) {
Captulo - Test Driven Design - TDD - Exerccios opcionais - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
throw new IllegalStateException("negociaes em ordem errada");
}
// se no for mesmo dia, fecha candle e reinicia variveis
...
) Vamos criar um gerador automtico de arquivos para testes da bolsa. Ele vai gerar dias de candle e
cada candle pode ser composto de a negociaes. Esses preos podem variar.
public class GeradorAleatorioDeXML {
public static void main(String[] args) throws IOException {
Calendar data = Calendar.getInstance();
Random random = new Random(123);
List<Negociacao> negociacoes = new ArrayList<Negociacao>();
double valor = 40;
int quantidade = 1000;
for (int dias = 0; dias < 30; dias++) {
int quantidadeNegociacoesDoDia = random.nextInt(20);
for (int negociacao = 0; negociacao < quantidadeNegociacoesDoDia;
negociacao++){
// no mximo sobe ou cai R$1,00 e nao baixa alm de R$5,00
valor += (random.nextInt(200) - 100) / 100.0;
if (valor < 5.0) {
valor = 5.0;
}
// quantidade: entre 500 e 1500
quantidade += 1000 - random.nextInt(500);
Negociacao n = new Negociacao(valor, quantidade, data);
negociacoes.add(n);
}
data = (Calendar) data.clone();
data.add(Calendar.DAY_OF_YEAR, 1);
}
XStream stream = new XStream(new DomDriver());
stream.alias("negociacao", Negociacao.class);
stream.setMode(XStream.NO_REFERENCES);
PrintStream out = new PrintStream(new File("negociacao.xml"));
out.println(stream.toXML(negociacoes));
}
Captulo - Test Driven Design - TDD - Exerccios opcionais - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
}
Se voc olhar o resultado do XML, ver que, por usarmos o mesmo objeto Calendar em vrios lugares, o
XStream coloca referncias no prprio XML evitando a cpia do mesmo dado. Mas talvez isso no seja
to interessante na prtica, pois mais comumna hora de integrar sistemas, passar umXML simples com
todos os dados.
Aopo XStream.NO_REFERENCES serve para indicar ao XStreamque no queremos que ele crie referncias
a tags que j foram serializadas iguaizinhas. Voc pode passar esse argumento para o mtodo setMode do
XStream. Faa o teste sem e com essa opo para entender a diferena.
Dvsnv:o - OnovNv n t:s1n oN ovmnNo
) Faa com que uma lista de Negociacao seja ordenvel pela data das negociaes.
Ento poderemos, logo no incio do mtodo, ordenar todas as negociaes com Collections.sort e no
precisamos mais verifcar se os negociaes esto vindo em ordem crescente!
Perceba que mudamos uma regra de negcio, ento teremos de refetir isso no nosso teste unitrio que
estava comexpected=IllegalStateException.class no caso de vir emordemerrada. Oresultado agora
com essa modifcao tem de dar o mesmo que com as datas crescentes.
Captulo - Test Driven Design - TDD - Exerccios opcionais - Pgina
C
Acessando um Web Service
Nenhum homem uma ilha isolada; cada homem uma partcula do continente, uma parte da terra
John Donne
. IN1vcnnXo vN1nv s:s1vmns
No captulo anterior resolvemos o problema de como interpretar os dados oriundos de um arquivo XML,
apesar disso, no mundo real, dados so gerados dinamicamente a todo instante das mais diversas fontes.
No mercado de bolsa de valores comum o uso de aplicaes que permitem aos seus usurios analisar o
mercado, e at mesmo comprar e vender aes em tempo real. Mas como possvel analisar o mercado se
no temos acesso aos dados da Bovespa?
A integrao e a comunicao com o sistema da Bovespa se faz necessria para que possamos receber dados
sempre atualizados. Geralmente essa comunicao se d pelo prprio protocolo da web, o HTTP, com o
formato difundido e j estudado XML. Essa integrao e comunicao entre aplicaes possui o nome de
Web Service.
. CoNscm:Noo onoos ov cmWvn Svnv:cv
Para consumir dados vindos de outra aplicao, a primeira coisa importante saber onde essa aplicao se
encontra. Emtermos tcnicos, qual a URLdesse webservice. Emnosso projeto a URLespecfca da aplicao
ser http://argentumws.caelum.com.br/negociacoes.
Podemos testar essa URL facilmente dentro do navegador, basta copiar e colar na barra de endereo. Ao
executar, o navegador recebe como resposta o XML de negcios que j conhecemos, por exemplo:
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. Cn:nNoo o ct:vN1v Jnvn
J sabemos de onde consumir, resta saber como consumir esses dados pela web. No mundo web trabalhamos
com o conceito de requisio e resposta. Se queremos os dados precisamos realizar uma requisio para
aquela URL, mas como?
Na prpria API do Java temos classes que tornam possvel essa tarefa. Como o caso da classe URL que nos
permite referenciar um recurso na Web, seja ele um arquivo ou at mesmo um diretrio.
URL url = new URL("http://argentumws.caelum.com.br/negociacoes");
Conhecendo a URL falta agora que uma requisio HTTP seja feita para ela. Faremos isso atravs do m-
todo openConnection que nos devolve um URLConnection. Entretanto, como uma requisio HTTP se faz
necessria, usaremos uma subclasse de URLConnection que a HttpURLConnection.
URL url = new URL("http://argentumws.caelum.com.br/negociacoes");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
Dessa conexo pediremos um InputStream que ser usado pelo nosso LeitorXML.
URL url = new URL("http://argentumws.caelum.com.br/negociacoes");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream content = connection.getInputStream();
List<Negociacao> negociacoes = new LeitorXML().carrega(content);
Captulo - Acessando um Web Service - Criando o cliente Java - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Dessa forma j temos em mos a lista de negociaes que era o nosso objetivo principal. Resta agora en-
capsularmos este cdigo em alguma classe, para que no seja necessrio repeti-lo toda vez que precisamos
receber os dados da negociao. Vamos implementar a classe ClienteWebService e nela deixar explcito qual
o caminho da aplicao que a conexo ser feita.
public class ClienteWebService {
private static final String URL_WEBSERVICE =
"http://argentumws.caelum.com.br/negociacoes";
}
Por ltimo, e no menos importante, declararemos um mtodo que retorna uma lista de negociaes, justa-
mente o que usaremos no projeto.
public class ClienteWebService {
private static final String URL_WEBSERVICE =
"http://argentumws.caelum.com.br/negociacoes";
public List<Negociacao> getNegociacoes() {
URL url = new URL(URL_WEBSERVICE);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream content = connection.getInputStream();
return new LeitorXML().carrega(content);
}
}
Nossa classe ainda no compila, pois tanto o construtor de URL quanto os mtodos de HttpURLConnection
lanam excees que so do tipo IOException. Vamos tratar o erro e fechar a conexo que foi aberta pelo
mtodo getInputStream, em um bloco finally.
...
public List<Negociacao> getNegociacoes() {
HttpURLConnection connection = null;
try {
URL url = new URL(URL_WEBSERVICE);
connection = (HttpURLConnection)url.openConnection();
InputStream content = connection.getInputStream();
return new LeitorXML().carrega(content);
} catch (IOException e) {
throw new RuntimeException(e);
Captulo - Acessando um Web Service - Criando o cliente Java - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
} finally {
connection.disconnect();
}
}
...
Dessa forma conseguimos nos comunicar com um Web Service e consumir os dados disponibilizados por
ele atravs de um XML. Esta uma prtica bastante utilizada pelo mercado e estudada com mais aprofunda-
mento no curso FJ- | Curso Java EE avanado e Web Services.
H11vCt:vN1
Existe uma biblioteca capaz de lidar com dados de uma forma simples e mais especfca do que
utilizar diretamente a API do Java. Para trabalhar com o protocolo HTTP h a biblioteca Http-
Client que faz parte do Apache Sofware Foundation:
http://hc.apache.org/httpcomponents-client-ga/index.html
Com ela ganhamos uma API que fornece toda funcionalidade do protocolo HTTP e podera-
mos us-la para chamar o Web Service. Segue um pequeno exemplo usando o HttpClient para
executar uma requisio do tipo GET:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(URL_DO_WEBSERVICE);
HttpResponse response = client.execute(request);
InputStream content = response.getEntity().getContent();
Captulo - Acessando um Web Service - Criando o cliente Java - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Wvn Svnv:cv - SOAP, JSONv oc1nos
Por defnio um Web Service alguma lgica de negcio acessvel usando padres da Inter-
net. O mais comum usar HTTP como protocolo de comunicao e XML para o formato que
apresenta os dados - justamente o que praticaremos aqui. Mas nada impede o uso de outros
formatos.
Uma tentativa de especifcar mais ainda o XML dos Web Services so os padres SOAP e WSDL.
Junto com o protocolo HTTP, eles defnem a base para comunicao de vrios servios no
mundo de aplicaes Enterprise. O SOAP e WSDL tentam esconder toda comunicao e ge-
rao do XML, facilitando assimo uso para quemno conhece os padres Web. No treinamento
FJ- veremos os detalhes sobre publicao e a criao de clientes baseados no Web Services
SOAP/WSDL.
Outro formato bastante popular nos Web Services o JSON. JSON parecido com XML, mas
umpouco menos verboso e fcil de usar comJavaScript. JSONganhou popularidade atravs das
requisies AJAX e conquistou o seu espao nos Web Services tambm. Alm de ser bastante
difundido no desenvolvimento mobile por ser mais leve no trfego via rede.
. Exvncc:os: Nosso ct:vN1v Wvn Svnv:cv
) Vamos agora implementar o cliente do Web Service, primeiramente criaremos a classe
ClienteWebService, dentro do pacote br.com.caelum.argentum.ws na pasta src/main/java. Va-
mos criar tambm uma constante com a URL para onde ser feita a requisio.
public class ClienteWebService {
private static final String URL_WEBSERVICE =
"http://argentumws.caelum.com.br/negociacoes";
}
) Agora vamos criar o mtodo getNegociacoes(), que retorna a nossa lista de negociaes:
public class ClienteWebService {
private static final String URL_WEBSERVICE =
"http://argentumws.caelum.com.br/negociacoes";
public List<Negociacao> getNegociacoes() {
HttpURLConnection connection = null;
URL url = new URL(URL_WEBSERVICE);
Captulo - Acessando um Web Service - Exerccios: Nosso cliente Web Service - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
connection = (HttpURLConnection)url.openConnection();
InputStream content = connection.getInputStream();
return new LeitorXML().carrega(content);
}
}
) No podemos esquecer de colocar o try/catch para tratar possveis erros e logo em seguida fechar a
conexo:
public class ClienteWebService {
private static final String URL_WEBSERVICE =
"http://argentumws.caelum.com.br/negociacoes";
public List<Negociacao> getNegociacoes() {
HttpURLConnection connection = null;
try {
URL url = new URL(URL_WEBSERVICE);
connection = (HttpURLConnection)url.openConnection();
InputStream content = connection.getInputStream();
return new LeitorXML().carrega(content);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
connection.disconnect();
}
}
}
. D:sccssXovmnctn: Como1vs1nn oct:vN1v oowvn svnv:cv:
Captulo - Acessando um Web Service - Discusso em aula: Como testar o cliente do web service? - Pgina
C
Introduo ao JSF e Primefaces
Eu no temo computadores, eu temo a falta deles
Isaac Asimov
Durante muitos anos, os usurios se habituaram com aplicaes Desktop. Este tipo de aplicao instalada
no computador local e acessa diretamente um banco de dados ou gerenciador de arquivos. As tecnologias
tpicas para criar uma aplicao Desktop so Delphi, VB (Visual Basic) ou, no mundo Java, Swing.
Para o desenvolvedor, a aplicao Desktop construda com uma srie de componentes que a plataforma de
desenvolvimento oferece para cada sistema operacional. Esses componentes ricos e muitas vezes sofsticados
esto associados a eventos ou procedimentos que executam lgicas de negcio.
Problemas de validao de dados so indicados na prpria tela sem que qualquer informao do formulrio
seja perdida. De uma forma natural, esses componentes lembram-se dos dados do usurio, inclusive entre
telas e aes diferentes.
Nesse tipo de desenvolvimento so utilizados diversos componentes ricos, como por exemplo, calendrios,
menus diversos ou componentes drag and drop (arrastar e soltar). Eles fcam associados a eventos, ou aes,
e guardam automaticamente seu estado, j que mantm os valores digitados pelo usurio.
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Esses componentes no esto, contudo, associados exclusivamente ao desenvolvimento de aplicaes Desk-
top. Podemos criar a mesma sensao confortvel para o cliente em uma aplicao web, tambm usando
componentes ricos e reaproveitveis.
. DvsvNvotv:mvN1o ovs1ov oc wvn:
Existem algumas desvantagens no desenvolvimento desktop. Como cada usurio tem uma cpia integral da
aplicao, qualquer alterao precisaria ser propagada para todas as outras mquinas. Estamos usando um
cliente gordo, isto , com muita responsabilidade no lado do cliente.
Note que, aqui, estamos chamando de cliente a aplicao que est rodando na mquina do usurio.
Para piorar, as regras de negcio rodam no computador do usurio. Isso faz com que seja muito mais difcil
depurar a aplicao, j que no costumamos ter acesso to fcil maquina onde a aplicao est instalada.
Em geral, enfrentamos problemas de manuteno e gerenciabilidade.
Captulo - Introduo ao JSF e Primefaces - Desenvolvimento desktop ou web? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
OovsvNvotv:mvN1o Wvn v o vno1ocoto HTTP
Para resolver problemas como esse, surgiram as aplicaes baseadas na web. Nessa abordagem h um ser-
vidor central onde a aplicao executada e processada e todos os usurios podem acess-la atravs de um
cliente simples e do protocolo HTTP.
Um navegador web, como Firefox ou Chrome, que far o papel da aplicao cliente, interpretando HTML,
CSS e JavaScript -- que so as tecnologias que ele entende.
Enquanto o usurio usa o sistema, o navegador envia requisies (requests) para o lado do servidor (server
side), que responde para o computador do cliente (client side). Em nenhum momento a aplicao est salva
no cliente: todas as regras da aplicao esto no lado do servidor. Por isso, essa abordagem tambm foi
chamada de cliente magro (thin client).
Isso facilita bastante a manuteno e a gerenciabilidade, pois temos um lugar central e acessvel onde a apli-
cao executada. Contudo, note que ser preciso conhecer HTML, CSS e JavaScript, para fazer a interface
com o usurio, e o protocolo HTTP para entender a comunicao pela web. E, mais importante ainda, no
h mais eventos, mas sim um modelo bem diferente orientado a requisies e respostas. Toda essa base
precisar ser conhecida pelo desenvolvedor.
Comparando as duas abordagens, podemos ver vantagens e desvantagens em ambas. No lado da aplicao
puramente Desktop, temos um estilo de desenvolvimento orientado a eventos, usando componentes ricos,
porm com problemas de manuteno e gerenciamento. Do outro lado, as aplicaes web so mais fceis
de gerenciar e manter, mas precisamos lidar com HTML, conhecer o protocolo HTTP e seguir o modelo
requisio/resposta.
Captulo - Introduo ao JSF e Primefaces - Desenvolvimento desktop ou web? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
MvsctnNoo ovsvNvotv:mvN1o Dvs1ov v Wvn
Emvez de desenvolver puramente para desktop, uma tendncia mesclar os dois estilos, aproveitando as van-
tagens de cada um. Seria um desenvolvimento Desktop para a web, tanto central quanto com componentes
ricos, aproveitando o melhor dos dois mundos e abstraindo o protocolo de comunicao. Essa justamente
a ideia dos frameworks web baseados em componentes.
No mundo Java h algumas opes como JavaServer Faces (JSF), Apache Wicket, Vaadin, Tapestry ou GWT
da Google. Todos eles so frameworks web baseados em componentes.
. Cnnnc1vns1:cns oo JSF
JSF uma tecnologia que nos permite criar aplicaes Java para Web utilizando componentes visuais pr-
prontos, de forma que o desenvolvedor no se preocupe com Javascript e HTML. Basta adicionarmos os
componentes (calendrios, tabelas, formulrios) e eles sero renderizados e exibidos em formato html.
Gcnnon o vs1noo oos comvoNvN1vs
Alm disso o estado dos componentes sempre guardado automaticamente (como veremos mais frente),
criando a caracterstica Stateful. Isso nos permite, por exemplo, criar formulrios de vrias pginas e navegar
nos vrios passos dele com o estado das telas sendo mantidos.
Svvnnn ns cnmnons
Outra caracterstica marcante na arquitetura do JSF a separao que fazemos entre as camadas de apresen-
tao e de aplicao. Pensando no modelo MVC, o JSF possui uma camada de visualizao bem separada do
conjunto de classes de modelo.
Esvvc:v:cnXo: vKn:ns :mvtvmvN1novs
OJSF ainda tema vantagemde ser uma especifcao do Java EE, isto , todo servidor de aplicaes Java tem
que vir com uma implementao dela e h diversas outras disponveis.
A implementao mais famosa do JSF e tambm a implementao de referncia, a Oracle Mojarra dis-
ponvel em http://javaserverfaces.java.net/. Outra implementao famosa a MyFaces da Apache Sofware
Foundation em http://myfaces.apache.org/.
Captulo - Introduo ao JSF e Primefaces - Caractersticas do JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Pn:mv:nos vnssos comJSF
Nosso projeto utilizar a implementao Mojarra do JSF. Ela j defne o modelo de desenvolvimento e oferece
alguns componentes bem bsicos. Nada alm de inputs, botes e ComboBoxes simples.
No h componentes sofsticados dentro da especifcao e isso proposital: uma especifcao tem que ser
estvel e as possibilidades das interfaces com o usurio crescemmuito rapidamente. A especifcao trata do
que fundamental, mas outros projetos suprem o que falta.
Para atender a demanda dos desenvolvedores por componentes mais sofsticados, h vrias extenses do
JSF que seguem o mesmo ciclo e modelo da especifcao. Exemplos dessas bibliotecas so PrimeFaces,
RichFaces e IceFaces. Todas elas defnem componentes JSF que vo muito alm da especifcao.
Cada biblioteca oferece ShowCases na web para mostrar seus componentes e suas funcionalidades. Voc
pode ver o showcase do PrimeFaces no endereo http://www.primefaces.org.
Captulo - Introduo ao JSF e Primefaces - Caractersticas do JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Na sua demo online, podemos ver uma lista de componentes disponveis, como inputs, painis, botes diver-
sos, menus, grfcos e componentes drag & drop, que vo muito alm das especifcaes, ainda mantendo a
facilidade de uso:
Captulo - Introduo ao JSF e Primefaces - Caractersticas do JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Para a defnio da interface do projeto Argentum usaremos Oracle Mojarra com PrimeFaces, uma combi-
nao muito comum no mercado.
PnvvnnnXo oo nmn:vN1v
Nossa aplicaoArgentumprecisa de uma interface web. Para issovamos preparar uma aplicaowebcomum
que roda dentro de um Servlet Container. Qualquer implementao de servlet container seria vlida e, no
curso, usaremos o Apache Tomcat . Uma outra boa opo seria o Jetty.
CoNv:ccnnXo oo coN1notnoon oo JSF
OJSFsegue o padro arquitetural MVC(Model-View-Controller) e faz o papel do Controller da aplicao. Para
comear a us-lo, preciso confgurar a servlet do JSF no web.xml da aplicao. Esse Servlet responsvel
por receber as requisies e deleg-las ao JSF. Para confgur-lo basta adicionar as seguintes confguraes
no web.xml:
<servlet>
<servlet-name>FacesServlet</servlet-name>
Captulo - Introduo ao JSF e Primefaces - Caractersticas do JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
Ao usar o Eclipse com suporte a JSF essa confgurao no web.xml j feita automaticamente durante a
criao de um projeto.
Fncvs-coNv:c: o nnqc:vo ov coNv:ccnnXo oo mcNoo JSF
Alm disso, h um segundo XML que o arquivo de confgurao relacionado com o mundo JSF, o
faces-config.xml.
Como o JSF na verso dois encoraja o uso de anotaes emvez de confguraes no XML, este arquivo torna-
se pouco usado. Ele era muito mais importante na primeira verso do JSF. Neste treinamento, deixaremos
ele vazio:
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
</faces-config>
Agora j temos as informaes necessrias para criar nosso primeiro projeto utilizando JSF.
. Exvncc:os: INs1ntnNoo o Tomcn1 v cn:nNoo o vno)v1o
) Primeiramente, precisamos instalar o Tomcat. Usaremos a verso .x:
a) V no Desktop e entre na pasta Caelum e em seguida na pasta .
b) Copie o arquivo zip do TomCat e cole ele na sua pasta Home.
c) Clique com o boto direito e escolha Extract here.
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
d) O Tomcat j est pronto para o uso!
) O prximo passo criar o nosso projeto no Eclipse.
a) Crie um novo projeto web usando o ctrl + Dynamic Web Project.
b) Em Project name coloque fj22-argentum-web.
c) Na seo Confguration clique em Modify para acrescentarmos suporte ao JSF.
d) Na tela que abre, marque o checkbox com JavaServer Faces . e clique d ok:
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
e) De volta tela de criao do projeto, clique em Next. Nessa tela, faremos como no incio do curso: re-
moveremos a source folder padro (src) e adicione as source folders src/main/java e src/test/java.
f) D Next mais duas vezes at chegar tela de JSF Capabilities. Nessa tela, escolha a opo Disable
Library Confguration para indicarmos para o Eclipse que ns mesmos copiaremos os JARs do JSF.
Ainda nessa tela, na parte URL Mapping Patterns, remova o mapeamento /faces/* e adicione umnovo
mapeamento como *.xhtml
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
g) Clique em Finish e o projeto est criado.
) O prximo passo confgurar o Tomcat no Eclipse, para que possamos control-lo mais facilmente.
a) Dentro do Eclipse, abra a view Servers. Para isso, pressione ctrl + , digite Servers e escolha a view. Ela
ser aberta na parte inferior do seu Eclipse.
b) Dentro da aba Servers clique com o boto direito do mouse e escolha New -> Server. Se no quiser
usar o mouse, voc pode fazer ctrl+ New server.
c) Dentro da Janela New Server escolha Apache Tomcat v. Server e clique em Next.
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
d) O prximo passo dizermos ao Eclipse em qual diretrio instalamos o Tomcat. Clique no boto
Browse... e escolha a pasta na qual voc descompactou o Tomcat.
e) Clique em Next e, na prxima tela, selecione o projeto f-argentum-web no box Available (da es-
querda), pressione o boto Add > (mover para o box Confgured da direita) e depois Finish.
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
f) Clique em Finish.
) Por fm, precisamos importar do projeto anterior as classes como Negociacao ou Candlestick. J o te-
mos pronto na pasta /caelum/cursos/22/, com o nome de modelo-argentum.zip. Precisamos apenas
import-lo:
Para import-lo, use ctrl + Archive File e escolha a opo Import (Archive fle).
Em Browse..., selecione o nosso arquivo modelo-argentum.zip e fnalize-o.
Note que, com esse import, trouxemos tambm os jars da implementao Mojarra do JSF e do Pri-
mefaces, que usaremos daqui pra frente.
Captulo - Introduo ao JSF e Primefaces - Exerccios: Instalando o Tomcat e criando o projeto - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Pnnn cnsn...
Se voc est fazendo esse exerccio em casa, certifque-se que seu projeto anterior est funcio-
nando corretamente e simplesmente copie os pacotes dele para o novo.
No esquea de copiar tambm o jar do XStream para a pasta WebContent/WEB-INF/lib/.
Alm disso, no zip da aula ainda h os jars do JSF e do PrimeFaces, que usaremos a seguir. Nesta
verso da apostila estamos usando as verses .x.x e ..x, respectivamente. Links para o down-
load:
JSF: https://javaserverfaces.java.net/download.html
Primefaces: http://primefaces.org/downloads.html
) Nossas classes de teste (src/test/java) ainda apresentamproblemas relacionados ao JUnit. Falta adicion-lo
ao Build Path.
Abra a classe CandlestickFactoryTest e d ctrl + na anotao @Test. Escolha a opo Add JUnit library
to the build path.
) Finalmente, para evitar confuses mais para a frente, feche o projeto que fzemos nos outros dias de curso.
Clique com o boto direito no f-argentum-base e escolha a opo Close project
. A vn:mv:nn vKc:Nn comJSF
Como confguramos, na criao do projeto, que o JSF ser responsvel por responder s requisies com
extenso .xhtml. Dessa forma, tabalharemos com arquivos xhtml no restante do curso.
Captulo - Introduo ao JSF e Primefaces - A primeira pgina com JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Vale relembrar uma diferena fundamental entre as duas formas de desenvolvimento para a web. A aborda-
gem action based, como no SpringMVC e no VRaptor, focam seu funcionamento nas classes que contm as
lgicas. A view meramente uma camada de apresentao do que foi processado no modelo.
Enquanto isso, o pensamento component based adotado pelo JSF leva a view como a pea mais importante
-- a partir das necessidades apontadas pelos componentes da view que o modelo chamado e populado
com dados.
As tags que representam os componentes do JSF esto em duas taglibs principais (bibliotecas de tags): a core
e a html.
A taglib html contm os componentes necessrios para montarmos nossa tela gerando o HTML adequado.
J a core possui diversos componentes no visuais, como tratadores de eventos ou validadores. Por ora,
usaremos apenas os componentes da h:html
Imvon1nNoo ns 1ncs vmNossn vKc:Nn
Diferente da forma importao de taglibs em JSPs que vimos no curso de Java para a web (FJ-), para im-
portar as tags no JSF basta declararmos seus namespaces no arquivo .xhtml. Dessa forma, teremos:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<!-- aqui usaremos as tags do JSF -->
</html>
Dvv:N:Noo n :N1vnvncv on nvt:cnXo
Como qualquer outro aprendizado de tecnologia, vamos comear a explorar o JSF criando nossa primeira
tela com uma mensagem de boas vindas para o usurio.
Como todo arquivo HTML, todo o cabealho deve estar dentro da tag head e o que ser renderizado no
navegador deve fcar dentro da tag body. Uma pgina padro para ns seria algo como:
<html ...>
<head>
<!-- cabealho aqui -->
</head>
<body>
<!-- informaes a serem mostradas -->
</body>
</html>
Captulo - Introduo ao JSF e Primefaces - A primeira pgina com JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Quando estamos lidando com o JSF, no entanto, precisamos nos lembrar de utilizar preferencialmente as
tags do prprio framework, j que, medida que utilizarmos componentes mais avanados, o JSF preci-
sar gerenciar os prprios body e head para, por exemplo, adicionar CSS e javascript que um componente
requisitar.
Assim, usando JSF preferiremos utilizar as tags estruturais do HTML que vm da taglib http://java.sun.com/
jsf/html, nosso html vai fcar mais parecido com esse:
<html ...>
<h:head>
<!-- cabealho aqui -->
</h:head>
<h:body>
<!-- informaes a serem mostradas -->
</h:body>
</html>
Mos1nnNoo :Nvonmnovs comn:oc1vc1Tvx1
Como queremos mostrar uma saudao para o visitante da nossa pgina, podemos usar a tag h:outputText.
atravs do seu atributo value que defnimos o texto que ser apresentado na pgina.
Juntando tudo, nosso primeiro exemplo uma tela simples com um texto:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Argentum Web</title>
</h:head>
<h:body>
<h:outputText value ="Ol JSF!" />
</h:body>
</html>
. IN1vnnc:Noo como moovto: MnNncvo BvnNs
Oh:outputText uma tag comumpropsito aparentemente muito bobo e, no exemplo acima, exatamente
equivalente a simplesmente escrevermos Ol JSF! diretamente. E, de fato, para textos fxos, no h problema
em escrev-lo diretamente!
Contudo, se um pedao de texto tiver que interagir com o modelo, uma lgica ou mesmo com outros com-
ponentes visuais, ser necessrio que ele tambm esteja guardado em um componente.
Captulo - Introduo ao JSF e Primefaces - Interagindo com o modelo: Managed Beans - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Exemplos dessas interaes, no caso do h:outputText: mostrar informaes vindas de um banco de dados,
informaes do sistema, horrio de acesso, etc.
Para mostrar tais informaes, precisaremos executar um cdigo Java e certamente no faremos isso na
camada de visualizao: esse cdigo fcar separado da view, em uma classe de modelo. Essas classes de
modelo que interagem com os componentes do JSF so os Managed Beans.
Estes, so apenas classezinhas simples que com as quais o JSF consegue interagir atravs do acesso a seus
mtodos. Nada mais so do que POJOs anotados com @ManagedBean.
POJO (Ptn:N Oto Jnvn On)vc1)
POJO um termo criado por Martin Fowler, Rebecca Parsons e Josh Mackenzie que serve para
defnir um objeto simples. Segundo eles, o termo foi criado pois ningum usaria objetos simples
nos seus projetos pois no existia um nome extravagante para ele.
Se quisermos, por exemplo, mostrar quando foi o acesso do usurio a essa pgina, podemos criar a seguinte
classe:
@ManagedBean
public class OlaMundoBean {
public String getHorario() {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
return "Atualizado em " + sdf.format(new Date());
}
}
E, bem semelhantemente forma padro nas JSPs vistas no treinamento de Java para a Web, acessaremos o
getter atravs da Expression Language. Existe apenas uma pequena diferena: para chamar os mtodos no
JSF, em vez do cifro ($), usaremos a cerquilha (#).
<h:outputText value="#{olaMundoBean.horario}" />
Ao fazer colocar o cdigo acima, estamos dizendo que h uma classe gerenciada pelo JSF chamada OlaMun-
doBean que tem um mtodo getHorario -- e que o retorno desse mtodo ser mostrado na pgina. uma
forma extremamente simples e elegante de ligar a view a mtodos do model.
. RvcvnvNoo :Nvonmnovs oo cscKn:o
Agora que j sabemos conectar a pgina camada de modelo, fca fcil obter dados do usurio! Por nossa
vivncia com aplicaes web, at mesmo como usurios, sabemos que a forma mais comum de trazer tais
dados para dentro da aplicao atravs de formulrios.
Captulo - Introduo ao JSF e Primefaces - Recebendo informaes do usurio - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
A boa notcia que no JSF no ser muito diferente! Se para mostrar dados na pgina usamos a tag
h:outputText, para trazer dados do usurio para dentro da aplicao, usaremos a tag h:inputText. Ela
far a ligao entre o atributo do seu bean e o valor digitado no campo.
Note que a ideia a mesma de antes: como o JSF precisar interagir com os dados desse componente, no
podemos usar a tag HTML que faria o mesmo trabalho. Em vez disso, usaremos a taglib de HTML provida
pelo prprio JSF, indicando como a informao digitada ser guardada no bean.
<h:outputLabel value="Digite seu nome:"/>
<h:inputText value="#{olaMundoBean.nome}"/>
Apenas com esse cdigo, j podemos ver o texto Digite seu nome e o campo de texto onde o usurio digitar.
Sabemos, no entanto, que no faz sentido ter apenas um campo de texto! preciso ter tambm um boto
para o usurio confrmar que acabou de digitar o nome e um formulrio para agrupar todas essas tags.
Bo1Xo v o vonmctKn:o vmJSF
Esse um pequeno ponto de divergncia entre o HTML puro e o JSF. Em um simples formulrio HTML,
confguramos a action dele na prpria tag form e o papel do boto apenas o de mandar executar a ao j
confgurada.
Para formulrios extremamente simples, isso o bastante. Mas quando queremos colocar dois botes com
aes diferentes dentro de um mesmo formulrio, temos que recorrer a um JavaScript que far a chamada
correta.
Como dito antes, no entanto, o JSF tem a proposta de abstrair todo o protocolo HTTP, o JavaScript e o CSS.
Para ter uma estrutura em que o formulrio marcado apenas como um agregador de campos e cada um
dos botes internos pode ter funes diferentes, a estratgia do JSF foi a de deixar seu form como uma tag
simples e adicionar a confgurao da ao ao prprio boto.
<h:form>
<h:outputLabel for="nome" value="Digite seu nome:"/>
<h:inputText id="nome" value="#{olaMundoBean.nome}"/>
<h:commandButton value="Ok" action="#{olaMundoBean.digaOi}"/>
</h:form>
Quando o usurio clica no boto Ok, o JSF chama o setter do atributo nome do OlaMundoBean e, logo em
seguida, chama o mtodo digaOi. Repare que esta ordem importante: o mtodo provavelmente depender
dos dados inseridos pelo usurio.
Note, tambm, que teremos um novo mtodo no managed bean chamado digaOi. Os botes sempre esto
atrelados a mtodos porque, na maior parte dos casos, realmente queremos executar alguma ao alm da
chamada do setter. Essa ao pode ser a de disparar um processo interno, salvar no banco ou qualquer outra
necessidade.
Captulo - Introduo ao JSF e Primefaces - Recebendo informaes do usurio - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Oqcv vnzvn vNqcnN1o NXo n:Non nocvvn :NvonmnXo:
Sabendo que, antes de chamar o mtodo correspondente ao do boto, o JSF preenche os
atributos atravs dos setters, sabemos que teremos a informao a ser mostrada para o usurio.
No entanto, muitas vezes no gostaramos de mostrar um campo enquanto ele no estiver pre-
enchido e, felizmente, o JSF tem uma forma bastante simples de s mostrar um h:outputText
na tela apenas se a informao estiver preenchida! Basta usar o atributo rendered:
<h:outputText value="Oi #{olaMundoBean.nome}"
rendered="#{not empty olaMundoBean.nome}"/>
. Exvncc:os: Os vn:mv:nos comvoNvN1vs JSF
) Use ctrl + N HTML para criar o arquivo olaMundo.xhtml na pasta WebContent da sua aplicao. Escolha
Next e, na prxima tela, escolha o template xhtml . transitional, usualmente a ltima opo da lista:
Selecione a mesma opo da imagem acima e pressione Finish.
Implemente nosso primeiro cdigo JSF com apenas uma sada de texto:
Captulo - Introduo ao JSF e Primefaces - Exerccios: Os primeiros componentes JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Argentum</title>
</h:head>
<h:body>
<h:outputText value="Ola Mundo" />
</h:body>
</html>
) Inicie o Tomcat e acesse a URL: http://localhost:/f-argentum-web/olaMundo.xhtml
) Verifque o cdigo fonte gerado pela pgina. Repare que ele no nada mais que simples HTML. Para
isso, na maior parte dos navegadores, use ctrl + U.
Repare no uso das tags <h:head>, <h:body> e <h:outputText>: elas no aparecem no html gerado! Sua
funo apenas indicar para o JSF como gerar o cdigo HTML necessrio para o exemplo funcionar.
) Alm de usar mensagens fxas, poderamos fazer com que a mensagem seja devolvida de uma classe
responsvel por prover objetos para uma view: umdos chamados ManagedBeans. Vamos comear criando
essa classe contendo apenas a mensagem inicial.
Crie uma classe chamada OlaMundoBean, com apenas o atributo mensagem j inicializada, seu getter e no
esquea de anotar a classe com @ManagedBean
@ManagedBean
public class OlaMundoBean {
private String mensagem = "Quem voc?";
public String getMensagem() {
return mensagem;
}
}
) Alteremos o arquivo xhtml, ento, para que ele use a mensagemQuem voc? que escrevemos hard-coded
na classe OlaMundoBean. Usaremos a Expression Language especfca do JSF para isso, que capaz de pegar
informaes de qualquer classe confgurada como um ManagedBean.
Basta alterar o value da tag h:outputText:
...
<h:body>
<h:outputText value="#{olaMundoBean.mensagem}" />
</h:body>
Captulo - Introduo ao JSF e Primefaces - Exerccios: Os primeiros componentes JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Agora, se quisermos pegar a resposta do usurio e cumpriment-lo propriamente, podemos adicionar
nossa pgina um campo de texto para que o usurio digite seu nome. Ento, trocaremos a mensagem
cumprimentando ele. Comecemos pelas alteraes no olaMundo.xhtml, adicionando um h:inputText e
um boto para o usurio enviar seu nome, como abaixo.
Ateno! No esquea da tag h:form em volta do formulrio. Lembre-se que, sem ela, os botes no
funcionam.
...
<h:body>
<h:form>
<h:outputText value="#{olaMundoBean.mensagem}" /><br />
<h:inputText value="#{olaMundoBean.nome}" />
<h:commandButton action="#{olaMundoBean.nomeFoiDigitado}"
value="Ok"/>
</h:form>
</h:body>
) Essa alterao, no entanto, no sufciente. Se voc rodar o servidor agora, notar que a pgina, que
antes funcionava, agora lana uma ServletException informando que Property nome not found on type
br.com.caelum.argentum.bean.OlaMundoBean.
Isto , falta adicionarmos o atributo nome e seu getter pgina, como fzemos coma mensagem, no outro
exerccio. Adicione classe OlaMundoBean o atributo e seu getter.
@ManagedBean
public class OlaMundoBean {
...
private String nome;
public String getNome() {
return nome;
}
...
}
) Agora sim podemos ver a mensagem, o campo de texto e o boto. Contudo, ao apertar o boto, levamos
uma javax.el.PropertyNotFoundException informando que nome um atributo no altervel.
Faltou adicionarmos o setter do atributo OlaMundoBean, para que o JSF possa preench-lo! Alm disso,
o boto chamar o mtodo nomeFoiDigitado, que tambm no existe ainda.
Complete a classe com o setter faltante e o mtodo nomeFoiDigitado, reinicie o servidor e teste!
@ManagedBean
public class OlaMundoBean {
// ...tudo o que j existia aqui
Captulo - Introduo ao JSF e Primefaces - Exerccios: Os primeiros componentes JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public void setNome(String nome) {
this.nome = nome;
}
public void nomeFoiDigitado() {
System.out.println("\nChamou o boto");
}
}
) (Opcional) Para entender melhor o ciclo de execuo de cada chamada ao JSF, adicione
System.out.println("nome do mtodo") a cada um dos mtodos da sua aplicao e veja a ordem das
chamadas pelo console do Eclipse.
. A t:s1n ov Nvcoc:novs
Agora que j aprendemos o bsico do JSF, nosso objetivo listar emuma pgina as negociaes do web service
que o Argentumconsome. Nessa listagem, queremos mostrar as informaes das negociaes carregadas --
isto , queremos uma forma de mostrar preo, quantidade e data de cada negociao. E a forma mais natural
de apresentar dados desse tipo , certamente, uma tabela.
At poderamos usar a tabela que vem na taglib padro do JSF, mas ela bastante limitada e no tem pr-
defnies de estilo. Isto , usando a taglib padro, teremos simuma tabela no HTML, mas ela ser mostrada
da forma mais feia e simples possvel.
J falamos, contudo, que a proposta do JSF abstrair toda a complexidade relativa web -- e isso inclui CSS,
formataes, JavaScript e tudo o mais. Ento, em apoio s tags bsicas, algumas bibliotecas mais sofsticadas
surgiram. As mais conhecidas delas so PrimeFaces, RichFaces e IceFaces.
Taglibs como essas oferecemumvisual mais bacana j pr-pronto e, tambm, diversas outras facilidades. Por
exemplo, uma tabela que utilize as tags do Primefaces j vem com um estilo bonito, possibilidade de colocar
cabealhos nas colunas e at recursos mais avanados como paginao dos registros.
O componente responsvel por produzir uma tabela baseada em um modelo se chama dataTable. Ele fun-
ciona de forma bem semelhante ao for do Java ou o forEach da JSTL: itera em uma lista de elementos
atribuindo cada item na varivel defnida.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Argentum</title>
</h:head>
<h:body>
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
Captulo - Introduo ao JSF e Primefaces - A lista de negociaes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
</p:dataTable>
</h:body>
</html>
O cdigo acima chamar o mtodo getNegociacoes da classe ArgentumBean e iterar pela lista devolvida
atribuindo o objeto varivel negociacao. Ento, para cada coluna que quisermos mostrar, ser necessrio
apenas manipular a negociao do momento.
E, intuitivamente o bastante, cada coluna da tabela ser representada pela tag p:column. Para mostrar o
valor, voc pode usar a tag que j vimos antes, o h:outputText. Note que as tags do Primefaces se integram
perfeitamente com as bsicas do JSF.
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
<p:column headerText="Preo">
<h:outputText value="#{negociacao.preco}"/>
</p:column>
... outras colunas
</p:dataTable>
Falta ainda implementar a classe que cuidar de devolver essa lista de negociaes. O cdigo acima sugere
que tenhamos uma classe chamada ArgentumBean, gerenciada pelo JSF, que tenha um getter de negociaes
que pode, por exemplo, trazer essa lista direto do ClienteWebService que fzemos anteriormente:
@ManagedBean
public class ArgentumBean {
public List<Negociacao> getNegociacoes() {
return new ClienteWebService().getNegociacoes();
}
}
Da forma acima, o exemplo j funciona e voc ver a lista na pgina. No entanto, nesse exemplo simples o JSF
chamar o mtodo getNegociacoes duas vezes durante uma mesma requisio. Isso no seria um problema
se ele fosse um getter padro, que devolve uma referncia local, mas note como nosso getNegociacoes vai
buscar a lista diretamente no web service. Isso faz com que, para construir uma simples pgina, tenhamos
que esperar a resposta do servio... duas vezes!
Esse comportamento no interessante. Ns gostaramos que o Argentum batesse no servio em busca
dos dados apenas uma vez por requisio, e no a cada vez que o JSF chame o getter. Isso signifca que o
acesso ao servio no pode estar diretamente no mtodo getNegociacoes, que deve apenas devolver a lista
pr-carregada.
No JSF, o comportamento padro diz que um objeto do ManagedBean dura por uma requisio. Em outras
palavras, o escopo padro dos beans no JSF o de requisio. Isso signifca que um novo ArgentumBean
Captulo - Introduo ao JSF e Primefaces - A lista de negociaes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
ser criado a cada vez que um usurio chamar a pgina da listagem. E, para cada chamada a essa pgina,
precisamos buscar a lista de negociaes no servio apenas uma vez. A resposta para esse problema, ento,
bastante simples e apareceu logo no incio do aprendizado do Java orientado a objetos.
Basta colocar a chamada do web service naquele bloco de cdigo que chamado apenas na criao do objeto,
isto , no construtor. Ao armazenar a listagememumatributo, o getter de negociaes passa a simplesmente
devolver a referncia, evitando as mltiplas chamadas a cada requisio.
@ManagedBean
public class ArgentumBean {
private List<Negociacao> negociacoes;
public ArgentumBean() {
ClienteWebService cliente = new ClienteWebService();
this.negociacoes = cliente.getNegociacoes();
}
public List<Negociacao> getNegociacoes() {
return this.negociacoes;
}
}
Juntando as informaes dessa seo, j conseguimos montar a listagemde negociaes comos dados vindos
do web service. E o processo ser muito frequentemente o mesmo para as diversas outras telas: criamos a
pgina usando as tags do Primefaces emcomplemento s bsicas do JSF, implementamos a classe que cuidar
da lgica por trs da tela e a anotamos com @ManagedBean.
. Fonmn1nXo ov Dn1n comJSF
A tabela j funcional, mas com a data mal formatada. O componente no sabe como gostaramos de for-
matar a data e chama por de baixo dos planos o mtodo toString da data para receber uma apresentao
como String.
A forma clssica de resolver esse problema seria atravs de um getter que traria a data formatada por um
SimpleDateFormat. Mas, assim como a JSTL vista no curso de Java para a Web, o JSF tambm tem uma tag
Captulo - Introduo ao JSF e Primefaces - Formatao de Data com JSF - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
para formatar valores, nmeros e, claro, datas. Essas tags e muitas outras, so parte da biblioteca fundamental
de tags lgicas do JSF e, para us-las, ser necessrio importar tal taglib.
Assim como as bibliotecas de tags de HTML e do Primefaces, para utilizar essas ser necessrio declar-las
no namespace da sua pgina.
Da, podemos facilmente mudar a forma padro de exibio usando o componente de formatao
f:convertDateTime que defne um pattern para a data. importante lembrar que, internamente, o
f:convertDateTime acaba fazendo uma chamada ao SimpleDateFormat e, assim, s podemos formatar ob-
jetos do tipo java.util.Date com ele. Por essa razo, chamaremos o mtodo getTime que devolve a repre-
sentao em Date do Calendar em questo. Mais uma vez podemos omitir a palavra get com expression
language. Segue a tabela completa:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:body>
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
... outras colunas, e ento:
<p:column headerText="Data">
<h:outputText value="#{negociacao.data.time}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
</p:dataTable>
</h:body>
</html>
. Exvncc:os: v:on1nTnntv vnnn t:s1nn ns Nvcoc:novs oo
Wvn Svnv:cv
) Use ctrl + N HTML para criar um novo arquivo na pasta WebContent chamado olaMundo.xhtml. Como
j fzemos antes, clique em Next e, na tela seguinte, escolha o template xhtml . transitional.
O Eclipse vai gerar um arquivo com um pouco de informaes a mais, mas ainda muito parecido com o
seguinte, onde mudamos o title:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Argentum Web</title>
</head>
Captulo - Introduo ao JSF e Primefaces - Exerccios: p:dataTable para listar as Negociaes do Web Service - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<body>
</body>
</html>
) Como vamos usar o JSF nesse arquivo e j temos at mesmo o JAR primefaces-.x.jar adicionado ao pro-
jeto (veja emWebContent/WEB-INF/lib) basta declarar os namespaces das taglibs do JSF e do Primefaces,
que usaremos no exerccio.
Almdisso, para que os componentes consigamincluir seu CSS nossa pgina, altere as tags head e body
de forma a usar suas verses gerenciadas pelo JSF:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Argentum Web</title>
</h:head>
<h:body>
</h:body>
</html>
) Agora, dentro do h:body, vamos comear a montar nossa tabela de negociaes. O componente que
usaremos para isso o p:datatable, do Primefaces. Ele precisar da lista de negociaes e, assim como
um forEach, uma varivel para que cada coluna seja preenchida.
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
</p:dataTable>
) Esse cdigo acima diz que o componente dataTable do Primefaces chamar o mtodo getNegociacoes()
da classe ArgentumBean e, para cada linha da tabela, disponibilizar a negociao da vez na varivel
negociacao.
O problema que o managed bean ArgentumBean ainda no existe e, claro, nem o mtodo
getNegociacoes() dela. E como cada vez que a pgina index.xhtml for requisitada ela far algumas
chamadas ao getNegociacoes, faremos a chamada ao webservice no construtor e, a cada chamada ao
getter, apenas devolveremos a referncia mesma lista.
a) Crie a classe ArgentumBean com ctrl + N Class, no pacote br.com.caelum.argentum.bean e anote ela
com @ManagedBean.
@ManagedBean
public class ArgentumBean {
}
Captulo - Introduo ao JSF e Primefaces - Exerccios: p:dataTable para listar as Negociaes do Web Service - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
b) Adicione o construtor que faa a chamada ao webservice atravs do ClienteWebservice, guarde a lista
em um atributo e crie o getter que o componente chamar.
@ManagedBean
public class ArgentumBean {
private List<Negociacao> negociacoes;
public ArgentumBean() {
negociacoes = new ClienteWebService().getNegociacoes();
}
public List<Negociacao> getNegociacoes() {
return negociacoes;
}
}
) Agora, nossa pgina j no d erro, mas nada mostrado na tela, quando a acessamos. Falta indicarmos
quais colunas queremos na nossa tabela -- no nosso caso: preo, quantidade, volume e data. Em cada
coluna, adicionaremos um ttulo e cada uma delas tambm mostrar o valor de texto.
Para criar a coluna como ttulo, usaremos o componente p:column e, como j fzemos antes, para mostrar
o valor necessrio, usaremos a h:outputText.
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
<p:column headerText="Preo">
<h:outputText value="#{negociacao.preco}"/>
</p:column>
<p:column headerText="Quantidade">
<h:outputText value="#{negociacao.quantidade}"/>
</p:column>
<p:column headerText="Volume">
<h:outputText value="#{negociacao.volume}"/>
</p:column>
<p:column headerText="Data">
<h:outputText value="#{negociacao.data}"/>
</p:column>
</p:dataTable>
) Reinicie o Tomcat e acesse em seu navegador o endereo http://localhost:/f-argentum-web/index.
xhtml . O resultado deve ser algo parecido com:
Captulo - Introduo ao JSF e Primefaces - Exerccios: p:dataTable para listar as Negociaes do Web Service - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) As informaes de preo, quantidade e volume esto legveis, mas a data das negociaes est mostrando
um monte de informaes que no nos interessam. Na verdades, o que precisamos na coluna data de
informaes de dia, ms, ano e, no mximo, horrio de cada movimentao.
Adicione a tag f:convertDateTime coluna da data. Essa tag modifcar o comportamento da
h:outputText para mostr-lo formatado de acordo com o padro passado. Note que a tag h:outputText
passar a ser fechada depois da formatao da data:
...
<p:column headerText="Data">
<h:outputText value="#{negociacao.data.time}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
...
. Pnnn snnvn mn:s: vnc:NnXo v onovNnXo
O componente p:dataTable sabe listar items, mas no pra por a. Ele j vem com vrias outras funcionali-
dades frequentemente necessrias em tabelas j prontas e fceis de usar.
Mc:1os onoos
Por exemplo, quando um programa traz uma quantidade muito grande de dados, isso pode causar uma
pgina pesada demais para o usurio que provavelmente nem olhar com ateno todos esses dados.
Uma soluo clssica para resultados demais mostr-los aos poucos, apenas conforme o usurio indicar
que quer ver os prximos resultados. Estamos, claro, falando da paginao dos resultados e o componente
de tabelas do Primefaces j a disponibiliza!
Para habilitar a paginao automtica, basta adicionar o atributo paginator="true" sua p:dataTable e
defnir a quantidade de linhas por pgina pelo atributo rows. A defnio da tabela de negociaes para
paginao de em resultados fcar assim:
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}"
paginator="true" rows="15">
Captulo - Introduo ao JSF e Primefaces - Para saber mais: paginao e ordenao - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<!-- colunas omitidas -->
</p:dataTable>
Essa pequena mudana j traz uma visualizao mais legal para o usurio, mas estamos causando um pro-
blema silencioso no servidor. A cada vez que voc chama uma pgina de resultados, a cada requisio, o
ArgentumBean recriado e perdemos a lista anterior. Assim, na criao da nova instncia de ArgentumBean,
seu construtor chamado e acessamos novamente o webservice.
Como recebemos a lista completa do webservice, podamos aproveitar a mesma lista para todas as pginas
de resultado e, felizmente, isso tambm bastante simples.
Ocomportamento padro de umManagedBean durar apenas uma requisio. Emoutras palavras, o escopo
padro de um ManagedBean de request. Com apenas uma anotao podemos alterar essa durao. Os trs
principais escopos do JSF so:
RequestScoped: o escopo padro. A cada requisio um novo objeto do bean ser criado;
ViewScoped: escopo da pgina. Enquanto o usurio estiver na mesma pgina, o bean mantido. Ele
s recriado quando acontece uma navegao em s, isto , um boto abre uma pgina diferente ou
ainda quando acessamos novamente a pgina atual.
SessionScoped: escopo de sesso. Enquanto a sesso com o servidor no expirar, o mesmo objeto do
ArgentumBean atender o mesmo cliente. Esse escopo bastante usado, por exemplo, para manter o
usurio logado em aplicaes.
No nosso caso, o escopo da pgina resolve plenamente o problema: enquanto o usurio no recarregar a
pgina usaremos a mesma listagem. Para utiliz-lo, basta adicionar ao bean a anotao @ViewScoped. No
exemplo do Argentum:
@ManagedBean
@ViewScoped
public class ArgentumBean {
...
T:nnNoo :Nvonmnovs mn:s vnc:tmvN1v
Outra situao clssica que aparece quando lidamos com diversos dados precisarmos v-los de diferentes
formas em situaes diversas.
Considere um sistema que apresenta uma tabela de contatos. Se quisermos encontrar um contato especfco
nela, melhor que ela esteja ordenada pelo nome. Mas caso precisemos pegar os contatos de todas as pessoas
de uma regio, melhor que a tabela esteja ordenada, por exemplo, pelo DDD.
Essa ideia de ordenao extremamente til e muito presente em aplicaes. Como tal, essa funcionali-
dade tambm est disponvel para tabelas do Primefaces. Apenas, como podemos tornar diversar colunas
ordenveis, essa confgurao fca na tag da coluna.
Captulo - Introduo ao JSF e Primefaces - Para saber mais: paginao e ordenao - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Para tornar uma coluna ordenvel, preciso adicionar um simples atributo sortBy tag h:column corres-
pondente. Esse atributo torna o cabealho dessa coluna em um elemento clicvel e, quando clicarmos nele,
chamar a ordenao.
Contudo, exatamente pela presena de elementos clicveis, ser necessrio colocar a tabela dentro de uma
estrutura que comporte botes em HTML: um formulrio. E, como quem confgurar o que cada clique vai
disparar o JSF, ser necessrio usar o formulrio da taglib de HTML dele. Resumidamente, precisamos
colocar a tabela inteira dentro do componente h:form.
Se quisssemos tornar ordenveis as colunas da tabela de negociaes, o resultado fnal seria algo como:
<h:form id="listaNegociacao">
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}">
<p:column sortBy="#{negociacao.preco}" headerText="Preo" >
<h:outputText value="#{negociacao.preco}" />
</p:column>
<!-- outras colunas omitidas -->
</p:dataTable>
<h:form>
Se permitirmos ordenar por qualquer coluna do modelo Negociacao, teremos um resultado bem atraente:
Note que no foi necessrio adicionar cdigo algum classe ArgentumBean! Note tambmque at possvel
usar ambas as funcionalidades na mesma tabela. E essas so apenas algumas das muitas facilidades que o
p:dataTable oferece. Vale a pena verifcar o showcase e documentao no site do Primefaces.
. Exvncc:o ovc:oNnt: no:c:oNv vnc:NnXo v onovNnXo X
1nnvtn
) Vamos colocar paginao na tabela. Adicione os atributos paginator="true" e rows="15". Adicione os
atributos paginator e rows:
Captulo - Introduo ao JSF e Primefaces - Exerccio opcional: adicione paginao e ordenao tabela - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<p:dataTable var="negociacao" value="#{argentumBean.negociacoes}"
paginator="true" rows="15">
Salve a pgina, suba o servidor e acesse no seu navegador o endereo http://localhost:/
f-argentum-web/index.xhtml . Agora voc j consegue ver resultados paginados de em negociaes:
) Para evitar chamar o webservice a cada vez que pedimos os prximos resultados paginados, adicione a
anotao @ViewScoped classe ArgentumBean:
@ManagedBean
@ViewScoped
public class ArgentumBean {
...
}
) Deixe as colunas ordenveis, use o atributo sortBy em cada atributo. Por exemplo, para a coluna que
mostra o preo da negociao:
<p:column sortBy="#{negociacao.preco}" headerText="Preo" >
<h:outputText value="#{negociacao.preco}" />
</p:column>
Repare que usamos a expression language #{negociacao.preco} do JSF dentro do sortBy para defnir o
valor a ordenar.
Salve a pgina e veja o resultado recarregando a pgina (F) no seu navegador.
Captulo - Introduo ao JSF e Primefaces - Exerccio opcional: adicione paginao e ordenao tabela - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
n:vonmsvmvnv csnnK HTTP POST
importante saber que diferente da tag form no HTML, o h:form sempre envia uma requisio
HTTP do tipo POST. Ele nem nos d a possibilidade de escolher usar requisies GET.
Isso ocorre porque o JSF tenta abstrair o mundo HTTP e assim fca mais perto do desenvolvi-
mento Desktop tradicional. Ele esconde do desenvolvedor o fato de que uma URL est sendo
chamada. Em vez disso, para o desenvolvedor, como se botes efetivamente chamassem mto-
dos ou eventos dentro de um Managed Bean.
A deciso automtica pelo POST foi a forma encontrada para abstrair o HTTP.
Captulo - Introduo ao JSF e Primefaces - Exerccio opcional: adicione paginao e ordenao tabela - Pgina
C
Refatorao: os Indicadores da bolsa
Nunca confe em um computador que voc no pode jogar pela janela.
Steve Wozniak
. ANKt:sv TvcN:cn on notsn ov vntonvs
Munehisa Homna, no sculo , foi quem comeou a pesquisar os preos antigos do arroz para reconhecer
padres. Ele fez isso e comeou a criar um catlogo grande de fguras que se repetiam.
A estrela da manh, Doji, da fgura abaixo, um exemplo de fgura sempre muito buscada pelos analistas:
Ela indica umpadro de reverso. Dizemque quando o preo de abertura e fechamento praticamente igual
(a estrela), essa uma forte indicao de que o mercado se inverta, isto , se estava em uma grande baixa,
tender a subir e, se estava em uma grande alta, tender a cair.
Baseada nessas ideias, surgiu a Anlise Tcnica Grafsta: uma escola econmica que tem como objetivo
avaliar o melhor momento para compra e venda de aes atravs da anlise histrica e comportamental do
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
ativo na bolsa.
Essa forma de anlise dos dados gerados sobre dados das negociaes (preo, volume, etc), usa grfcos na
busca de padres e faz anlise de tendncias para tentar prever o comportamento futuro de uma ao.
Aanlise tcnica surgiu no incio do sculo , como trabalho de Charles Dowe Edward Jones. Eles criaram
a empresa DowJones &Company e foramos primeiros a inventaremndices para tentar prever o comporta-
mento do mercado de aes. Oprimeiro ndice era simplesmente uma mdia ponderada de ativos famosos
da poca, que deu origem ao que hoje conhecido como Dow-Jones.
A busca de padres nos candlesticks uma arte. Atravs de critrios subjetivos e formao de fguras, ana-
listas podem determinar, com algum grau de acerto, como o mercado se comportar dali para a frente.
. INo:cnoonvs TvcN:cos
Uma das vrias formas de aplicar as premissas da anlise tcnica grafsta atravs do uso de indicadores
tcnicos. Indicadores so frmulas que manipulam dados das negociaes e tiram valores deles em busca
de informaes interessantes para recomendar as prximas aes para um ativo. Esse novo nmero, deter-
minstico e de fcil clculo por umcomputador. at de praxe que analistas fnanceiros programemdiversas
dessas frmulas em macros VBScript, para v-las dentro do Excel.
comum, na mesma visualizao, termos uma combinao de grfcos, indicadores e at dos candles:
Diversos livros so publicados sobre o assunto e os principais homebrokers fornecem sofwares que traam
esses indicadores e muitos outros. Alm disso, voc encontra uma lista com os indicadores mais usados e
como calcul-los em: http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators
Captulo - Refatorao: os Indicadores da bolsa - Indicadores Tcnicos - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. As mvo:ns movv:s
H diversos tipos de mdias mveis usadas em anlises tcnicas e elas so frequentemente usadas para in-
vestidores que fazem compras/vendas em intervalos muito maiores do que o intervalo de recolhimento de
dados para as candles. As mdias mais famosas so a simples, a ponderada, a exponencial e a Welles Wilder.
Vamos ver as duas primeiras, a mdia mvel simples e a mdia mvel ponderada.
Mvo:n movvt s:mvtvs
A mdia mvel simples calcula a mdia aritmtica de algum dos valores das candlesticks do papel para um
determinado intervalo de tempo -- em geral, o valor de fechamento. Basta pegar todos os valores, somar e
dividir pelo nmero de dias.
A fgura a seguir mostra duas mdias mveis simples: uma calculando a mdia dos ltimos dias e outra
dos ltimos dias. O grfco do valor das aes da antiga Sun Microsystems em .
Repare que a mdia mvel mais curta, a de dias, responde mais rpido aos movimentos atuais da ao,
mas pode gerar sinais pouco relevantes a mdio prazo.
Usualmente, estamos interessados na mdia mvel dos ltimos N dias e queremos defnir esse dia inicial. Por
exemplo, para os dados de fechamento abaixo:
DIA FECHAMENTO
dia 1: 31
dia 2: 32
dia 3: 33
dia 4: 34
dia 5: 33
Captulo - Refatorao: os Indicadores da bolsa - As mdias mveis - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
dia 6: 35
dia 7: 34
dia 8: 33
Vamos fazer as contas para que o indicador calcule a mdia para os dias anteriores ao dia que estamos
interessados. Por exemplo: se pegamos o dia , a mdia mvel simples para os ltimos dias a soma do
dia ao dia : ( + + ) / = . A mdia mvel do dia para os ltimos dias : ( + + ) / . E
assim por diante.
O grfco anterior das mdias mveis da Sun pega, para cada dia do grfco, a mdia dos dias anteriores.
Mvo:n movvt voNovnnon
Outra mdia mvel muito famosa a ponderada. Ela tambmleva emconta os ltimos N dias a partir da data
a ser calculada. Mas, em vez de uma mdia aritmtica simples, faz-se uma mdia ponderada onde damos
mais peso para o valor mais recente e vamos diminuindo o peso dos valores conforme movemos para valores
mais antigos.
Por exemplo, para os dias a seguir:
DIA FECHAMENTO
dia 1: 11
dia 2: 12
dia 3: 14
dia 4: 18
dia 5: 15
dia 6: 13
dia 7: 12
dia 8: 16
Vamos calcular a mdia mvel para os ltimos dias, onde hoje tem peso , ontem tem peso e anteontem
tem peso . Se calcularmos a mdia mvel ponderada para o dia temos: (* + * + *) / = ..
Captulo - Refatorao: os Indicadores da bolsa - As mdias mveis - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Amdia ponderada nos d uma viso melhor do que est acontecendo no momento coma cotao da minha
ao, mostrando com menos importncia os resultados atrasados, portanto menos relevantes para minhas
decises de compra e venda atuais. Essa mdia, contudo, no to efciente quando estudamos uma srie a
longo prazo.
. Exvncc:os: cn:nNoo :No:cnoonvs
) O clculo de uma mdia mvel feito a partir de uma lista de resumos do papel na bolsa. No nosso caso,
vamos pegar vrios Candlesticks, um para cada dia, e usar seus valores de fechamento.
Para encapsular a lista de candles e aproximar a nomenclatura do cdigo utilizada pelo cliente no dia a
dia, vamos criar a classe SerieTemporal no pacote br.com.caelum.argentum.modelo:
public class SerieTemporal {
private final List<Candlestick> candles;
public SerieTemporal(List<Candlestick> candles) {
this.candles = candles;
}
public Candlestick getCandle(int i) {
return this.candles.get(i);
}
public int getUltimaPosicao() {
return this.candles.size() - 1;
}
}
) Vamos criar a classe MediaMovelSimples, dentro do novo pacote
br.com.caelum.argentum.indicadores. Essa classe ter o mtodo calcula que recebe a posio
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: criando indicadores - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
a ser calculada e a SerieTemporal que prover os candles. Ento, o mtodo devolver a mdia simples
dos fechamentos dos dois dias anteriores e o atual.
Comece fazendo apenas o cabealho desse mtodo:
public class MediaMovelSimples {
public double calcula(int posicao, SerieTemporal serie) {
return 0;
}
}
Aideia passarmos para o mtodo calcula a SerieTemporal e o dia para o qual queremos calcular a mdia
mvel simples. Por exemplo, se passarmos que queremos a mdia do dia da srie, ele deve calcular a
mdia dos valores de fechamento dos dias , e (j que nosso intervalo de dias).
Como essa uma lgica um pouco mais complexa, comearemos essa implementao pelos testes.
) Seguindo a ideia do TDD, faremos o teste antes mesmo de implementar a lgica da mdia. Assim como
voc j vemfazendo, use o ctrl + N ->JUnit Test Case para criar a classe de teste MediaMovelSimplesTest
na source folder src/test/java, pacote br.com.caelum.argentum.indicadores.
Ento, crie umteste para verifcar que a mdia calculada corretamente para a sequncia de fechamentos
1, 2, 3, 4, 3, 4, 5, 4, 3.
Note que, para fazer tal teste, ser necessrio criar uma srie temporal com candles cujo fechamento
tenha tais valores. Criaremos uma outra classe para auxiliar nesses testes logo em seguida. Por hora, no
se preocupe com o erro de compilao da a. linha do cdigo abaixo:
public class MediaMovelSimplesTest {

@Test
public void sequenciaSimplesDeCandles() throws Exception {
SerieTemporal serie =
GeradorDeSerie.criaSerie(1, 2, 3, 4, 3, 4, 5, 4, 3);
MediaMovelSimples mms = new MediaMovelSimples();

Assert.assertEquals(2.0, mms.calcula(2, serie), 0.00001);


Assert.assertEquals(3.0, mms.calcula(3, serie), 0.00001);
Assert.assertEquals(10.0/3, mms.calcula(4, serie), 0.00001);
Assert.assertEquals(11.0/3, mms.calcula(5, serie), 0.00001);
Assert.assertEquals(4.0, mms.calcula(6, serie), 0.00001);
Assert.assertEquals(13.0/3, mms.calcula(7, serie), 0.00001);
Assert.assertEquals(4.0, mms.calcula(8, serie), 0.00001);
}
}
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: criando indicadores - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Ainda necessrio fazer esse cdigo compilar! Note que, pelo que escrevemos, queremos chamar um
mtodo esttico na classe GeradorDeSerie que receber diversos valores e devolver a srie com Candles
respectivas.
Deixe que o Eclipse o ajude a criar essa classe: use o ctrl + 1 e deixe que ele crie a classe para voc
e, ento, adicione a ela o mtodo criaSerie, usando o recurso de varargs do Java para receber diversos
doubles.
Vnnnncs
A notao double... valores (com os trs pontinhos mesmo!) que usaremos no mtodo a
seguir indicao do uso de varargs. Esse recurso est presente desde o Java e permite que
chamemos o mtodo passando de zero a quantos doubles quisermos! Dentro do mtodo, esses
argumentos sero interpretados como um array.
Varargs vieram para oferecer uma sintaxe mais amigvel nesses casos. Antigamente, quando
queramos passar um nmero varivel de parmetros de um mesmo tipo para um mtodo, era
necessrio construir um array com esses parmetros e pass-lo como parmetro.
Leia mais sobre esse recurso em: http://docs.oracle.com/javase/../docs/guide/language/
varargs.html
Na classe GeradorDeSerie, faa o seguinte mtodo:
Ateno: no necessrio copiar o JavaDoc.
/**
* Serve para ajudar a fazer os testes.
*
* Recebe uma sequncia de valores e cria candles com abertura, fechamento,
* minimo e maximo iguais, mil de volume e data de hoje. Finalmente, devolve
* tais candles encapsuladas em uma Serie Temporal.
**/
public static SerieTemporal criaSerie(double... valores) {
List<Candlestick> candles = new ArrayList<Candlestick>();
for (double d : valores) {
candles.add(new Candlestick(d, d, d, d, 1000,
Calendar.getInstance()));
}
return new SerieTemporal(candles);
}
Agora que ele compila, rode a classe de teste. Ele falha, j que a implementao padro simplesmente
devolve zero!
) Volte classe principal MediaMovelSimples e implemente agora a lgica de negcio do mtodo calcula,
que j existe. O mtodo deve fcar parecido com o que segue:
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: criando indicadores - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public class MediaMovelSimples {

public double calcula(int posicao, SerieTemporal serie) {


double soma = 0.0;
for (int i = posicao; i > posicao - 3; i--) {
Candlestick c = serie.getCandle(i);
soma += c.getFechamento();
}
return soma / 3;
}
}
Repare que iniciamos o for com posicao e iteramos com i--, retrocedendo nas posies enquanto elas
forem maiores que os trs dias de intervalo. Isso signifca que estamos calculando a mdia mvel apenas
dos ltimos dias.
Mais para frente, existe um exerccio opcional para parametrizar esse valor.
) Crie a classe MediaMovelPonderada anloga a MediaMovelSimples. Essa classe d peso para o dia atual,
peso para o dia anterior e o peso para o dia antes desse. O cdigo interno muito parecido com o da
mdia mvel simples, s precisamos multiplicar sempre pela quantidade de dias passados.
A implementao do mtodo calcula deve fcar bem parecida com isso:
public class MediaMovelPonderada {

public double calcula(int posicao, SerieTemporal serie) {


double soma = 0.0;
int peso = 3;

for (int i = posicao; i > posicao - 3; i--) {


Candlestick c = serie.getCandle(i);
soma += c.getFechamento() * peso;
peso--;
}
return soma / 6;
}
}
Repare que o peso comea valendo 3, o tamanho do nosso intervalo, para o dia atual e vai reduzindo
conforme nos afastamos do dia atual, demonstrando a maior importncia dos valores mais recentes.
A diviso por 6 no fnal a soma dos pesos para o intervalo de 3 dias: ( + + = ).
) Depois a classe MediaMovelPonderada deve passar pelo seguinte teste:
public class MediaMovelPonderadaTest {
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: criando indicadores - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
@Test
public void sequenciaSimplesDeCandles() {
SerieTemporal serie =
GeradorDeSerie.criaSerie(1, 2, 3, 4, 5, 6);
MediaMovelPonderada mmp = new MediaMovelPonderada();
//ex: calcula(2): 1*1 + 2*2 +3*3 = 14. Divide por 6, da 14/6
Assert.assertEquals(14.0/6, mmp.calcula(2, serie), 0.00001);
Assert.assertEquals(20.0/6, mmp.calcula(3, serie), 0.00001);
Assert.assertEquals(26.0/6, mmp.calcula(4, serie), 0.00001);
Assert.assertEquals(32.0/6, mmp.calcula(5, serie), 0.00001);
}
}
Rode o teste e veja se passamos!
) (opcional) Crie umteste de unidade em uma nova classe SerieTemporalTest, que verifque se essa classe
pode receber uma lista nula. O que no deveria poder.
Aproveite o momento para pensar quais outros testes poderiam ser feitos para essa classe.
. Rvvn1onnXo
"Refatorao uma tcnica controlada para reestruturar um trecho de cdigo existente, alterando sua estrutura
interna sem modifcar seu comportamento externo. Consiste em uma srie de pequenas transformaes que
preservam o comportamento inicial. Cada transformao (chamada de refatorao) refete em uma pequena
mudana, mas uma sequncia de transformaes pode produzir uma signifcante reestruturao. Como cada
refatorao pequena, menos provvel que se introduza um erro. Alm disso, o sistema continua em pleno
funcionamento depois de cada pequena refatorao, reduzindo as chances do sistema ser seriamente danifcado
durante a reestruturao. -- Martin Fowler
Emoutras palavras, refatorao o processo de modifcar umtrecho de cdigo j escrito, executando peque-
nos passos (baby-steps) semmodifcar o comportamento do sistema. uma tcnica utilizada para melhorar
a clareza do cdigo, facilitando a leitura ou melhorando o design do sistema.
Note que para garantir que erros no sero introduzidos nas refatoraes, bem como para ter certeza de
que o sistema continua se comportando da mesma maneira que antes, a presena de testes fundamental.
Com eles, qualquer erro introduzido ser imediatamente apontado, facilitando a correo a cada passo da
refatorao imediatamente.
Algumas das refatoraes mais recorrentes ganharamnomes que identifcamsua utilidade (veremos algumas
nas prximas sees). Alm disso, Martin Fowler escreveu o livro Refactoring: Improving the Design of
Existing Code, onde descreve em detalhes as principais.
Algumas so to corriqueiras, que o prprio Eclipse inclui um menu com diversas refatoraes que ele
Captulo - Refatorao: os Indicadores da bolsa - Refatorao - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
capaz de fazer por voc:
. Exvncc:os: Pn:mv:nns nvvn1onnovs
) Temos usado no texto sempre o termo candle em vez de Candlestick. Essa nomenclatura se propagou
no nosso dia-a-dia, tornando-se parte do nosso modelo. Refatore o nome da classe Candlestick para
Candle no pacote br.com.caelum.argentum.modelo.
Use ctrl + shift + T para localizar e abrir a classe Candlestick.
Seja no Package Explorer ou na classe aberta no editor, coloque o cursor sobre o nome da classe e use
o atalho alt + shift + R, que renomeia. Esse atalho funciona para classes e tambm para mtodos,
variveis, etc.
) No mtodo calcula da classe MediaMovelSimples, temos uma varivel do tipo Candle que s serve para
que peguemos o fechamento desse objeto. Podemos, ento, deixar esse mtodo uma linha menor fazendo
o inline dessa varivel!
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: Primeiras refatoraes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Na linha do mtodo abaixo, coloque o cursor na varivel c e use o alt + shift + I. (Alternativamente,
use ctrl + 1 Inline local variable)
public double calcula(int posicao, SerieTemporal serie) {
double soma = 0.0;
for (int i = posicao - 2; i <= posicao; i++) {
Candle c = serie.getCandle(i);
soma += c.getFechamento();
}
return soma / 3;
}
O novo cdigo, ento fcar assim:
public double calcula(int posicao, SerieTemporal serie) {
double soma = 0.0;
for (int i = posicao - 2; i <= posicao; i++) {
soma += serie.getCandle(i).getFechamento();
}
return soma / 3;
}
No esquea de tirar os imports desnecessrios (ctrl + shift + O)!
) Finalmente, abra a classe CandlestickFactory e observe o mtodo constroiCandles. Escrevemos esse
mtodo no captulo de XML com um algoritmo para separar todos os negcios em vrios candles.
No meio desse cdigo, contudo, h um pequeno bloco de cdigo que se repete duas vezes, dentro e fora
do for:
Candle candleDoDia = constroiCandleParaData(dataAtual, negociacoesDoDia);
candles.add(candleDoDia);
Se encontramos cdigos iguais pelo nosso cdigo, as boas prticas de orientao a objetos nos dizempara
isolar ento essa parte repetida em um novo mtodo que, alm de poder ser chamado vrias vezes, ainda
tem um nome que ajuda a compreender o algoritmo fnal.
No Eclipse, podemos aplicar a refatorao Extract Method. Basta ir at a classe CandlestickFactory e
selecionar essas linhas de cdigo dentro do mtodo constroiCandles e usar o atalho alt + shift + M,
nomeando o novo mtodo de criaEGuardaCandle e clique em OK.
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: Primeiras refatoraes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Repare como a IDE resolve os parmetros e ainda substitui as chamadas ao cdigo repetido pela chamada
ao novo mtodo.
) No mtodo constroiCandleParaData, observe que no bloco de cdigo dentro do for invocamos
negociacao.getPreco() quatro vezes.
// ...
for (Negociacao negociacao : negociacoes) {
volume += negociacao.getVolume();
if (negociacao.getPreco() > maximo) {
maximo = negociacao.getPreco();
}
if (negociacao.getPreco() < minimo) {
minimo = negociacao.getPreco();
}
}
// ...
Uma forma de deixar o cdigo mais limpo e evitar chamadas desnecessrias seria extrair para uma varivel
local.
Para isso, usaremos a refatoraoExtract Local Variable atravs do Eclipse. Selecione a primeira chamada
para negociacao.getPreco() e pressione alt + shift + L.
Um box vai aparecer perguntando o nome da varivel que ser criada, mantenha o nome aconselhado
pelo Eclipse e pressione OK.
O Eclipse vai alterar o cdigo de forma que fque parecido com:
Captulo - Refatorao: os Indicadores da bolsa - Exerccios: Primeiras refatoraes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
// ...
for (Negociacao negociacao : negociacoes) {
volume += negociacao.getVolume();
double preco = negociacao.getPreco();
if (preco > maximo) {
maximo = preco;
}
if (preco < minimo) {
minimo = preco;
}
}
// ...
Observe que o Eclipse automaticamente substituiu as outras chamadas negociacoes.getPreco() por
preco.
) (Opcional) Aproveite e mude os nomes das outras classes que usam a palavra Candlestick: a Factory e
os Testes.
Rvvn1onnovs o:svoNvv:s
Para quem est comeando com a usar o Eclipse, a quantidade de atalhos pode assustar. Note,
contudo, que os atalhos de refatorao comeam sempre com alt + shift!
Para ajudar um pouco, comece memorizando apenas o atalho que mostra as refatoraes dispo-
nveis dado o trecho de cdigo selecionado: alt + shift + T.
. Rvvn1onnovs mn:onvs
As refatoraes que fzemos at agora so bastante simples e, por conta disso, o Eclipse pde fazer todo o
trabalho para ns!
H, contudo, refatoraes bem mais complexas que afetam diversas classes e podem mudar o design da
aplicao. Algumas refatoraes ainda mais complexas chegama modifcar at a arquitetura do sistema! Mas,
quanto mais complexa a mudana para chegar ao resultado fnal, mais importante quebrar essa refatorao
em pedaos pequenos e rodar os testes a cada passo.
Nos prximos captulos faremos refatoraes que fexibilizam nosso sistema e tornam muito mais fcil tra-
balhar com os indicadores tcnicos que vimos mais cedo.
Exemplos de refatoraes maiores so:
Adicionar uma camada a um sistema;
Tirar uma camada do sistema;
Captulo - Refatorao: os Indicadores da bolsa - Refatoraes maiores - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Trocar uma implementao domstica por uma biblioteca;
Extrair uma biblioteca de dentro de um projeto;
etc...
. D:sccssXo vmnctn: qcnNoo nvvn1onnn:
Captulo - Refatorao: os Indicadores da bolsa - Discusso em aula: quando refatorar? - Pgina
C
Grfcos interativos com Primefaces
A nica pessoa educada aquela que aprendeu a aprender e a mudar.
Carl Rogers
. Pon qcv csnn cnKv:cos:
Nossa aplicao apresenta os dados das negociaes tabularmente atravs do componente p:dataTable. Essa
forma de mostrar informaes interessante para analisarmos dados um a um, mas no ajudam muito
quando queremos ter uma ideia do que acontece com dados coletivamente.
Grfcos comprovadamente ajudamno entendimento mais abrangente dos dados e so mais fceis de analisar
do que nmeros dentro de uma tabela. simples reconhecer padres de imagens, por exemplo na anlise
tcnica de valores da bolsa.
Para o projeto Argentum, apresentaremos os valores da SerieTemporal em um grfco de linha, aplicando
algum indicador como abertura ou fechamento. Continuaremos com a biblioteca Primefaces que j vem
com suporte para vrios tipos de grfcos.
Exvmvtos ov cnKv:cos
O Primefaces j possui diversos componentes para grfcos: possvel utiliz-lo para desenhar grfcos de
linha, de barra, de pizza, de rea, grfcos para atualizao dinmica e at para Candles, entre outros. Tambm
possvel exportar e animar grfcos.
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. GnKv:cos como Pn:mvvncvs
Vamos usar o Primefaces para gerar um grfco que mostra a evoluo dos valores da srie.
Nosso projeto est confgurado e j podemos decidir qual grfco utilizar. Para facilitar a deciso e ao mesmo
tempo ver as possibilidades e tipos de grfcos disponveis, o showcase do Primefaces nos ajudar muito:
http://www.primefaces.org/showcase/ui/home.jsf
Nele encontramos o resultado fnal e tambm o cdigo utilizado para a renderizao. Vamos progra-
mar usando o componente p:lineChart que deve mostrar os valores de abertura ou de fechamento da
SerieTemporal.
Captulo - Grfcos interativos com Primefaces - Grfcos com o Primefaces - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
O uso de componente simples, veja o cdigo de exemplo do showcase:
<p:lineChart id="category" value="#{chartBean.categoryModel}" legendPosition="e"
title="Category Chart" minY="0" maxY="200" style="height:300px;margin-top:20px"/>
Alm dos atributos para defnir o layout (maxY e style) em forma de propriedades CSS, o ttulo (title) e a
posio da legenda (legendPosition), podemos ver que o componente recebe os dados (value) atravs da
Expression Language que chama o Managed Bean #{chartBean.categoryModel}.
. Pnovn:vonovs vnnn vvnsoNnt:znn o cnKv:co
J vimos algumas propriedades do componente p:lineChart, mas existem outras bastante utilizadas, so
elas:
legendPosition - a posio da legenda - west (w), east (e), south (s), north (n)
xaxisLabel - nome do eixo X
yaxisLabel - nome do eixo y
minX, maxX - mnimo e mximo do valor no eixo X
minY, maxY - mnimo e mximo do valor no eixo X
title - o ttulo do grfco
fill - true ou false, preenche o grfco, no renderiza uma linha apenas
showMarkers - true ou false, habilita detalhes em cada ponto do grfco
zoom - true ou false, habilita a funcionalidade de zoom no navegador
Todas as propriedades so opcionais. Na documentao do Primefaces h uma seo dedicada aos grfcos
no qual podemos ver as classes relacionadas, atributos do componentes com exemplos de utilizao. Segue
uma parte da documentao ofcial do Primefaces:
Captulo - Grfcos interativos com Primefaces - Propriedades para personalizar o grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
A documentao do Primefaces est disponvel na internet e na forma de um guia do usurio em PDF. Ela
far parte do dia-a-dia do desenvolvedor, que a consultar sempre que necessrio:
http://www.primefaces.org/documentation.html
Tambm h o tradicional Javadoc disponvel em: http://www.primefaces.org/docs/api/./. Devemos usar
ambos para descobrir funcionalidades e propriedades dos componentes.
No showcase tambm h um exemplo do uso do Managed Bean, porm para maiores informaes funda-
mental ter acesso ao Javadoc e documentao da biblioteca para saber quais classes, atributos e mtodos
utilizar.
Captulo - Grfcos interativos com Primefaces - Propriedades para personalizar o grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
JSF v CSS
O Primefaces ajuda o desenvolvedor atravs de seu suporte a temas, mas nem sempre ele suf-
ciente, inclusive quando h uma equipe de designers responsvel em determinar a apresentao
da aplicao.
Apesar de trabalharmos comcomponentes, no fnal o que enviado para o cliente puro HTML.
Assim, quem conhece CSS pode aplicar estilos para sobrescrever o visual da aplicao.
A Caelum oferece o curso Desenvolvimento Web com HTML, CSS e JavaScript, para aque-
les que querem aprender a criar interfaces Web com experincia rica do usurio, estruturao
correta e otimizaes SEO.
Avt:cnNoo no Nosso vno)v1o
Para mostrarmos o grfco no Argentum, usaremos a tag do Primefaces vista acima, colocando o ttulo In-
dicadores e a legenda de quais indicadores esto sendo traados esquerda do grfco.
No p:lineChart, passaremos essas informaes pelos atributos title, que recebe o ttulo como texto, e
legendPosition, que usa direes geogrfcas para defnir a posio da legenda. Isto , se queremos que ela
fque esquerda indicaremos que a legenda vai na poro oeste (west) do grfco.
<p:lineChart legendPosition="w" title="Indicadores"/>
Da forma como est, no entanto, no h nada a ser mostrado no grfco. Ainda falta indicarmos para o
componente que os dados, o modelo do grfco, ser disponibilizado por nosso ManagedBean. Em outras
palavras, faltou indicarmos que o value desse grfco ser produzido em argentumBean.modeloGrafico.
Nossa adio ao index.xhtml ser, portanto:
<p:lineChart value="#{argentumBean.modeloGrafico}"
legendPosition="w" title="Indicadores"/>
. Dvv:N:Xo oo moovto oo cnKv:co
J temos uma noo de como renderizar grfcos atravs de componentes do Primefaces. O desenvolvedor
no precisa se preocupar como detalhes de JavaScript, imagem ou animaes. Tudo isso encapsulado no
prprio componente, seguindo boas prticas do mundo orientado a objetos.
Apenas, ser necessrio informar ao componente quais so os dados a seremplotados no grfco emquesto.
Esses dados representamo modelo do grfco e devemser disponibilizados como o value para o p:lineChart
em um objeto do tipo org.primefaces.model.chart.ChartModel.
Captulo - Grfcos interativos com Primefaces - Defnio do modelo do grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Essa a classe principal do modelo e h classes flhas especializadas dela como CartesianChartModel,
PieChartModel ou BubbleChartModel. No JavaDoc podemos ver todas as flhas da ChartModel e ainda no
showcase possvel ver o ManagedBean responsvel por cada modelo de grfco. Assim, saberemos qual delas
devemos usar de acordo com o grfco escolhido:
Javadoc: http://www.primefaces.org/docs/api/./org/primefaces/model/chart/ChartModel.html
No nosso projeto, utilizaremos o CartesianChartModel, j que queremos plotar pontos em um grfco de
linha. Um CartesianChartModel recebe uma ou mais ChartSeries e cada ChartSeries representa uma
linha no grfco do componente p:lineChart. Uma ChartSeries, por sua vez, contm todos os pontos de
uma linha do grfco, isto , os valores X e Y que sero ligados pela linha do grfco.
Vejo como fca o cdigo fcil de usar:
ChartSeries serieGrafico = new ChartSeries("Abertura");
serieGrafico.set("dia 1", 20.9);
serieGrafico.set("dia 2", 25.1);
serieGrafico.set("dia 3", 22.6);
serieGrafico.set("dia 4", 24.6);
CartesianChartModel modeloGrafico = new CartesianChartModel();
modeloGrafico.addSeries(serieGrafico);
Uma ChartSeries recebe no construtor a legenda da linha que ela representa (label) e, atravs do mtodo set,
passamos os valores de cada ponto nos eixos horizontal e vertical, respectivamente. No exemplo acima, os va-
lores colocados so fxos, mas na nossa implementao do Argentum, claro, iteraremos pela SeriaTemporal
calculando os indicadores sobre ela.
Isto , uma vez que temos a SerieTemporal, nosso cdigo para plotar a mdia mvel simples do fechamento
em uma ChartSeries ser semelhante a este:
SerieTemporal serie = ...
ChartSeries chartSeries = new ChartSeries("MMS do Fechamento");
MediaMovelSimples indicador = new MediaMovelSimples(new IndicadorFechamento());
for (int i = 2; i < serie.getUltimaPosicao(); i++) {
double valor = indicador.calcula(i, serie);
chartSeries.set(i, valor);
}
CartesianChartModel modeloGrafico = new CartesianChartModel();
modeloGrafico.addSeries(chartSeries);
Conseguir a srie temporal um problema pelo qual j passamos antes. Relembre que a SerieTemporal
apenas um wrapper de uma lista de Candles. E a lista de Candles gerada pelo CandlestickFactory
resumindo uma lista com muitas Negociacoes.
Captulo - Grfcos interativos com Primefaces - Defnio do modelo do grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Se procurarmos o local no nosso cdigo onde pegamos a lista de negociaes do web service, vamos notar
que isso acontece no construtor da ArgentumBean. Seu cdigo completo fcaria assim;
public ArgentumBean() {
this.negociacoes = new ClienteWebService().getNegociacoes();
List<Candle> candles = new CandleFactory().constroiCandles(negociacoes);
SerieTemporal serie = new SerieTemporal(candles);
ChartSeries chartSeries = new ChartSeries("MMS do Fechamento");
MediaMovelSimples indicador = new MediaMovelSimples(new IndicadorFechamento());
for (int i = 2; i < serie.getUltimaPosicao(); i++) {
double valor = indicador.calcula(i, serie);
chartSeries.set(i, valor);
}
this.modeloGrafico = new CartesianChartModel();
modeloGrafico.addSeries(chartSeries);
}
Note, no entanto, que esse trecho de cdigo est com responsabilidades demais: ele busca as negociaes no
web service, cria a srie temporal, plota um indicador e disponibiliza o modelo do grfco. E, pior ainda, esse
cdigo ainda est no construtor do ArgentumBean!
Com todo esse cdigo no construtor do bean, teramos um cdigo mais sujo, pouco coeso e muito difcil de
testar. O que acontece aqui que no estamos separando responsabilidades o bastante e nem encapsulando
a lgica de gerao de grfco corretamente.
. IsotnNoo n API oo Pn:mvvncvs: nn:xo ncovtnmvN1o
O que acontecer se precisarmos criar dois grfcos de indicadores diferentes? Vamos copiar e colar todo
aquele cdigo e modifcar apenas as partes que mudam? E se precisarmos alterar algo na gerao do modelo?
Essas mudanas no sero fceis se tivermos o cdigo todo espalhado pelo nosso programa.
Os princpios de orientao a objetos e as boas prticas de programao vm ao nosso socorro aqui. Vamos
encapsular a maneira como o modelo do grfco criado na classe GeradorModeloGrafico.
Essa classe deve ser capaz de gerar o ChartModel para nosso grfco de linhas, com os pontos plotados pelos
indicadores combase nos valores de uma srie temporal. Isto , nosso GeradorModeloGrafico precisa receber
a SerieTemporal sobre a qual plotar os indicadores.
Captulo - Grfcos interativos com Primefaces - Isolando a API do Primefaces: baixo acoplamento - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Se quisermos restringir o grfco a um perodo menor do que o devolvido pelo web service, uma boa re-
cebermos as posies de incio e fm que devem ser plotadas. Esse intervalo tambm serve para que no
tentemos calcular a mdia da posio zero, por exemplo -- note que, como a mdia dos trs ltimos valo-
res, tentaramos pegar as posies 0, -1 e -2, o que causaria uma IndexOutOfBoundsException.
Como essas informaes so fundamentais para qualquer grfco que plotemos, o gerador do mo-
delo do grfco receber tais informaes no construtor. Alm delas, teremos tambm o objeto do
CartesianChartModel, que guardar as informaes do grfco.
public class GeradorModeloGrafico {
private SerieTemporal serie;
private int comeco;
private int fim;
private CartesianChartModel modeloGrafico;
public GeradorModeloGrafico(SerieTemporal serie, int comeco, int fim) {
this.serie = serie;
this.comeco = comeco;
this.fim = fim;
this.modeloGrafico = new CartesianChartModel();
}
}
E, quem for usar essa classe, far:
SerieTemporal serie = //...
GeradorModeloGrafico g = new GeradorModeloGrafico(serie, inicio, fim);
Repare como o cdigo que usa o GeradorModeloGrafico no possui nada que o ligue ao ChartModel especi-
fcamente. Odia emque precisarmos mudar o grfco a ser plotado ou mesmo mudar a tecnologia que gerar
o grfco, s precisaremos alterar a classe GeradorModeloGrafico. Relembre o conceito: esse o poder do
encapsulamento!
E nossa classe no se limitar a isso: ela encapsular tudo o que for relacionado ao grfco. Por exemplo, para
criar o grfco, precisamos ainda de um mtodo que plote os pontos calculados por um indicador, como
o plotaMediaMovelSimples abaixo. Ele passa por cada posio do comeco ao fim da serie, chamando o
clculo da mdia mvel simples.
public void plotaMediaMovelSimples() {
MediaMovelSimples indicador = new MediaMovelSimples();
LineChartSeries chartSerie = new LineChartSeries("MMS - Fechamento");
Captulo - Grfcos interativos com Primefaces - Isolando a API do Primefaces: baixo acoplamento - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSerie.set(i, valor);
}
this.modeloGrafico.addSeries(chartSerie);
}
O mtodo plotaMediaMovelSimples cria um objeto da MediaMovelSimples e varre a SerieTemporal rece-
bida para calcular o conjunto de dados para o modelo do grfco.
Por fm, ainda precisaremos de ummtodo getModeloGrafico que devolver o modelo para o ArgentumBean,
j que o componente p:lineChart que precisar desse objeto preenchido. Repare que o retorno do tipo
ChartModel, super classe do CartesianChartModel. boa prtica deixar nossa classe a mais genrica possvel
para funcionar com qualquer tipo de mtodo.
Evvvc1:vv Jnvn: nvv:nn-sv n on)v1os vvtn scn :N1vnvncv
O item do Efective Java discorre sobre preferir referenciar objetos pela sua interface, em vez
de pelo seu prprio exato, sempre que este for relevante para o restante do sistema.
O livro tambm menciona que, na falta de uma interface adequada, uma superclasse pode ser
utilizada, o que nosso caso com a superclasse abstrata ChartModel. Referir-se a um objeto da
forma mais genrica possvel uma boa ideia, j que isso faz comque futuras mudanas limitem-
se ao mximo classe que as encapsula.
Veja como fca o programa dentro do ArgentumBean e note que essa classe apenas delega para a outra toda
a parte de criao do grfco:
public class ArgentumBean {
private List<Negociacao> negociacoes;
private String indicadorBase;
private String media;
private ChartModel modeloGrafico;
public ArgentumBean() {
this.negociacoes = new ClienteWebService().getNegociacoes();
List<Candle> candles = new CandleFactory().constroiCandles(negociacoes);
SerieTemporal serie = new SerieTemporal(candles);
GeradorModeloGrafico geradorGrafico =
new GeradorModeloGrafico(serie, 2, serie.getUltimaPosicao());
geradorGrafico.plotaMediaMovelSimples();
this.modeloGrafico = geradorGrafico.getModeloGrafico();
Captulo - Grfcos interativos com Primefaces - Isolando a API do Primefaces: baixo acoplamento - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
}
public List<Negociacao> getNegociacoes() {
return negociacoes;
}
public ChartModel getModeloGrafico() {
return modeloGrafico;
}
}
Note que, para quemusa o GeradorModeloGrafico nemd para saber como ele gera o modelo. um cdigo
encapsulado, fexvel, pouco acoplado e elegante: usa boas prticas da Orientao a Objetos.
. Pnnn snnvn mn:s: Dvs:cN Pn11vnNs Fnc1onv Mv1noo v Bc:t-
ovn
Dois famosos design patterns do GoF so o Factory Method e o Builder -- e estamos usando ambos. Eles
so chamados de padres de criao (creational patterns), pois nos ajudam a criar objetos complicados.
Afactory usada pelo GeradorDeSerie dos testes. Aideia que criar umobjeto SerieTemporal diretamente
complicado. Ento criaram um mtodo de fbrica que encapsula essas complicaes e j devolve o objeto
prontinho para uso.
O padro Builder o que estamos usando na classe GeradorModeloGrafico. Queremos encapsular a criao
complicada do modelo e que pode mudar depois com o tempo. Entra a o objeto construtor da nossa classe
Builder: seu nico objetivo descrever os passos para criao do nosso objeto fnal (o grfco) e encapsular
a complexidade disso.
Leia mais sobre esses e outros Design Patterns no livro do GoF.
Captulo - Grfcos interativos com Primefaces - Para saber mais: Design Patterns Factory Method e Builder - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
JFnvvCnnn1
O JFreeChart uma biblioteca famosa para desenho de grfcos, independente da tecnologia
JSF. um projeto de sofware livre iniciado em e que tem ampla aceitao pelo mercado,
funcionando at em ambientes antigos que rodam Java ..
Alm do fato de ser livre, possui a vantagem de ser bastante robusta e fexvel. possvel us-la
para desenhar grfcos de pontos, de barra, de torta, de linha, grfcos fnanceiros, gantt charts,
em D ou D e muitos outros. Consegue dar sada em JPG, PNG, SVG, EPS e at mesmo exibir
em componentes Swing.
O site ofcial possui links para download, demos e documentao:
http://www.jfree.org/jfreechart/
Existe um livro ofcial do JFreeChart escrito pelos desenvolvedores com exemplos e explicaes
detalhadas de vrios grfcos diferentes. Ele pago e pode ser obtido no site ofcial. Alm disso,
h muitos tutoriais gratuitos na internet.
. Exvncc:os: GnKv:cos comPn:mvvncvs
) Dentro da pasta src/main/java crie a classe GeradorModeloGrafico no pacote
br.com.caelum.argentum.grafico para encapsular a criao do modelo do grfco.
Use os recursos do Eclipse para escrever esse cdigo! Abuse do ctrl + espao, do ctrl + 1 e do ctrl
+ shift + O.
public class GeradorModeloGrafico {
// atributos: serie, comeco, fim e grafico
// (todos gerados com ctrl + 1, conforme voc criar o construtor)
// importe as classes com ctrl + shift + O
Captulo - Grfcos interativos com Primefaces - Exerccios: Grfcos com Primefaces - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public GeradorModeloGrafico(SerieTemporal serie, int comeco, int fim) {
this.serie = serie;
this.comeco = comeco;
this.fim = fim;
this.modeloGrafico = new CartesianChartModel();
}
public void plotaMediaMovelSimples() {
MediaMovelSimples indicador = new MediaMovelSimples();
LineChartSeries chartSerie = new LineChartSeries("MMS - Fechamento");
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSerie.set(i, valor);
}
this.modeloGrafico.addSeries(chartSerie);
}
public ChartModel getModeloGrafico() {
return this.modeloGrafico;
}
}
) Agora que j temos uma classe que criar o modelo do grfco, falta us-la para renderizar o grfco na
tela usando a tag do Primefaces. Abra a pgina index.xhtml que se encontra na pasta WebContent.
Na pgina procure o componente h:body. Logo depois da abertura da tag h:body e antes do h:form da
lista de negociaes, adicione o componente p:lineChart:
<p:lineChart value="#{argentumBean.modeloGrafico}"
legendPosition="w" title="Indicadores"/>
Salve a pgina. Reinicie o Tomcat e acesse emseu navegador: http://localhost:/f-argentum-web/index.
xhtml
Captulo - Grfcos interativos com Primefaces - Exerccios: Grfcos com Primefaces - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Na classe ArgentumBean, procure o construtor. nele que criaremos uma SerieTemporal baseada na lista
de negociaes do Web Service. Depois usaremos o GeradorModeloGrafico para criar o modelo grfco:
public ArgentumBean() {
this.negociacoes = new ClienteWebService().getNegociacoes();
List<Candle> candles = new CandleFactory().constroiCandles(negociacoes);
SerieTemporal serie = new SerieTemporal(candles);
GeradorModeloGrafico geradorGrafico =
new GeradorModeloGrafico(serie, 2, serie.getUltimaPosicao());
geradorGrafico.plotaMediaMovelSimples();
this.modeloGrafico = geradorGrafico.getModeloGrafico();
}
) Voc deve estar vendo um erro de compilao na ltima linha do seu construtor. Ele acontece porque
faltou criarmos um novo atributo que representa o modelo do grfco. Use o ctrl + para criar o atributo
e, ao mesmo tempo, fazer o import da classe.
private ChartModel modeloGrafico;
Gere tambm o getter para este atributo, para que o componente p:lineChart consiga pegar o modelo
do grfco quando necessitar.
Para isso, na classe ArgentumBean, escreva getM e aperte ctrl + espao. O Eclipse sugerir o getter para o
atributo modeloGrafico.::
Captulo - Grfcos interativos com Primefaces - Exerccios: Grfcos com Primefaces - Pgina
C
Aplicando Padres de projeto
Estamos todos na sarjeta, mas alguns de ns esto olhando para as estrelas.
Oscar Wilde
. Nossos :No:cnoonvs v o ovs:cN vn11vnN S1nn1vcv
Nosso gerador de grfcos j est interessante, mas no momento ele s consegue plotar a Mdia Mvel Simples
do fechamento da srie. Nosso cliente certamente precisar de outros indicadores tcnicos como o de Mdia
Mvel Ponderada ou ainda indicadores mais simples como os de Abertura ou de Fechamento.
Esses indicadores, similarmente MediaMovelSimples, devem calcular o valor de uma posio do grfco
baseado na SerieTemporal que ele atende.
Se tivermos esses indicadores todos, precisaremos que o GeradorModeloGrafico consiga plotar cada umdes-
ses grfcos. Terminaremos com uma crescente classe GeradorModeloGrafico com mtodos extremamente
parecidos:
public class GeradorModeloGrafico {
//...
public void plotaMediaMovelSimples() {
MediaMovelSimples indicador = new MediaMovelSimples();
LineChartSeries chartSerie = new LineChartSeries("MMS - Fechamento");
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSerie.set(i, valor);
}
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
this.modeloGrafico.addSeries(chartSerie);
}
public void plotaMediaMovelPonderada() {
MediaMovelPonderada indicador = new MediaMovelPonderada();
LineChartSeries chartSerie = new LineChartSeries("MMP - Fechamento");
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSerie.set(i, valor);
}
this.modeloGrafico.addSeries(chartSerie);
}
//...
}
Oproblema que cada vez que criarmos umindicador tcnico diferente, umnovo mtodo dever ser criado
na classe GeradorModeloGrafico. Isso uma indicao clssica de acoplamento no sistema.
Como resolver esses problemas de acoplamento e de cdigo parecidssimo nos mtodos? Ser que consegui-
mos criar um nico mtodo para plotar e passar como argumento qual indicador tcnico queremos plotar
naquele momento?
Note que a diferena entre os mtodos est apenas no new do indicador escolhido e na legenda do grfco. O
restante precisamente igual.
A orientao a objetos nos d a resposta: polimorfsmo! Repare que nossos dois indicadores possuem a
mesma assinatura de mtodo, parece at que eles assinaram o mesmo contrato. Vamos defnir ento a inter-
face Indicador:
Captulo - Aplicando Padres de projeto - Nossos indicadores e o design pattern Strategy - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public interface Indicador {
public abstract double calcula(int posicao, SerieTemporal serie);
}
Podemos fazer as classes MediaMovelSimples e MediaMovelPonderada implementarem a interface
Indicador. Com isso, podemos criar apenas um mtodo na classe do grfco que recebe um Indicador
qualquer. O objeto do indicador ser responsvel por calcular o valor no ponto pedido (mtodo calcula) e,
tambm, pela legenda do grfco (mtodo toString)
public class GeradorModeloGrafico {
public void plotaIndicador(Indicador indicador) {
LineChartSeries chartSerie = new LineChartSeries(indicador.toString());
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSeries.set(i, valor);
}
this.modeloGrafico.addSeries(chartSeries);
}
}
Na hora de desenhar os grfcos, chamaremos sempre o plotaIndicador, passando como parmetro qual-
quer classe que seja um Indicador:
GeradorModeloGrafico gerador = new GeradorModeloGrafico(serie, 2, 40);
gerador.plotaIndicador(new MediaMovelSimples());
gerador.plotaIndicador(new MediaMovelPonderada());
A ideia de usar uma interface comum ganhar polimorfsmo e poder trocar os indicadores. Nosso mtodo
plota qualquer Indicador, isto , quando criarmos ou removermos uma implementao de indicador, no
precisaremos mexer no GeradorModeloGrafico: ganhamos fexibilidade e aumentamos a coeso. Podemos
ainda criar novos indicadores que implementem a interface e pass-los para o grfco sem que nunca mais
mexamos na classe GeradorModeloGrafico.
Por exemplo, imagine que queremos um grfco simples que mostre apenas os preos de fechamento. Pode-
mos considerar a evoluo dos preos de fechamento como um Indicador:
public class IndicadorFechamento implements Indicador {
public double calcula(int posicao, SerieTemporal serie) {
return serie.getCandle(posicao).getFechamento();
}
}
Captulo - Aplicando Padres de projeto - Nossos indicadores e o design pattern Strategy - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Ou criar ainda classes como IndicadorAbertura, IndicadorMaximo, etc.
Temos agora vrios indicadores diferentes, cada um com sua prpria estratgia de clculo do valor, mas
todos obedecendo a mesma interface: dada uma srie temporal e a posio a ser calculada, eles devolvem
o valor do indicador. Note que o plotaIndicador no recebe dados, mas sim a forma de manipular esses
dados, a estratgia para trat-los. Esse o design pattern chamado de Strategy.
Dvs:cN Pn11vnNs
Design Patterns so aquelas solues catalogadas para problemas clssicos de orientao a ob-
jetos, como este que temos no momento: encapsular e ter fexibilidade.
A fbrica de Candles apresentada em outro captulo e o mtodo que nos auxilia a criar sries
para testes na GeradorDeSerie so exemplos, respectivamente, dos padres Abstract Factory e
Factory Method. No caso que estamos estudando agora, o Strategy est nos ajudando a deixar a
classe GeradorModeloGrafico isolada das diferentes formas de clculo dos indicadores.
. Exvncc:os: nvvn1onnNoo vnnn cmn :N1vnvncv v csnNoo
nvmos 1vs1vs
) J que nossas classes de mdias mveis so indicadores tcnicos, comearemos extraindo a interface de
um Indicador a partir dessas classes.
Abra a classe MediaMovelSimples e use o ctrl + Extract interface. Selecione o mtodo calcula e d o
nome da interface de Indicador:
Ateno: A interface deve fcar dentro do pacote br.com.caelum.argentum.indicadores:
Captulo - Aplicando Padres de projeto - Exerccios: refatorando para uma interface e usando bem os testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Evvvc1:vv Jnvn
Item : Refra a objetos pelas suas interfaces
) Na classe MediaMovelPonderada coloque agora o implements Indicador nela.
public class MediaMovelPonderada implements Indicador {
...
}
) Vamos criar tambm uma classe para, por exemplo, ser o indicador do preo de fechamento, o
IndicadorFechamento, no pacote br.com.caelum.argentum.indicadores, que implementa a interface
Indicador.
Note que, ao adicionar o trecho implements Indicador classe, o Eclipse mostra umerro de compilao.
Usando o ctrl + , escolha a opo Add unimplemented methods para que ele crie toda a assinatura do
mtodo calcula.
No fnal, faltar preencher apenas a linha destacada:
public class IndicadorFechamento implements Indicador {
@Override
public double calcula(int posicao, SerieTemporal serie) {
return serie.getCandle(posicao).getFechamento();
}
}
) De maneira anloga vamos criar o IndicadorAbertura, tambm no pacote
br.com.caelum.argentum.indicadores, que implementa a interface Indicador:
Captulo - Aplicando Padres de projeto - Exerccios: refatorando para uma interface e usando bem os testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public class IndicadorAbertura implements Indicador {
@Override
public double calcula(int posicao, SerieTemporal serie) {
return serie.getCandle(posicao).getAbertura();
}
}
) Volte para a classe GeradorModeloGrafico e altere o mtodo plotaMediaMovelSimples usando o atalho
alt + shif + C. Voc precisar alterar o nome para plotaIndicador e adicionar um parmetro. Veja com
ateno o screenshot abaixo:
Ignore o erro e, quando essa refatorao terminar, remova a linha que declarava o indicador. Seu mtodo
terminar assim:
public void plotaIndicador(Indicador indicador) {
LineChartSeries chartSeries = new LineChartSeries(indicador.toString());
for (int i = comeco; i <= fim; i++) {
double valor = indicador.calcula(i, serie);
chartSeries.set(i, valor);
}
modeloGrafico.addSeries(chartSeries);
}
) Repare que estamos chamando o mtodo toString() do indicador no mtodo plotaIndicador(). Va-
mos sobrescrev-lo em todos os indicadores criados.
Sobrescreva na classe MediaMovelSimples:
Captulo - Aplicando Padres de projeto - Exerccios: refatorando para uma interface e usando bem os testes - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
public class MediaMovelSimples implements Indicador{
// mtodo calcula
public String toString() {
return "MMS de Fechamento";
}
}
Sobrescreva na classe MediaMovelPonderada:
public class MediaMovelPonderada implements Indicador{
// mtodo calcula
public String toString() {
return "MMP de Fechamento";
}
}
Tambm na classe IndicadorFechamento:
public class IndicadorFechamento implements Indicador {
// mtodo calcula
public String toString() {
return "Fechamento";
}
}
E por ltimo na classe IndicadorAbertura:
public class IndicadorAbertura implements Indicador {
// mtodo calcula
public String toString() {
return "Abertura";
}
}
. Exvncc:os ovc:oNn:s
) Nossos clculos de mdias mveis so sempre para o intervalo de dias. Faa com que o intervalo seja
parametrizvel. As classes devem receber o tamanho desse intervalo no construtor e usar esse valor no
algoritmo de clculo.
No esquea de fazer os testes para essa nova verso e alterar os testes j existentes para usar esse clculo
novo. Os testes j existentes que fcarem desatualizados aparecero com erros de compilao.
Captulo - Aplicando Padres de projeto - Exerccios opcionais - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Toda refatorao deve ser acompanhada dos testes para garantir que no quebramos nada! Rode os testes
e veja se as mudanas feitas at agora mudaram o comportamento do programa.
Se voc julgar necessrio, acrescente mais testes sua aplicao refatorada.
. INo:cnoonvs mn:s vtnnonnoos v o Dvs:cN Pn11vnN Dvco-
nn1on
Vimos no captulo de refatorao que os analistas fnanceiros fazemsuas anlises sobre indicadores mais ela-
borados, como por exemplo Mdias Mveis, que so calculadas a partir de outros indicadores. No momento,
nossos algoritmos de mdias mveis sempre calculam seus valores sobre o preo de fechamento. Mas, e se
quisermos calcul-las a partir de outros indicadores? Por exemplo, o que faramos se precisssemos da mdia
mvel simples do preo mximo, da abertura ou de outro indicador qualquer?
Criaramos classes como MediaMovelSimplesAbertura e MediaMovelSimplesMaximo? Que cdigo colo-
caramos l? Provavelmente, copiaramos o cdigo que j temos e apenas trocaramos a chamada do
getFechamento pelo getAbertura e getMaximo.
A maior parte do cdigo seria a mesma e no estamos reaproveitando cdigo - copiar e colar cdigo no
reaproveitamento, uma forma de nos dar dor de cabea no futuro ao ter que manter cdigos idnticos em
lugares diferentes.
Queremos calcular mdias mveis de fechamento, abertura, volume, etc, sem precisar copiar essas classes de
mdia. Na verdade, o que queremos calcular a mdia mvel baseado em algum outro indicador. J temos
a classe IndicadorFechamento e trivial implementar outros como IndicadorAbertura, IndicadorMinimo,
etc.
A MediaMovelSimples um Indicador que vai depender de algum outro Indicador para ser calculada (por
exemplo o IndicadorFechamento). Queremos chegar em algo assim:
MediaMovelSimples mms = new MediaMovelSimples(new IndicadorFechamento());
// ou...
MediaMovelSimples mms = new MediaMovelPonderada(new IndicadorFechamento());
Repare na fexibilidade desse cdigo. Oclculo de mdia fca totalmente independente do dado usado e, toda
vez que criarmos um novo indicador, j ganhamos a mdia mvel desse novo indicador de brinde. Vamos
fazer ento nossa classe de mdia receber algum outro Indicador:
public class MediaMovelSimples implements Indicador {
private final Indicador outroIndicador;
public MediaMovelSimples(Indicador outroIndicador) {
Captulo - Aplicando Padres de projeto - Indicadores mais elaborados e o Design Pattern Decorator - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
this.outroIndicador = outroIndicador;
}
// ... calcula ...
}
E, dentro do mtodo calcula, em vez de chamarmos o getFechamento, delegamos a chamada para o
outroIndicador:
@Override
public double calcula(int posicao, SerieTemporal serie) {
double soma = 0.0;
for (int i = posicao; i > posicao - 3; i--) {
soma += outroIndicador.calcula(i, serie);
}
return soma / 3;
}
Nossa classe MediaMovelSimples recebe um outro indicador que modifca um pouco os valores de sada -
ele complementa o algoritmo da mdia! Passar um objeto que modifca um pouco o comportamento do seu
uma soluo clssica para ganhar em fexibilidade e, como muitas solues clssicas, ganhou um nome
nos design patterns de Decorator.
Tnmnvmv cmcomvos:1v:
Note que, agora, nossa MediaMovelSimples umIndicador e tambmtemumoutro Indicador.
J vimos antes outro tipo que se comporta da mesma forma, voc se lembra?
Assimcomo os componentes do Swing, nossa MediaMovelSimples se tornou tambmumexem-
plo de Composite.
. Exvncc:os: INo:cnoonvs mn:s vsvvn1os v oDvs:cNPn11vnN
Dvconn1on
) Faremos uma grande mudana agora: nossas mdias devemreceber como argumento umoutro indicador,
formando o design pattern Decorator, como visto na explicao.
Para isso, crie o construtor padro (sem parmetros) da MediaMovelSimples usando o atalho de sua pre-
ferncia:
a) Comece a escrever o nome da classe e mande autocompletar: Med<ctrl + espao>;
b) Use o criador automtico de construtores: ctrl + Constructor.
Captulo - Aplicando Padres de projeto - Exerccios: Indicadores mais espertos e o Design Pattern Decorator - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Modifque o construtor usando o atalho alt + shif + C para adicionar o parmetro do tipo Indicador
chamado outroIndicador e com valor padro new IndicadorFechamento().
Agora, com o cursor sobre o parmetro outroIndicador, faa ctrl + e guarde esse valor em um novo
atributo, selecionando assign parameter to new feld.
) Troque a implementao do mtodo calcula para chamar o calcula do outroIndicador:
public double calcula(int posicao, SerieTemporal serie) {
double soma = 0.0;
for (int i = posicao; i > posicao - 3; i--) {
soma += outroIndicador.calcula(i, serie);
}
return soma / 3;
}
) Lembre que toda refatorao deve ser acompanhada dos testes correspondentes. Mas ao usar a refatorao
do Eclipse no construtor da nossa classe MediaMovelSimples, a IDE evitou que quebrssemos os testes j
passando o IndicadorFechamento como parmetro padro para todos eles!
Agora, rode os testes novamente e tudo deve continuar se comportando exatamente como antes da refa-
torao. Caso contrrio, nossa refatorao no foi bem sucedida e seria bom reverter o processo todo.
) Modifque tambm a classe MediaMovelPonderada para tambm ter um Decorator.
Isto , faa ela tambm receber um outroIndicador no construtor e delegar a chamada a esse indicador
no seu mtodo calcula, assim como fzemos com a MediaMovelSimples.
Captulo - Aplicando Padres de projeto - Exerccios: Indicadores mais espertos e o Design Pattern Decorator - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) (opcional)Faa um teste de unidade na classe MediaMovelSimplesTest que use receba um
IndicadorAbertura vez do de fechamento. Faa tambm para quaisquer outros indicadores que
voc crie.
Captulo - Aplicando Padres de projeto - Exerccios: Indicadores mais espertos e o Design Pattern Decorator - Pgina
C
A API de Refection
At agora, ao acessar a aplicao pelo navegador, o grfco e a tabela de negociaes sero gerados automa-
ticamente. No h nenhuma forma de personalizar o grfco, como por exemplo a opo de ver apenas um
dos indicadores por vez.
Vamos melhorar a interface e adicionar um formulrio que oferece para o usurio as seguintes opes:
Tipo de indicador (abertura ou fechamento)
Tipo de mdia (mvel simples ou mvel ponderada)
. EscotnvNoo qcnt cnKv:co vto1nn
Nesse momento, apesar de conseguirmos compor diversos indicadores e plotar seus grfcos, o Argentum
apenas consegue mostrar o grfco da Mdia Mvel Simples do Fechamento. No entanto, ns j preparamos
diversos outros indicadores e poderamos plotar todos eles naquele mesmo grfco. O resultado disso seria
algo assim:
H informao demais nesse grfco e isso o torna menos til. Seria muito mais interessante se o usurio
pudesse escolher quais indicadores ele quer ver e mandar plotar apenas estes no grfco. Uma das formas
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
possveis para isso seria colocarmos as opes para que ele decida e um boto que disparar a gerao do
grfco. Nossa tela fcar parecida com:
Parece bom? Felizmente, colocar tais botes na tela uma tarefa bastante simples! Como diversas aplicaes
tm a necessidade desses botes, esses componentes j existem e us-los ser bem semelhante ao que j
vnhamos fazendo desde nossos primeiros exemplos com JSF.
Tais componentes so, inclusive, to comuns que existem tanto na implementao do JSF quanto no Prime-
faces e nas outras bibliotecas semelhantes. Esse um dilema comum quando trabalhamos com JSF: usar a
implementao padro ou a do Primefaces.
Essa escolha usualmente cai para a utilizao da biblioteca, j que seus componentes j vm com um estilo
uniforme e, como j vimos antes, frequentemente adicionamfuncionalidades interessantes aos componentes.
Sabendo disso, daremos preferncia para os componentes do Primefaces, embora isso traga alguns efeitos
colaterais. Fique atento s particularidades em destaque no decorrer desse captulo.
ComvoNvN1vs vnnn vscotnvn o cnKv:co
Para que o usurio escolha qual grfco ele quer plotar, ser necessrio que ele consiga interagir com a tela,
isto , precisamos de um componente de input de dados. H diversos deles disponveis no Primefaces: http:
//www.primefaces.org/showcase/ui/home.jsf
Como temos opes pr-defnidas para as mdias e para os indicadores bsicos, usaremos um componente
de select. Voc pode descobr-los at de dentro do Eclipse, no index.xhtml: basta abrir a tag <p:select e
usar o ctrl + espao!
Para replicar a tela do screenshot acima, usaremos o componente com cara de boto que permite escolher
apenas uma opo, o p:selectOneButton. E, como qualquer select, precisamos tambm indicar quais so
os itens que serviro de opo.
<h:outputLabel value="Media Mvel: "/>
<p:selectOneButton value="#{argentumBean.nomeMedia}">
<f:selectItem itemLabel="Simples" itemValue="MediaMovelSimples" />
<f:selectItem itemLabel="Ponderada" itemValue="MediaMovelPonderada" />
</p:selectOneButton>
Captulo - A API de Refection - Escolhendo qual grfco plotar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Marcamos, atravs do value, que esse componente est ligado ao atributo nomeMedia da classe ArgentumBean.
Quando o usurio escolher o boto desejado, o itemValue ser atribudo a esse atributo.
Semelhantemente, queremos outra listagem de indicadores possveis, mas agora com nossos indicadores
bsicos:
<h:outputLabel value="Indicador base: "/>
<p:selectOneButton value="#{argentumBean.indicadorBase}">
<f:selectItem itemLabel="Abertura" itemValue="IndicadorAbertura" />
<f:selectItem itemLabel="Fechamento" itemValue="IndicadorFechamento" />
</p:selectOneButton>
Finalmente, tambmprecisamos que o usurio indique que terminou de escolher e mande efetivamente gerar
tal grfco. E a forma mais natural de fazer isso atravs de um boto com uma determinada ao -- em
outras palavras, a action desse componente indica o mtodo que ser chamado quando o usurio apertar o
boto:
<p:commandButton value="Gerar grfico"
action="#{argentumBean.geraGrafico}"/>
Note que esse boto do Primefaces muito mais atraente do que o boto padro que usamos no
olaMundo.xhtml. A folha de estilos do Primefaces realmente superior, mas no s isso que muda!
PoN1o ov n1vNXo: Pn:mvvncvs v o AJAX
Os botes do Primefaces no so apenas bonitos. Eles tambm trabalham por padro com cha-
madas via AJAX, em vez de recarregar a tela toda. Isso interessante quando temos telas com-
plexas, com diversas informaes e o apertar de um boto altera somente um pedao dela.
Contudo, exatamente porque nossa chamada ser executada via AJAX, no haver navegao e
os outros componentes da tela no sero recarregados, a menos que explicitamente indiquemos
que tal boto deve recarregar um componente.
No nosso caso, queremos que apertar boto Gerar grfco regere o modelo do grfco e recarregue tal com-
ponente na tela, ento ainda necessrio alterar o p:commandButton para que ele atualize o grfco. Para isso,
precisamos indicar ao boto que ele ser tambm responsvel por atualizar o componente do grfco. Para
ligar um componente ao outro, usaremos um id.
<p:commandButton value="Gerar grfico" update=":grafico"
action="#{argentumBean.geraGrafico}"/>
Note o : (dois pontos). Isso indica para o boto que ele partir da tag raiz da pgina procurando algum
componente com id grafico. E, para que isso funcione, tambm necessrio que o componente do grfco
tenha tal id.
Captulo - A API de Refection - Escolhendo qual grfco plotar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
<p:lineChart value="#{argentumBean.modeloGrafico}" id="grafico"
legendPosition="w" title="Indicadores"/>
Lembre-se tambm que sempre que temos botes, precisamos que eles estejam dentro de um componente
h:form. Fora deste componente, os botes no funcionam. Outro detalhe aqui que, por padro, o Pri-
mefaces coloca cada label, select e boto em uma linha. Esse comportamento timo para formulrios mais
padro, mas se quisermos mostrar tudo emuma linha s ainda podemos utilizar umpanelGrid com colunas
para acomodar os componentes desse menu.
<h:form>
<h:panelGrid columns="5">
<h:outputLabel value="Media Mvel: "/>
<p:selectOneButton value="#{argentumBean.nomeMedia}">
<f:selectItem itemLabel="Simples" itemValue="MediaMovelSimples" />
<f:selectItem itemLabel="Ponderada" itemValue="MediaMovelPonderada" />
</p:selectOneButton>
<h:outputLabel value="Indicador base: "/>
<p:selectOneButton value="#{argentumBean.nomeIndicadorBase}">
<f:selectItem itemLabel="Abertura" itemValue="IndicadorAbertura" />
<f:selectItem itemLabel="Fechamento" itemValue="IndicadorFechamento"/>
</p:selectOneButton>
<p:commandButton value="Gerar grfico" update=":grafico"
action="#{argentumBean.geraGrafico}"/>
</h:panelGrid>
</h:form>
E o MnNncvoBvnN:
Semelhantemente proposta do JSF, focamos apenas nos novos componentes e todas as alteraes propostas
nesse captulo esto limitadas a alteraes no index.xhtml.
Se repararmos bem, contudo, os novos componentes exigiro mudanas considerveis ao ArgentumBean:
Atributo nomeMedia, seu getter e setter;
Atributo nomeIndicadorBase, seu getter e setter;
Mtodo geraGrafico, que ser o novo responsvel pelo modelo do grfco.
Faremos tais alteraes no decorrer do prximo exerccio.
Captulo - A API de Refection - Escolhendo qual grfco plotar - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. Exvncc:os: vvnm:1:Noo qcv o cscKn:o vscotnn o cnKv:co
) No index.html e logo aps a tag <h:body>, adicione o formulrio que permitir que o usurio escolha
qual indicador ele gostaria de ver plotado e tambm o panelGrid que far com que seu formulrio ocupe
apenas uma linha.
<h:form>
<h:panelGrid columns="5">
</h:panelGrid>
</h:form>
) Agora, dentro do h:panelGrid, precisamos colocar nossos selects das mdias e dos indicadores bsicos,
juntamente com as respectivas legendas dos campos:
<h:outputLabel value="Media Mvel: "/>
<p:selectOneButton value="#{argentumBean.nomeMedia}">
<f:selectItem itemLabel="Simples" itemValue="MediaMovelSimples" />
<f:selectItem itemLabel="Ponderada" itemValue="MediaMovelPonderada" />
</p:selectOneButton>
<h:outputLabel value="Indicador base: "/>
<p:selectOneButton value="#{argentumBean.nomeIndicadorBase}">
<f:selectItem itemLabel="Abertura" itemValue="IndicadorAbertura" />
<f:selectItem itemLabel="Fechamento" itemValue="IndicadorFechamento"/>
</p:selectOneButton>
) Suba o TomCat agora e verifque que recebemos uma ServletException. Ela nos informa que ainda no
temos a propriedade nomeMedia no ArgentumBean. Precisamos criar os atributos necessrios para que
esses componentes funcionem corretamente.
Na classe ArgentumBean crie os atributos nomeMedia e nomeIndicadorBase e seus respectivos getters e
setters. Lembre-se de usar o ctrl + getter para isso!
@ManagedBean
@ViewScoped
public class ArgentumBean {
private List<Negociacao> negociacoes;
private ChartModel modeloGrafico;
private String nomeMedia;
private String nomeIndicadorBase;
// agora crie os getters e setters com o ctrl+3
Ateno: se seu ArgentumBean no estiver anotado com @ViewScoped, anote-o. A explicao dos escopos
est no exerccio opcional de paginao e ordenao, no captulo de Introduo ao JSF.
Captulo - A API de Refection - Exerccios: permitindo que o usurio escolha o grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Reinicie o TomCat e veja os selects na tela. Falta pouco! De volta ao index.xhtml coloque o boto no
mesmo formulrio, logo aps os selects. Coloque tambm o id=grafico no componente p:lineChart
que j existe, para fazer com que o clique no boto atualize tambm esse componente.
<p:commandButton value="Gerar grfico" update=":grafico"
action="#{argentumBean.geraGrafico}"/>
</h:panelGrid>
</h:form>
<p:lineChart value="#{argentumBean.modeloGrafico}" id="grafico"
legendPosition="w" title="Indicadores"/>
) J possvel ver a tela, mas ao clicar no boto de gerar o grfco, nada acontece. Na verdade, no Console do
Eclipse possvel ver que uma exceo foi lanada porque o mtodo que o boto chama, o geraGrafico,
ainda no existe.
Esse mtodo ter que, a partir da lista de negociaes, criar as Candles, a Srie Temporal, mandar plotar
um indicador ao grfco e disponibilizar o modelo atualizado para o grfco. Note, no entanto, que nosso
construtor j faz todo esse trabalho!
Basta fazermos uma simples refatorao Extract method nessas linhas! Selecione tais linhas do construtor
da ArgentumBean e use ctrl + extract method indicando que o novo mtodo deve se chamar geraGrafico
e deve ser pblico.
Captulo - A API de Refection - Exerccios: permitindo que o usurio escolha o grfco - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Finalmente, para verifcarmos que estamos recebendo informaes corretas sobre qual indicador plotar
no momento que o mtodo geraGrafico chamado, vamos imprimir essas informaes no console com
um simples syso.
Altere o recm-criado geraGrafico, adicionando o syso:
public void geraGrafico() {
System.out.println("PLOTANDO: " + nomeMedia + " de " + nomeIndicadorBase);
List<Candle> candles = new CandleFactory().constroiCandles(negociacoes);
//...
) Reinicie o TomCat e volte a acessar a URL do projeto: http://localhost:/f-argentum-web/index.xhtml
Teste os botes e mande gerar o grfco. Ateno! O grfco ainda no ser gerado corretamente! Falta
implementarmos essa parte no bean. Olhando no Console do Eclipse, contudo, note que nosso syso j
mostra que os atributos que escolhero qual indicador plotar j foi escolhido corretamente!
Faa o teste para algumas combinaes de mdia e indicador, observando o console.
. MoN1nNoo os :No:cnoonvs o:Nnm:cnmvN1v
No nosso formulrio criamos dois select buttons, um para a mdia e outro para o indicador base. Ns at j
verifcamos que essas informaes esto sendo preenchidas corretamente quando o usurio clica no boto.
No entanto, ainda no estamos usando essa informao para plotar o indicador escolhido pelo usurio -
ainda estamos plotando a mdia mvel simples do fechamento em todos os casos. Essa informao est
hard-coded no geraGrafico
public void geraGrafico() {
System.out.println("PLOTANDO: " + nomeMedia + " de " + nomeIndicadorBase);
List<Candle> candles = new CandleFactory().constroiCandles(negociacoes);
SerieTemporal serie = new SerieTemporal(candles);
GeradorModeloGrafico geradorGrafico =
new GeradorModeloGrafico(serie, 2, serie.getUltimaPosicao());
geradorGrafico.plotaIndicador(
new MediaMovelSimples(new IndicadorFechamento()));
this.modeloGrafico = geradorGrafico.getModeloGrafico();
}
Note que as informaes de qual indicador ousurio quer plotar j esto preenchidas nos atributos nomeMedia
e nomeIndicadorBase, mas esses atributos so meramente Strings passadas pelo componente de select.
Poderamos, ento, usar um conjunto de if/else para decidir qual indicador usar:
Captulo - A API de Refection - Montando os indicadores dinamicamente - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
private Indicador defineIndicador() {
if ("MediaMovelSimples".equals(nomeMedia)) {
if ("IndicadorAbertura".equals(nomeIndicadorBase))
return new MediaMovelSimples(new IndicadorAbertura());
if ("IndicadorFechamento".equals(nomeIndicadorBase))
return new MediaMovelSimples(new IndicadorFechamento());
} else if ("MediaMovelPonderada".equals(nomeMedia)) {
// varios outros ifs
fcil ver que essa uma soluo extremamente deselegante. Nesse pequeno trecho escrevemos quatro ifs
e isso um sinal de mal design. Pense agora no teste para esse trecho de cdigo: esse mtodo sozinho tem
quatro caminhos possveis de se percorrer. Esse nmero tambm chamado de complexidade ciclomtica.
Quatro no um nmero ruim, mas note que, ao adicionar um novo indicador bsico ou uma nova
mdia, esse nmero aumentar de forma multiplicativa. O nmero de caminhos ser sempre igual
quantidadeDeMedias * quantidadeDeIndicadoresBase.
Comvtvx:onov C:ctomK1:cn
Essa mtrica expe o nmero de caminhos diferentes que uma execuo pode percorrer em um
mtodo. O problema de uma complexidade ciclomtica alta que: quanto maior esse nmero
for, mais testes sero necessrios para garantir o funcionamento esperado.
Para maiores detalhes sobre essa mtrica consulte no blog da caelum esse artigo: http://blog.
caelum.com.br/medindo-a-complexidade-do-seu-codigo/
Cnon vvz mn:s :No:cnoonvs
Por vantagem competitiva, nosso cliente pode pedir mais indicadores (mnimo e mximo) e outras mdias
(exponencial e adaptativa). sensvel que o cdigo nunca parar de crescer e estar sempre sujeito a alterao.
Embora seja aceitvel para um nmero bem pequeno de indicadores, conforme nosso sistema evolui fun-
damental que encontremos um jeito melhor de conseguir um objeto de Indicador a partir das Strings que j
temos.
Nesse caso a API de refection cai com uma luva. Com ela podemos escrever o cdigo que cria objetos ou
chamar mtodos sem conhecer as classes antecipadamente, justamente o que precisamos para montar as
indicadores.
. IN1noocXo n Rvvtvc1:oN
Por ser uma linguagem compilada, Java permite que, enquanto escrevemos nosso cdigo, tenhamos total
controle sobre o que ser executado, de tudo que faz parte do nosso sistema. Emtempo de desenvolvimento,
Captulo - A API de Refection - Introduo a Refection - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
olhando nosso cdigo, sabemos quantos atributos uma classe tem, quais construtores e mtodos ela possui,
qual chamada de mtodo est sendo feita e assim por diante.
Mas existem algumas raras situaes onde essa garantia do compilador no nos ajuda. Isto , existem situ-
aes em que precisamos de caractersticas dinmicas. Por exemplo, imagine permitir que, dado um nome
de mtodo que o usurio passar, ns o invocaremos em um objeto. Ou ainda, que, ao recebermos o nome de
uma classe enquanto executando o programa, possamos criar um objeto dela!
Nas prximas sees, voc vai conhecer um pouco desse recurso avanado e muito poderoso que, embora
possua diversas qualidades, aumenta bastante a complexidade do nosso cdigo e por essa razo deve ser
usado de forma sensata.
. Pon qcv nvvtvc1:oN:
Um aluno que j cursou o FJ- pode notar uma incrvel semelhana com a discusso em aula sobre MVC,
onde, dado um parmetro da requisio, criamos um objeto das classes de lgica. Outro exemplo, j visto,
o do XStream: dado um XML, ele consegue criar objetos para ns e colocar os dados nos atributos dele.
Como ele faz isso? Ser que no cdigo-fonte do XStream acharamos algo assim:
Negociacao n = new Negociacao(...);
OXStreamfoi construdo para funcionar comqualquer tipo de XMLe objeto. Comumpouco de ponderao
fca bvio que no h um new para cada objeto possvel e imaginvel dentro do cdigo do XStream. Mas
como ele consegue instanciar um objeto da minha classe e popular os atributos, tudo sem precisar ter new
Negociacao() escrito dentro dele?
O java.lang.refect um pacote do Java que permite criar instncias e chamadas em tempo de execuo,
sem precisar conhecer as classes e objetos envolvidos no momento em que escrevemos nosso cdigo (tempo
de compilao). Esse dinamismo necessrio para resolvermos determinadas tarefas que s descobrimos
serem necessrias ao receber dados, isto , em tempo de execuo.
De volta ao exemplo do XStream, ele s descobre o nome da nossa classe Negociacao quando rodamos o
programa e selecionamos o XML a ser lido. Enquanto escreviam essa biblioteca, os desenvolvedores do
XStream no tinham a menor ideia de que um dia o usaramos com a classe Negociacao.
Apenas para citar algumas possibilidades com refection:
Listar todos os atributos de uma classe e pegar seus valores em um objeto;
Instanciar classes cujo nome s vamos conhecer em tempo de execuo;
Invocar um construtor especifco baseado no tipo de atributo
Invocar mtodos dinamicamente baseado no nome do mtodo como String;
Descobrir se determinados pedaos do cdigo tm annotations.
Captulo - A API de Refection - Por que refection? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
. CoNs1ncc1on, F:vto v Mv1noo
O ponto de partida da refection a classe Class. Esta, uma classe da prpria API do Java que representa
cada modelo presente no sistema: nossas classes, as que esto em JARs e tambm as do prprio Java. Atravs
da Class conseguimos obter informaes sobre qualquer classe do sistema, como seus atributos, mtodos,
construtores, etc.
Todo objeto tem um jeito fcil pegar o Class dele:
Negociacao n = new Negociacao();
// chamamos o getClass de Object
Class<Negociacao> classe = n.getClass();
Mas nem mesmo precisamos de um objeto para conseguir as informaes da sua classe. Diretamente com o
nome da classe tambm podemos fazer o seguinte:
Class<Negociacao> classe = Negociacao.class;
Ou ainda, se tivermos o caminho completo da classe, conseguimos recuperar tal classe at atravs de uma
String:
Class classe = Class.forName("br.com.caelum.argentum.model.Negociacao");
Jnvn v GvNvn:cs
A partir do Java , a classe Class tipada e recebe o tipo da classe que estamos trabalhando. Isso
melhora alguns mtodos, que antes recebiamObject e agora trabalhamcomumtipo T qualquer,
parametrizado pela classe.
A partir de um Class podemos listar, por exemplo, os nomes e valores dos seus atributos:
Class<Negociacao> classe = Negociacao.class;
for (Field atributo : classe.getDeclaredFields()) {
System.out.println(atributo.getName());
}
A sada ser:
preco
quantidade
data
Captulo - A API de Refection - Constructor, Field e Method - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Fazendo similarmente para os mtodos possvel conseguir a lista:
Class<Negociacao> classe = Negociacao.class;
for (Method metodo : classe.getDeclaredMethods()) {
System.out.println(metodo.getName());
}
Cuja sada ser:
getPreco
getQuantidade
getData
getVolume
isMesmoDia
Assim como podemos descobrir mtodos e atributos, o mesmo aplica para construtores. Para, por exemplo,
descobrir o construtor da classe MediaMovelSimples:
Class<MediaMovelSimples> classe = MediaMovelSimples.class;
Constructor<?>[] construtores = classe.getConstructors();
for (Constructor<?> constructor : construtores) {
System.out.println(Arrays.toString(constructor.getParameterTypes()));
}
Imprime o tipo do parmetro do nico construtor:
interface br.com.caelum.argentum.indicadores.Indicador
possvel fazer muito mais. Investigue a API de refection usando ctrl + espao a partir das classes Method,
Constructor e Fields no Eclipse e pelo JavaDoc.
. MvtnonnNoo Nosso AncvN1cmBvnN
J temos os conhecimentos necessrios para melhorar nosso mtodo defineIndicador(), que ser chamado
pelo geraGrafico. A primeira necessidade instanciar um Indicador a partir da String recebida. Mas antes
preciso descobrir a classe pela String e atravs do mtodo newInstance() instanciar um objeto da classe.
Isso se torna bastante fcil se convencionarmos que todo indicador estar no pacote
br.com.caelum.argentum.indicadores. Assim, instanciar o indicador base muito simples.
String pacote = "br.com.caelum.argentum.indicadores.";
Class<?> classeIndicadorBase = Class.forName(pacote + nomeIndicadorBase);
Indicador indicadorBase = (Indicador) classeIndicadorBase.newInstance();
Captulo - A API de Refection - Melhorando nosso ArgentumBean - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Para a mdia o trabalho um pouco maior, j que precisamos passar um Indicador como parmetro na
instanciao do objeto. Isso pode ser at mais complexo se houver outros indicadores na classe em questo.
Nesse caso, no basta fazer a chamada ao mtodo newInstance(), j que este s consegue instanciar objetos
quando o construtor padro existe.
Por outro lado, j sabemos como descobrir o construtor a partir de um Class. A boa notcia que existe
como criarmos uma instncia a partir de um Constructor, pelo mesmo mtodo newInstance() que passa a
receber parmetros.
Veja o cdigo:
Class<?> classeMedia = Class.forName(pacote + nomeMedia);
Constructor<?> construtorMedia = classeMedia.getConstructor(Indicador.class);
Indicador indicador = (Indicador) construtorMedia.newInstance(indicadorBase);
Repare que esse cdigo funciona com qualquer indicador ou mdia que siga a conveno de passar o nome
da classe no itemValue do select e a conveno de pacote.
Se errarmos alguma dessas informaes, no entanto, diversos erros podem acontecer e por isso que
o cdigo acima pode lanar diversas excees: InstantiationException, IllegalAccessException,
ClassNotFoundException, NoSuchMethodException, InvocationTargetException.
Como essas excees so todas checked, seria necessrio declar-las todas com um throws na assinatura do
mtodo defineIndicador, o que pode no ser desejvel. Podemos, ento, apelar para um try/catch que
encapsule tais excees em uma unchecked para que ela continue sendo lanada, mas no suje a assinatura
do mtodo com as tantas excees. Essa uma prtica um tanto comum, hoje em dia, e linguagens mais
novas chegam a nem ter mais as checked exceptions.
Nosso mtodo, portanto, fcar assim:
private Indicador defineIndicador() {
try {
String pacote = "br.com.caelum.argentum.indicadores.";
// instancia indicador base
// instancia a mdia, passando o indicador base
return indicador;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
. Exvncc:os: :No:cnoonvs vm1vmvo ov vxvccXo
) Na classe ArgentumBean, ache o mtodo geraGrafico e identifque a linha que plota o indicador. Ela deve
ser algo como:
Captulo - A API de Refection - Exerccios: indicadores em tempo de execuo - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
geradorGrafico.plotaIndicador(new MediaMovelSimples(new IndicadorFechamento()));
Troque o parmetro do plotaIndicador por uma chamada a um novo mtodo defineIndicador():
geradorGrafico.plotaIndicador(defineIndicador());
) Use o ctrl + e escolha a opo Create method defneIndicador. O Eclipse gerar o esqueleto do mtodo
para ns e, agora, falta preench-lo.
private Indicador defineIndicador() {
String pacote = "br.com.caelum.argentum.indicadores.";
Class<?> classeIndicadorBase = Class.forName(pacote + nomeIndicadorBase);
Indicador indicadorBase = (Indicador) classeIndicadorBase.newInstance();
Class<?> classeMedia = Class.forName(pacote + nomeMedia);
Constructor<?> construtorMedia = classeMedia.getConstructor(Indicador.class);
Indicador indicador = (Indicador) construtorMedia.newInstance(indicadorBase);
return indicador;
}
) O cdigo acima ainda no compila! As diversas excees que a API de refection lana ainda precisam
ser tratadas. Com a ajuda do Eclipse, envolva todo esse trecho de cdigo com um try/catch que pega
qualquer Exception e a encapsula em uma RuntimeException.
private Indicador defineIndicador() {
try {
String pacote = "br.com.caelum.argentum.indicadores.";
Class<?> classeIndicadorBase = Class.forName(pacote + nomeIndicadorBase);
Indicador indicadorBase = (Indicador) classeIndicadorBase.newInstance();
Class<?> classeMedia = Class.forName(pacote + nomeMedia);
Constructor<?> construtorMedia = classeMedia.getConstructor(Indicador.class);
Indicador indicador = (Indicador) construtorMedia.newInstance(indicadorBase);
return indicador;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
) Vamos aproveitar e adicionar um comportamento padro para quando o usurio no tiver escolhido
qual grfco ele quer ainda. Antes mesmo do bloco de try/catch, podemos adicionar o comportamento
padro de, se os indicadores no estiverem escolhidos, devolvemos por padro a Mdia Mvel Simples
do Fechamento.
private Indicador defineIndicador() {
if (nomeIndicadorBase == null || nomeMedia == null)
return new MediaMovelSimples(new IndicadorFechamento());
Captulo - A API de Refection - Exerccios: indicadores em tempo de execuo - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
try {
//...
) Reinicie o TomCat e acesse o Argentum para testar o funcionamento dessa nova modifcao no sistema.
Tudo deve estar funcionando!
. MvtnonnNoo n on:vN1nXo n on)v1os
O design do cdigo do exerccio anterior tem muito espao para melhorias. Note que acabamos colocando
muitas responsabilidades diferentes na classe ArgentumBean - justamente nela, que deveria servir apenas para
prover objetos para os componentes da nossa pgina.
Almdisso, nosso mtodo defineIndicador ummtodo privado na ArgentumBean e isso o torna extrema-
mente difcil de testar.
Podemos, por exemplo, extrair essa lgica de defnio do indicador para uma classe completamente
nova, que tivesse essa nica responsabilidade. Assim, nosso mtodo geraGrafico instanciaria um
IndicadorFactory, que devolveria o indicador correto:
public void geraGrafico() {
// outras linhas de cdigo
IndicadorFactory fabrica = new IndicadorFactory(nomeMedia, nomeIndicadorBase);
geradorGrafico.plotaIndicador(fabrica.defineIndicador());
this.modeloGrafico = geradorGrafico.getModeloGrafico();
}
Assim, o mtodo defineIndicador() passar a ser pblico e, portanto, muito mais facilmente testvel e
muito mais coeso - seguindo um dos princpios SOLID: mais especifcamente, o princpio da responsabili-
dade nica
Exvncc:os Ovc:oNn:s: nvvn1onnXo vnnn mvtnonnn n covsXo
) (Opcional) Crie a classe IndicadorFactory e faa com que ela receba no construtor os parmetros
nomeMedia e nomeIndicadorBase. Esses valores so obrigatrios e no sero alterados, portanto eles
podem ser final.
) (Opcional) Traga para essa classe o mtodo defineIndicador, alterando ele para pblico, agora que
ele est em outra classe. Lembre-se, tambm, de arrumar erros de compilao que surgirem na classe
ArgentumBean.
) (Opcional) Crie testes para a IndicadorFactory. Um desses testes deve verifcar o comportamento
quando no passamos o nome de uma das classes. Outro, poderia motivar a melhoria do tratamento
das excees para algo mais descritivo.
Captulo - A API de Refection - Melhorando a orientao a objetos - Pgina
C
Apndice Testes de interface com Selenium
Alm da magia negra, h apenas automao e mecanizao
Federico Garcia Lorca
. IN1noocXo no 1vs1v ov ncv:1nXo
Nos captulos anteriores fzemos uso dos testes de unidade, ser que eles so sufcientes para garantir que
a aplicao funcione da maneira esperada? Em um projeto web, uma das partes mais importantes para o
funcionamento desejado a parte de apresentao, j que a partir dela que toda a comunicao do cliente
com o nosso sistema ser feita.
Verifcar se as funcionalidades de um sistema esto se comportando corretamente sem que tenhamos de
testar manualmente a aplicao, abrindo um navegador, navegando por ele e visualizando os resultados so
tarefas que so realizadas pelos Acceptance Testing (ou Testes de Aceitao).
Temos que testar o nosso cdigo, mas em uma aplicao web fca difcil testar a camada de apresentao,
o resultado fnal. Como testar a compatibilidade entre browsers diferentes de maneira automatizada? Em
geral, como testar se a pgina renderizada tem o resultado desejado?
Para isso ser possvel, existemalgumas ferramentas que permitemtal trabalho, simulando a interao de um
usurio coma aplicao. Esse o caso do Seleniumque, coma assistncia do JUnit, pode facilitar o trabalho
de escrever tais testes.
. Como vcNc:oNn:
Para demonstrar como o Selenium funciona, testaremos se a validao do campo titulo funciona correta-
mente, isto , o formulrio no poder ser submetido caso ele esteja em branco.
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
A primeira coisa que uma pessoa faz para testar a aplicao abrir um browser. Com Selenium, precisamos
apenas da linha abaixo:
WebDriver driver = new FirefoxDriver();
Nesse caso, abrimos o Firefox. A ideia aqui igual ao mundo JDBC onde o Driver abstrai detalhes sobre o
funcionamento do banco de dados. Em nosso caso o driver se preocupa com a comunicao com o navega-
dor.
H outros drivers disponveis para Chrome, Internet Explorer, Safari e at para Android ou iPhone. O que
precisa mudar apenas a implementao concreta da interface WebDriver, por exemplo:
WebDriver driver = new InternetExplorerDriver();
H1mtUN:1Dn:vvn
H uma outra implementao do WebDriver disponvel que nem precisa abrir um navegador.
Ela se chama HtmlUnitDriver e simula o navegador em memria. Isso muito mais rpido mas
no testa a compatibilidade do navegador fdedignamente:
WebDriver driver = new HtmlUnitDriver();
Essa alternativa bastante utilizada em ambientes de integrao que fazem uso de um cloud, j
que no temos disponveis um browser para teste.
O prximo passo indicar qual pgina queremos abrir atravs do navegador. O driver possui um mtodo
get que recebe a URL:
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
Com a pgina aberta, faremos a insero de um valor em branco no campo titulo. Para isso, precisamos da
referncia deste elemento em nosso cdigo, o que feito pelo mtodo findElement.
Este mtodo recebe como parmetro umcritrio de busca. Aclasse By possui uma srie de mtodos estticos.
Pesquisaremos pelo id:
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
Captulo - Apndice Testes de interface com Selenium - Como funciona? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Agora que temos o elemento, podemos preench-lo como texto que quisermos atravs do mtodo sendKeys.
Em nosso caso, deixaremos o campo em branco passando uma string vazia:
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
titulo.sendKeys("");
Quando o formulrio for submetido e o campo titulo estiver em branco, esperamos que o sistema mostre
a mensagem Erro de Validao.
Antes de testarmos se tudo esta correto, precisamos submeter o formulrio. O objeto WebElement possui o
mtodo submit que faz exatamente isso:
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
titulo.sendKeys("");
titulo.submit();
Para termos certeza de que o sistema esta validando, pediremos ao Selenium que procure pelo texto Erro
de Validao. Primeiro, precisamos evocar o mtodo getPageSource, que nos permite procurar por algo no
cdigo da pgina, e logo em seguida o mtodo contains, que retorna true ou false:
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
titulo.sendKeys("");
titulo.submit();
boolean existeMensagem = driver.getPageSource().contains("Erro de validao");
Por fm, aps o formulrio ter sido submetido, precisamos saber se tudo saiu conforme o planejado, o que
pode ser feito atravs do mtodo esttico assertTrue da classe Assert, que recebe como parmetro um
boolean que indica a presena ou no do texto procurado pelo mtodo contains:
Captulo - Apndice Testes de interface com Selenium - Como funciona? - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
titulo.sendKeys("");
titulo.submit();
boolean existeMensagem = driver.getPageSource().contains("Erro de validao");
Assert.assertTrue(existeMensagem);
Pronto, podemos verifcar no prprio Eclipse se o teste passou se ele estiver verde. Se algo der errado, como
de costume, a cor vermelha ser utilizada.
Podemos usar agora o mtodo driver.close() para fechar a janela do navegador.
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/fj22-argentum-web/index.xhtml");
WebElement titulo = driver.findElement(By.id("titulo"));
titulo.sendKeys("");
titulo.submit();
boolean existeMensagem = driver.getPageSource().contains("Erro de validao);
Assert.assertTrue(existeMensagem);
driver.close();
. TnnnntnnNoo como:vvnsos 1vs1vs ov ncv:1nXo
comum termos dois ou mais testes de aceitao em nossa bateria de testes. Teramos ento que abrir uma
janela do navegador em cada mtodo, e, aps os testes, fech-la. Com isso, estaramos repetindo muito
cdigo! O Selenium nos permite fazer isso de uma forma mais fcil. Primeiro, criaremos o mtodo setUp, e
o anotaremos com @Before.
@Before
public void setUp() {
driver = new FirefoxDriver();
}
Captulo - Apndice Testes de interface com Selenium - Trabalhando com diversos testes de aceitao - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Este mtodo ser invocado antes de cada teste, sempre abrindo uma nova janela. Analogamente, existe a
anotao @After, que indica que o mtodo ser invocado aps cada teste. Agora, precisamos fechar essas
janelas:
@After
public void tearDown() {
driver.close();
}
. Pnnn snnvn mn:s: CoNv:ccnnNoo o SvtvN:cmvmcnsn
Caso voc esteja fazendo esse passo de casa, preciso baixar algumas JARs para o funcionamento dessa
aplicao, usaremos as seguintes verses:
commons-exec-..jar
commons-logging-...jar
guava-..jar
httpclient-...jar
httpcore-...jar
json-.jar
selenium-java-...jar
Para mais informaes, voc pode consultar o site http://docs.seleniumhq.org/
. Exvncc:os: Tvs1v comSvtvN:cm
Vamos criar nosso primeiro teste com Selenium:
) Antes de tudo vamos colocar as jars do Selenium no nosso projeto, elas se encontram na pasta
Desktop/caelum/22/selenium-jars/:
Captulo - Apndice Testes de interface com Selenium - Para saber mais: Confgurando o Selenium em casa - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
Para adicion-las ao projeto, crie uma nova pasta chamada lib-teste na raiz do projeto e copie as jars
para dentro dela.
Logo em seguida adicione-as ao Build Path:
Captulo - Apndice Testes de interface com Selenium - Exerccios: Teste com Selenium - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
) Crie a classe usando ctrl + N Class, chamada GeraGraficoTest no source folder src/test/java e dentro do
pacote br.com.caelum.argentum.aceitacao:
) A classe ter dois atributos. O primeiro com a URL da pgina que queremos testar e o segundo o Web-
Driver, o objeto que nos permite manipular o navegador.
public class GeraGraficoTest {
private static final String URL =
"http://localhost:8080/fj22-argentum-web/index.xhtml";
private WebDriver driver;
}
) Vamos criar o mtodo testeAoGerarGraficoSemTituloUmaMensagemEhApresentada e anot-lo com
@Test para indicar que ele deve ser chamado quando o teste for executado:
public class GeraGraficoTest {
private static final String URL =
"http://localhost:8080/fj22-argentum-web/index.xhtml";
private WebDriver driver;
@Test
public void testeAoGerarGraficoSemTituloUmaMensagemEhApresentada() {
}
}
) Usaremos o WebDriver para abrir uma nova janela do Firefox e acessar a URL do projeto, e usaremos o
mtodo driver.close() para fechar a janela
public class GeraGraficoTest {
Captulo - Apndice Testes de interface com Selenium - Exerccios: Teste com Selenium - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
private static final String URL =
"http://localhost:8080/fj22-argentum-web/index.xhtml";
private WebDriver driver;
@Test
public void testeAoGerarGraficoSemTituloUmaMensagemEhApresentada() {
driver = new FirefoxDriver();
driver.get(URL);
driver.close();
}
}
) Estamos testando se a mensagem de erro aparece quando submetemos um formulrio com o ttulo. Para
isso, primeiro precisamos capturar o elemento do ttulo em um WebElement. Como estamos trabalhando
com JSF, devemos lembrar que ele concatena o id do formulrio com o id dos inputs. Por conseguinte,
devemos procurar o elemento pelo id dadosGrafico:titulo
public class GeraGraficoTest {
private static final String URL =
"http://localhost:8080/fj22-argentum-web/index.xhtml";
private WebDriver driver;
@Test
public void testeAoGerarGraficoSemTituloUmaMensagemEhApresentada() {
driver = new FirefoxDriver();
driver.get(URL);
WebElement titulo = driver.findElement(By.id("dadosGrafico:titulo"));
titulo.sendKeys("");
titulo.submit();
boolean existeMensagem = driver.getPageSource().contains("Erro de validao");
Assert.assertTrue(existeMensagem);
driver.close();
}
}
) Vemos que usamos driver = new FirefoxDriver() para abrir uma janela (um WebDriver) do navega-
dor, e driver.close() para fechar a janela. Caso formos escrever mais testes, precisaremos abrir e fechar
o navegador novamente. Para podermos reaproveitar esse cdigo, podemos coloc-los em blocos sepa-
Captulo - Apndice Testes de interface com Selenium - Exerccios: Teste com Selenium - Pgina
Material do Treinamento Laboratrio Java com Testes, JSF, Web Services e Design Patterns
rados e usar as anotaes @Before, para execut-lo antes de cada mtodo, e @After, para execut-lo aps
cada mtodo.
public class GeraGraficoTest {
private static final String URL =
"http://localhost:8080/fj22-argentum-web/index.xhtml";
private WebDriver driver;
@Before
public void setUp() {
driver = new FirefoxDriver();
}
@After
public void tearDown() {
driver.close();
}
@Test
public void testeAoGerarGraficoSemTituloUmaMensagemEhApresentada() {
driver.get(URL);
WebElement titulo = driver.findElement(By.id("dadosGrafico:titulo"));
titulo.sendKeys("");
titulo.submit();
boolean existeMensagem = driver.getPageSource().contains("Erro de validao");
Assert.assertTrue(existeMensagem);
}
}
Captulo - Apndice Testes de interface com Selenium - Exerccios: Teste com Selenium - Pgina
ndice Remissivo
anotaes,
Calendar,
Candlestick, ,
datas,
Design patterns,
Escopos do JSF,
Factory pattern,
fnal,
h:form,
JUnit,
Negociao,
Refection,
static import,
Tail,
TDD,
Test driven design,
testes de unidade,
testes unitrios,

You might also like