Académique Documents
Professionnel Documents
Culture Documents
Essa apostila referente a um curso completo de desenvolvimento de software, com durao de 120hs. O objetivo do curso tornar o aluno pronto para desenvolver aplicaes corporativas completas, usando o framework de desenvolvimento rpido Grails.
Capitulo 01: Conceitos Bsicos de Arquitetura de Software......................................... 5 1.1 - O que Arquitetura de Software? ....................................................................... 5 1.2 - O que so aplicaes corporativas? ..................................................................... 6 1.3 - Quais os tipos de aplicaes corporativas? ........................................................ 7 1.4 - Solues comprovadas para problemas comuns: Padres .............................. 7 1.5 - O sistema para estacionamento: Estudo de Caso ............................................. 7 1.6 - Tecnologia base do treinamento: Grails ............................................................. 8 1.7 A estrutura de uma aplicao Grails ................................................................... 9 Prtica 01 ..........................................................................................................................10 1.8 - A linguagem Groovy ..............................................................................................11 Prtica 02 ..........................................................................................................................11 1.9 - O IDE Spring Tool Suite ........................................................................................12 Prtica 03 ..........................................................................................................................12 Captulo 02: Camada de Domnio .....................................................................................13 2.1 - Domain-Driven Design (DDD) .............................................................................13 2.2 - Programao Orientada a Objetos (POO) ..........................................................13 2.2.1 - Classe e Objetos..............................................................................................13 Prtica 04 ..........................................................................................................................16 2.2.2 - Herana e Polimorfismo .................................................................................17 Prtica 05 ..........................................................................................................................21 2.2.3 - Interfaces .........................................................................................................21 Prtica 06 ..........................................................................................................................23 2.2.4 - Pensando em Papeis+Comportamentos+Colaboraes na hora de definir seus objetos ......................................................................................................23 Prtica 07 ..........................................................................................................................24 2.3 - Testes de Unidade..................................................................................................24 Prtica 08 ..........................................................................................................................26 2.4 Cobertura de Testes..............................................................................................26 2.4.1 - Cobertura por Linha de Cdigo x Cobertura por Branch ..........................27 Prtica 09 ..........................................................................................................................28
Copyright 2011 @ FiboDev - http://fibodev.com.br
2.5 - Desenvolvimento Guiado por Testes (TDD) ......................................................28 Prtica 10 ..........................................................................................................................29 Capitulo 03: Camada de Persistncia ..............................................................................31 3.1 - Mapeamento Objeto Relacional ...........................................................................31 Prtica 11 ..........................................................................................................................32 3.1.1 - Mapeamento de Associaes ........................................................................32 3.1.1.1 - One-to-One...................................................................................................32 3.1.1.2 - One-to-Many ................................................................................................34 3.1.1.3 - Many-to-Many ..............................................................................................35 3.1.2 - Mapeamento de Composies ......................................................................35 3.1.3 - Mapeamento de Herana ...............................................................................36 3.2 - Realizando operaes de banco de dados .........................................................37 3.3 - Customizando o Mapeamento ..............................................................................37 3.4 - Consultas via Finders Dinmicos .........................................................................38 3.5 - Consultas via HQL.................................................................................................38 Prtica 12 ..........................................................................................................................39 3.6 - Sesso e Transao ...............................................................................................39 Prtica 13 ..............................................................................................................................39 3.7 - Configuraes de Banco........................................................................................39 Prtica 14 ..........................................................................................................................41 3.8 - Testes de Integrao .............................................................................................41 Prtica 15 ..........................................................................................................................42 Captulo 04: Camada de Servios ....................................................................................43 4.1 - O que so aspectos?..............................................................................................43 4.2 - Como criar meus servios? ..................................................................................43 Prtica 16 ..........................................................................................................................44 Captulo 05: Camada de Apresentao ...........................................................................45 5.1 Model View Controller (MVC)...............................................................................45 5.2 Controladores .........................................................................................................47 5.3 Grails Server Pages (GSP) ...................................................................................50 5.4 Customizando nossa interface grfica ...............................................................50
Copyright 2011 @ FiboDev - http://fibodev.com.br
5.4.1 Questes de Usabilidade...................................................................................50 5.4.2 Redirecionamento de Pginas..........................................................................50 Captulo 06: Configuraes do Grails...............................................................................51 6.1 BootStrap.groovy ..................................................................................................51 6.2 BuildConfig.groovy ................................................................................................51 6.3 DataSources.groovy..............................................................................................51 6.4 UrlMappings.groovy ..............................................................................................51 6.5 Fazendo o deploy de uma aplicao Grails .......................................................51 6.6 Configuraes de Idioma .....................................................................................51 6.7 Customizando controles GSP com as taglibs ....................................................51 6.8 Scripts de customizao de Builds .....................................................................51
O diagrama abaixo mostra como a comunicao entre essas camadas. Observe que a camada de domnio est no centro, e que todas as outras camadas dependem dela, ao mesmo tempo em que ela no depende de ningum. fundamental compreender essa importncia da camada de domnio j no comeo do curso, pois todo o desenvolvimento dele ser em torno dela.
simplificado, o sistema real deve responder de imediato, um compilador precisa ter boas mensagens de erro, e assim por diante. Consideramos aplicaes corporativas aquelas que manipulam um conjunto de dados muito grande, e tambm muito complexo. Alm disso, essas aplicaes possuem uma lgica de negcio extremamente complicada, no raro ver um programador dizendo que o cliente est pedindo para ele fazer algo que no tem sentido algum. As aplicaes corporativas so acessadas por muitos usurios ao mesmo tempo, o que implica cuidados peculiares quanto concorrncia e performance. Outro ponto importante que nestas aplicaes os requisitos mudam com muita frequncia, se comparados aos requisitos de um jogo ou de um compilador, por exemplo. As tcnicas que sero ministradas neste curso so para resolver essas, e outras, questes sobre o desenvolvimento de aplicaes corporativas.
Um dono de estacionamento deseja utilizar um sistema para executar algumas regras de clculo, em relao ao valor que tem que ser pago por um perodo dentro do estacionamento. Ele ir criar trs portes de entrada em seus estacionamentos. No menos deles apenas tero acesso motocicletas, no intermedirio, tero acesso apenas carros de passeio e no porto maior podero passar as caminhonetes. Para cada um deste tipo de veculo haver uma forma especfica de se calcular o valor do estacionamento. Sempre que um veculo entrar no estacionamento, sua entrada ser registrada com a data e hora, placa do veculo e categoria do mesmo, de acordo com o porto de entrada; Esse registro ser usado para o clculo do valor, que ser efetivado quando o motorista decidir pagar o estacionamento para poder retirar seu veculo; Um bilhete com essas informaes ser entregue ao motorista; Alm destas informaes o bilhete contm um cdigo de identificao; O bilhete usado para que ele possa efetuar o pagamento e ento poder retirar seu veculo. O bilhete tambm pode ser usado para verificar o valor parcial da conta, com base em um portal de acompanhamento aberto aos clientes. O sistema ser feito de forma gradual, com base nas prioridades dos requisitos, que sero dadas a cada prtica presente nesta apostila; Dever haver um tempo de tolerncia no qual o motorista no precisa pagar para poder retirar seu veculo; O tempo de tolerncia poder variar de acordo com o tipo de veculo O sistema dever dar suporte a perodos promocionais; Pode ser definido um valor de hora menor, para as primeiras horas de permanncia de um veculo; Promoes podero ser vlidas para um ou mais tipos de veculos; Veculos podem permanecer no estacionamento o tempo que quiserem; Acima de 12 horas ser cobrada uma diria; O tempo que ultrapassar 24horas ser contabilizado normalmente, at que o veculo inicie outra diria: Ex 01: 26 horas = 1 diria + 2 horas Ex 02: Das 37hs s 48hs = 2 dirias
Como foi avisado, esses requisitos sero detalhados e implementados gradativamente, medida que o contedo do curso for progredindo. Essa lista de requisitos serve apenas para dar uma boa idia geral do que se trata nosso aplicativo, no se prenda muito a cada item levantado, pense no sistema como um todo, pelo menos por enquanto.
Ao p da letra Grails significa Groovy On Rails, isto , um aplicativo que fornece a arquitetura Rails para a linguagem dinmica Groovy (principal linguagem dinmica para a plataforma Java). O Grails (assim como outras plataformas Rails) foi construdo para facilitar o desenvolvimento de sistemas de informao para a web. Atravs do uso de Conveno sobre Configurao, essa ferramenta diminui radicalmente o tempo que o programador gastaria para integrar e configurar todos os mdulos do seu aplicativo web (banco de dados, regras de negcio, controladores de tela, testes, etc..). Para arrematar podemos dizer que com Grails o desenvolvedor pode se preocupar quase que exclusivamente apenas com a lgica de negcio do sistema que ir desenvolver, a lgica de aplicao fica por conta do framework. Groovy a principal linguagem de programao de cdigo aberto para a Mquina Virtual Java, que oferece uma sintaxe flexvel em Java, de modo que a maioria dos desenvolvedores Java pode aprender em questo de horas. Groovy fornece recursos vistos em outras linguagens dinmicas como Ruby, Python e Smalltalk. Groovy realmente brilha em sua capacidade de definir facilmente novas Domain Specific Languages (DSLs) que podem ser usadas como uma camada de abstrao que permite que especialistas no assunto, mesmo no sendo programadores, codifiquem regras de negcio. A combinao de Groovy e Grails oferece benefcios de produtividade rivalizando com Ruby on Rails, mas na plataforma Java que j comprovada a um tempo, escalvel e integrada. (Texto extrado do site www.springsource.com, acessado em 13/05/2011, s 14h40min; Traduzido
pelo Google Tradutor)
importante dizer que, como Groovy executado sobre a plataforma Java, podermos usar qualquer biblioteca ou classe Java que desejarmos em nossos cdigos em Groovy, e viceversa. Alm dos benefcios j citados vale a pena dizer que o Grails fornece uma interface de comandos bastante simples para realizar suas tarefas (compilar, executar, rodar testes, criar classes, etc.). No obstante, essa plataforma fornece uma robusta estrutura de plugins, que fornece a possibilidade de adicionar sua aplicao, funcionalidades feitas por terceiros de forma muito rpida.
10
Prtica 01 Abra uma janela de comandos e execute o seguinte comando para criar uma nova aplicao grails: grails create-app HelloGrails Verifique a estrutura de diretrios e arquivos que foi gerada por esse comando. No tenha preguia, olhe e compreenda, ao menos razoavelmente, artefato por artefato. Execute mais um comando para criar uma classe de domnio: grails create-domain-class Pessoa Abra o arquivo Pessoa.groovy, no diretrio grails-app/domain/hellograils, com o aplicativo GroovyConsole, e adicione as propriedade dataDeNascimento e nome. O Arquivo ficar assim:
Para finalizar nosso primeiro contato execute o seguinte comando: grails generate-all hellograils.Pessoa Esse comando ir criar telas, controladores e testes para a classe de domnio Pessoa. Verifique novamente esses arquivos criados e posteriormente execute a aplicao para saborear o resultado: Copyright 2011 @ FiboDev - http://fibodev.com.br
11
grails run-app
Obs.: Os mtodo save e findAllByNomeLike so injetados pelo Grails, eles no iro funcionar no GroovyConsole.
Prtica 02 Abra uma janela de comando e execute o aplicativo GroovyConsole. Escreva cdigos para experimentar os seguintes cenrios: Identificar o maior elemento de uma lista (testar para lista de inteiros, floats e strings) Imprimir na tela todos os elementos da lista Imprimir na tela todos os elementos pares (para lista de tipos numricos)
12
13
14
Objeto uma unidade de um software que contm dados relacionados a um conceito bem definido, e que contm operaes que utilizam, alterando ou no, esses dados. Essas operaes realizam as responsabilidades deste objeto. Exemplo: Um arquivo de texto um objeto, seus dados so o contedo de seu texto, seu tamanho, sua codificao, etc. Suas responsabilidades so: adicionar um texto ao fim do arquivo, renomear-se, verificar se pode ser lido, verificar se pode ser alterado, dentre outras. Uma observao importante quanto identificao dos objetos. Dois objetos, mesmo que contenham o mesmo contedo, so objetos distintos. Veja o trecho de cdigo abaixo. Primeiro criamos dois objetos idnticos e verificamos se so diferentes:
15
16
Porm, se de acordo com suas regras de negcio dois objetos idnticos devam ser considerados iguais, voc pode fazer isso alterando o mtodo de comparao:
Uma classe a frma para a construo de um objeto. na classe que definimos quais so os dados do objeto e codificamos o comportamento do mesmo. Com essa frma podemos criar nossos objetos, como pode ser notado nas imagens anteriores temos a definio da classe MP3 e a criao dos objetos musica01 e musica02. Prtica 04
17
Construa um modelo de domnio, usando apenas o que foi visto at agora, para o seguinte cenrio: Um computador contm um processador e um sistema operacional. O sistema operacional responsvel por gerenciar tarefas, ele mantm uma fila de tarefas. O SO delega a um processador que execute cada uma das tarefas. Aps executar um trecho da tarefa, o SO verifica se a tarefa finalizou, se tiver finalizado no faz nada e continua o processamento da lista, se no finalizou ele coloca a tarefa no final da fila e pega outra para processar. Cada tarefa tem um nome, um cdigo e uma quantidade de passos. O SO fornece a funcionalidade de criar tarefas. O SO tem um nome e uma verso. 2.2.2 - Herana e Polimorfismo A herana um recurso da orientao a objetos que nos permite reutilizar cdigo e definir uma hierarquia para nossas classes, no sentido de classes mais genricas para classes mais especializadas. Essas especializaes so simples de compreender se olharmos para o mundo real. Pense em veculos por exemplo. Para pensarmos no conceito mais genrico nos precisamos pensar em caractersticas comuns a todos os veculos, como: velocidade mxima de locomoo, peso, meio de locomoo (gua, terra, ar), cor, capacidade de carga, capacidade de passageiros, e outras. Dentre esses tipos de veculo cada um tem suas caractersticas peculiares, veculos terrestres tm quantidade de rodas, aeronaves tm quantidade de motores e veculos aquticos podem ser divididos em trao humana, movido pelo vento ou por motor. (note
que estou pegando alguns pontos para poder explicar o que herana, no vamos ficar aqui levantando todas possibilidades de veculos)
Da mesma foram que no mundo real temos entidades genricas (Veculos), e entidade especializadas (Carros, Motos, Bicicletas, Navios, etc), no mundo da programao orientada a objetos tambm podemos fazer isso, atravs da herana de classes. Podemos tambm ter especializao em mais de um nvel: Veiculo se especializa em Veculos terrestres, veculos aquticos e veculos areos, os terrestres por sua vez se especializam em carros, motos, caminhes, e assim por diante. Vejamos uma possvel codificao para esse exemplo:
18
Note que a operao adicionePassageiro est disponvel para todas classes que herdam de veculo. E as subclasses (classes que herdam) podem ter operaes especficas que no so encontradas nas superclasses (classes que so herdadas). Poderamos ter a operao troquePneus para a classe Carro, por exemplo, e que no faria muito sentido para a classe Navio. Resumidamente podemos dizer que uma subclasse a superclasse e mais um
19
pouco, isto , ela tem todos dados e operaes da sua classe pai, e mais alguns dados e operaes especficas para ela. Note que a classe veculo iniciada com a palavra abstract, o que indica, obviamente, que est uma classe abstrata. Classes abstratas no podem ser instanciadas, elas apenas servem de molde para suas classes filhas, no faz sentido existir uma classe abstrata que no contenha classes filhas. Esse um assunto bastante extenso, porm no momento nosso objetivo apenas introduzir esses conceitos, e medida que formos aplicando-os na prtica, que o que nos interessa, eles sero compreendidos com mais detalhes e clareza. Vamos apenas dar uma pincelada sobre polimorfismo antes de passar adiante. Alm de poder adicionar novas operaes e dados, as subclasses tambm podem alterar comportamentos definidos na classe pai, o que chamamos de Polimorfismo. Ou seja: Polimorfismo a capacidade que classes filhas tm de alterar algum comportamento definido na classe pai, atravs da sobrescrita de mtodos. Ou, por outro ponto de vista, a capacidade que objetos tm de realizar uma mesma operao de forma distinta, de acordo com a especializao de cada um. Exemplo:
20
21
Modifique o cdigo do exerccio anterior, de modo a dar suporte s seguintes alteraes: O nosso sistema operacional deve dar suporte a trs tipos de processo: Processos de processamento lento, de processamento neutro e de processamento rpido. Os de processamento lento executam um passo de cada vez, os de processamento mdio dois passos por vez, e os ltimos trs passos por vez. O SO deve dar suporte criao de todos esses novos tipos de tarefas. 2.2.3 - Interfaces Como foi dito anteriormente, em um sistema orientado a objetos existe uma comunicao entre os objetos do sistema, para que a lgica de domnio possa ser implementada. Para que os objetos possam conversar necessrio que eles estabeleam um contrato de comunicao. Esse contrato pode ser definido direto na classe, ou pode ficar separada, em uma interface. Para nosso exemplo dos veculos a interface da classe Carro, por exemplo, :
Voc pode estar se perguntando: Mas isso no a prpria classe? Na verdade no, isso a definio das operaes que os objetos desta classe podem realizar. A classe envolve tambm a implementao destas operaes. A outra forma extrair para uma interface, que um conceito especfico das linguagens de programao orientadas a objeto. Vamos mudar um pouco o a nossa soluo de veculos, vamos remover a herana da classe Veculo e criar uma interface IVeiculo:
22
Da mesma forma que no caso anterior as operaes estaro disponveis para os objetos da classe Carro. A questo se o contrato ser definido apenas na classe ou se ser definido em uma interface apenas tecnolgica, conceitualmente ambas servem para estabelecer a forma que os objetos destas classes iro trocar mensagens com outros. Conceitualmente so equivalentes, porm com a separao da interface podemos deixar a soluo mais flexvel. Suponha que uma companhia de viagem dependa de um carro para realizar uma viagem de turismo. Porm se pensarmos um pouco a viagem precisa de um veculo qualquer, desta forma viagem pode depender da interface IVeiculo e no da classe Carro, pois assim podemos fornecer qualquer implementao de IVeiculo(Carro, Moto, Jegue) que a viagem acontece de qualquer forma!
23
Novamente no se assuste com essa teoria, so apenas pinceladas, vamos aprender mesmo na prtica. Prtica 06 Suponhamos que algumas de nossas tarefas possam ser interrompidas. Implemente uma interface que fornea uma operao para a interrupo de processos. O nosso SO tambm deve ser alterado de modo que fornea uma opo para interromper processos, caso o processo no seja interrompido uma exceo deve ser lanada, caso contrrio ele deve ser removido da lista. 2.2.4 - Pensando em Papeis+Comportamentos+Colaboraes na hora de definir seus objetos No tpico sobre DDD foi dito que os objetos de domnio contem dados e algoritmos que alteram esses dados. No produto final o que realmente temos realmente isso, porm a forma de se chegar neste resultado pode ser diferente. Existe uma outra forma de se pensar no problema, para que chegamos ao nosso modelo de domnio, essa forma de pensar definida por Craig Larman. Essa forma pensarmos em Papeis, Comportamentos e Colaboraes. O Objetivo desta nova forma de se pensar em objeto aproxima ainda mais essa observao de componentes do sistema observao que temos do mundo real. Para chegar ao nosso modelo de objetos devemos seguir os passos abaixo, aps ter compreendido bem nossos requisitos claro: Identificar os objetos no domnio do problema Pensar nas responsabilidades destes objetos Pensar em como os objetos colaboram para cumprir as responsabilidades
Para facilitar um pouco a compreenso do que foi dito vamos pedir ajuda tabelinha de definies abaixo: Termo Aplicao Objeto Papel Responsabilidade Definio Um conjunto de objetos que se interagem A implementao de um ou mais papis Um conjunto de responsabilidades relacionadas Uma obrigao de executar uma tarefa ou conhecer uma informao Uma interao de objetos o papis (ou ambos)
Colaborao
24
Como ocorre a colaborao? A colaborao entre os objetos ocorre atravs da troca de mensagens. Um objeto envia uma mensagem a outro objeto, relativa a alguma de suas responsabilidades. Para que o objeto atenda a esta mensagem, ele pode usar informaes que ele mesmo armazena, ou enviar mensagens a outros objetos. Prtica 07 Com base nos requisitos apresentados no item 1.5, identifique os papis as responsabilidades e colaboraes necessrias para que o nosso sistema possa funcionar. Utilize a notao que achar mais adequada seja ela UML, texto ou qualquer tipo de diagrama.
25
reduzido, e os erros de programao mais ainda, isso por que ao escrever os testes antes, o programador tira todas suas dvidas quanto ao comportamento daquilo que ele est fazendo, mas isso assunto para daqui a pouco. Os testes de unidade geralmente tratam de uma classe especfica. Normalmente temos uma classe de testes para uma classe da aplicao, classes do domnio, e dentro desta classe de testes tm vrios mtodos, que so realmente os testes responsveis por testar diversos comportamentos das operaes desta classe. Esses testes so escritos via cdigofonte, na mesma linguagem dos seus sistemas, as plataformas normalmente usadas para aplicaes corporativas tem boas bibliotecas para construo de testes (.NET, Java, Groovy, Ruby, etc.) Para cada operao de uma dada classe, os testes devem ser escritos com base no simples raciocnio: Realizamos diversas chamadas para essas operaes, com os parmetros e configuraes conhecidas, e verificamos se o resultado obtido o que esperado, de acordo com as regras de negcio. Veja o exemplo abaixo: (para esse exemplo vamos usar uma classe utilitria, e no uma classe de domnio)
26
Vamos a algumas observaes importantes: A classe que nos fornece a estrutura para testes GrailsUnitTestCase. O mtodo setUp pode ser usado para colocarmos cdigos de inicializao, isto , um cdigo que ser executado antes de cada teste, um cdigo para criar arquivos que sero usados nos testes, por exemplo. O mtodo tearDown pode ser usado para colocar cdigos de finalizao, pois este ser executado aps cada teste, como um cdigo para apagar arquivos por exemplo. A verificao do teste feitos pelas assertivas, neste testes usamos assertivas de igualdade, com o mtodo assertEquals(valorEsperado,valorRetornado). Existem diversos outros: assertNotNull, assertNull, assertTrue, assertContains etc..
Vale salientar tambm que os testes do segurana para que alteraes sejam feitas no cdigo, e as alteraes vo surgir aos montes! Prtica 08 Construa testes de unidade para todas as operaes da classe Lista, fornecida pelo instrutor.
27
Escrever bons testes de software um desafio tanto para programadores iniciantes, quanto para os mais experientes. Existem dezenas de estratgias que podem ser usadas para buscar uma codificao de testes mais efetivos. O natural que medida que voc vai testando seu sistema voc v se deparando com situaes mais complexas para serem testadas, um desafio constante! Uma das formas de buscar qualidade no seu teste atravs da anlise de cobertura de cdigo atingida por seus testes de unidade. Mas afinal, o que essa cobertura de cdigo? Cobertura de cdigo um relatrio que diz quais trechos de seu cdigo foram executados por um determinado conjunto de testes. Existem diversos frameworks que geram cobertura de cdigo para testes, para nosso estudo iremos utilizar o framework Cobertura, que bastante utilizado em aplicaes Java e que est disponvel via plugin para aplicaes Grails. Abra o gerenciador de plugins do STS: Alt+G,M Selecione o plugin code-coverage e mande instalar
Aps instalar o plugin basta executar o comando de testes com a opo coverage: grails test-app coverage Esse comando ir gerar um relatrio de cobertura de cdigo em HTML, que estar disponvel no diretrio traget/test-reports/cobertura. Atravs destes relatrios voc ir identificar os trechos do seu cdigo que no foram testados e ir, ento, poder criar novos testes ou alterar os existentes de modo que esses trechos possam ento ser executados durantes os testes. 2.4.1 - Cobertura por Linha de Cdigo x Cobertura por Branch No relatrio de cobertura ns iremos encontrar informaes referentes a dois tipos de cobertura, cobertura por linha e por branch, como na figura abaixo:
A cobertura por linha de cdigo simplesmente verifica se a linha em questo foi executada, enquanto que a cobertura por branch ir validar se todos os caminhos possveis foram executados. Por isso importante ter poucos condicionais no cdigo e assim manter baixa Copyright 2011 @ FiboDev - http://fibodev.com.br
28
a complexidade ciclomtica do mesmo, pois quanto menos condicionais menos opes de caminho termos para percorrer e, consequentemente, mais fcil ser alcanar 100% de cobertura de cdigo por branch. Prtica 09 Execute a cobertura dos testes criados na Prtica 08 e faa as alteraes necessrias para que eles cubram 100% das linhas da classe Lista.
De posse destas informaes fica-nos fcil identificar a primeira vantagem de escrever os testes antes de codificar o sistema: Quando o sistema ficar pronto ele j estar com todos seus testes construdos. A outra vantagem, tambm importantssima, que ao escrever os testes, o programador obrigado a compreender com detalhes, o requisito que est implementando. A escrita de testes serve para refinar os requisitos, medida que os testes vo sendo escritos, as dvidas vo sendo esclarecidas, e quando chegar a hora de programar, poucas dvidas(referentes ao que deve ser feito) restaro na mente do programador. Como os testes devem validar todo comportamento do sistema, ele tambm servir como documentao do projeto, e o melhor de tudo, uma documentao executvel! Pense nisso! Voc ter um registro que descreve como suas classes devem se comportar em todas situaes, timo, e ainda por cima poder executar para ver se elas realmente esto fazendo o que devem fazer, fantstico! De forma bem direta, para programarmos de forma guiada por testes devemos seguir os passos do diagrama abaixo: (antes de fazer os passos abaixo no deve exitir cdigo nas suas classes, no mximo o arquivo delas, sem nada dentro)
29
Esse ciclo deve ser repetido at que voc tenha um conjunto de testes bastante completo para a funcionalidade que est implementando. Quando voc saber que est bom o suficiente? Isso depende da sua experincia e dos seus conhecimentos sobre as prticas de escrita para bons testes. Outra linha tnue a avaliao que voc far para verificar se seu cdigo precisa de melhoria ou no, isso sutil, minha dica a seguinte, quando voc achar que est bom o suficiente chame algum mais experiente para dar uma opinio. Prtica 10 A partir deste momento iremos direcionar todas nossas prticas para o nosso estudo de caso, o sistema de estacionamento. Essa prtica ser a mais longa dentre as que j fizemos at este momento. Voc dever construir toda camada de domnio da nossa aplicao, de forma orientada a testes. Construa um teste por vez, e incremente-os gradativamente, conforme o diagrama de TDD apresentado acima, at que tenhamos nossa implementao completa. A cada passo do ciclo voc dever solicitar o acompanhamento do instrutor para que ele possa avaliar os passos que j executou e lhe orientar em relao aos prximos. Copyright 2011 @ FiboDev - http://fibodev.com.br
30
Ainda usando os requisitos definidos no item 1.5, considere os seguintes dados para a construo de seus testes: Os valores de hora so: o Moto: R$ 1,00 o Carro: R$ 2,00 o Caminhonete: R$ R$ 2,50 As configuraes de valor reduzido para horas iniciais so: o Carro, as duas primeiras horas, R$ 1,00 o Caminhonete, as trs primeiras horas, R$ 2,00 As tolerncias so: o Moto: 15 minutos o Carro: 30 minutos o Caminhonete: 30 minutos Os valores de dirias so: o Moto: R$ 15,00 o Carro: R$ 26,00 o Caminhonete: R$ 35,00 A tolerncia vale apenas para os minutos iniciais Existe tambm uma tolerncia por hora, de 10 minutos para todos o 1h10min => Ser cobrada 1 hora o 1h11min => Sero cobradas 2 horas Deve ser possvel criar promoes Promoes podem valer para um ou mais tipo de veculo Promoes contm o valor promocional e a faixa de horrios em que ela vlida A hora promocional vale desde que a hora a receber desconto contenha no mnimo 20 minutos dentro do perodo promocional o Promoo, R$ 0,50, das 11hs s 13hs o Ex. 01: Entrada 10h30min, Sada 11h30 Paga o valor promocional o Ex. 02: Entrada 10h20min, Sada 11h15 Paga hora normal
Obs.: Ao escrever seus testes lembre-se de que eles so uma documentao do seu sistema, atravs dele deve ser possvel compreender tudo que sua aplicao dever fazer. Esse o momento de tirar as dvidas quanto aos requisitos.
31
Quando decidimos construir um sistema de informao (o mesmo que aplicao corporativa) usando programao orientada a objetos, ns acabamos nos deparando com um problema de compatibilidade, referente ao armazenamento no voltil dos dados. O problema em questo o seguinte: No armazenamento voltil nos temos os dados representados atravs de objetos de domnio, enquanto que no armazenamento no voltil (bancos de dados relacionais), ns temos os dados representados atravs de tabelas, e relaes entre as mesmas. claro que hoje tambm temos a opo de usar bancos de dados orientados a objetos, j existem opes bem difundidas no mercado (o que mais ouo falar o db4objects). Mesmo tendo a opo de usar banco de dados orientado a objetos, poucas pessoas passaram por uma experincia real com esses bancos, e eu no sou uma delas. Alm disso, os bancos de dados relacionais apresentam algumas vantagens em relao aos bancos relacionais, dentre elas: Vasto contedo na internet; atendem bem, comprovadamente, a sistemas com grande fluxo de dados; e existem boas opes grtis. Deste modo vamos estudar o modelo tradicional que utiliza objetos em memria, e tabelas dos bancos de dados relacionais, como armazenamento esttico de dados. Nos prximos tpicos veremos com isso feito.
32
Para toda classe de domnio criada uma tabela no banco de dados; Para todos os propriedades simples das classes de domnios so criadas colunas para a tabela da classe em questo; Para as referncias entre objetos o GORM cria uma chave estrangeira da classe contida para a classe que contm; De maneira resumida podemos dizer que o GORM cria todos artefatos necessrios para o mapeamento dos seus dados nas tabelas, isso vale apara associaes de listas e de dicionrios tambm; A API de persistncia injetada diretamente nos objetos de domnio, atravs dos finders dinmicos, e demais mtodos de persistncia (get, delete, save, etc.); A sesso e transao so gerenciadas automaticamente atravs das chamadas aos controladores.
Prtica 11 Altere no arquivo DataSources.groovy a url de conexo com o banco de desenvolvimento. Originalmente este banco est configurado para ser em memria, mude para arquivo. Inicie a aplicao e realize alguma operao que altere o estado do banco de dados. Agora abra seu banco com algum cliente e verifique as tabelas e colunas criadas, analise-as comparando-as com o seu modelo de domnio. 3.1.1 - Mapeamento de Associaes Vejamos alguns exemplos de associaes entre objetos e configuraes do GORM que nos permitem dizer como desejamos que essas associaes sejam refletidas no banco de dados. 3.1.1.1 - One-to-One Unidirecional, sem cascata
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS Copyright 2011 @ FiboDev - http://fibodev.com.br
33
34
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS 3.1.1.2 - One-to-Many //Por default criado um list, mas voc pode alterar isso, criando uma propriedade do tipo que desejar: Set, SortedSet, Map, etc... Unidirecional, cascata para save e update
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS Bidirecional, cascata para save, update e delete
35
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS 3.1.1.3 - Many-to-Many //OBS: O Scaffolding do Grails no da suporte a relaes do tipo Many-to-Many, para elas necessrio escrever o cdigo manualmente
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS: A cascata s acontece de um dos lados, do lado pai 3.1.2 - Mapeamento de Composies
36
//EXPLICAR COMO REPERCUTE NO BANCO e NA MANIPULAO DE OBJETOS 3.1.3 - Mapeamento de Herana Por padro o GORM ir criar uma tabela nica para todas classes de uma dada hierarquia de classes, e nesta tabela existe uma coluna responsvel por identificar qual objeto est sendo armazenado em cada linha.
37
O GORM injeta, em nossos objetos de domnio, uma srie de mtodos que tornam muito simples as operaes em banco de dados. Veja os principais: save - Para persistir ou atualizar um objeto no banco; delete - Para remover um objeto do banco; get - Para recuperar um objeto do banco, dado seu identificador; getAll - Para recuperar um objeto do banco, dado seus identificadores; list - Para recuperar uma lista de objetos do banco;
38
A forma mais prtica de se realizar buscas no banco de dados em Grails utilizando os finders dinmicos, que nada mais so do que mtodos injetados em nossos objetos de domnio e que nos possibilitam consultar objetos atravs de uma srie de restries. Alguns exemplos: Buscar uma pessoa por nome def pessoa = Pessoa.findByName(Roberto Carlos) Buscar todas pessoas que se chamam Roberto def listaDePessoas = Pessoa.findAllByNameLike(Roberto Carlos%) Buscar pessoas por nome e cidade def lista = Pessoa.findAllByNameLikeAndCidade(Fernando%, Goinia)
Essas condies de busca podem ser concatenadas sem restries, as possibilidades so extensas, confira a lista completa em: http://inseriraquiumaurl
39
Essas consultas tambm podem conter parmetros. Prtica 12 //Mapear e consultar, de diversas formas //[TODO]
Prtica 13 //[TODO]
40
As configuraes de banco do Grails se encontram no arquivo DataSources.groovy, que fica no diretrio grails-app/conf. Neste arquivo temos trs configuraes: dataSource Configuraes do servidor de banco de dados: URL, Dirver de Conexo, Usurio, Senha, etc. hibernate Configuraes de cache do Hibernate environments Configurao individual de cada ambiente disponvel devlopment - Configuraes de banco usadas enquanto o sistema est sendo desenvolvido test - Configuraes de banco usadas para os testes de integrao production - Configuraes de banco usada quando feito o deploy do sistema para algum servidor de aplicao/servidor web;
Veja um exemplo: (essa a forma que o arquivo gerado por padro, quando voc cria sua aplicao Grails)
41
O arquivo DataSources.groovy deve ser editado de acordo com as configuraes que voc deseja para seu sistema.
42
caracterstica de nossas classes de domnio. Nos testes de integrao devemos testar, como o prprio nome diz, a integrao de componentes do sistema, e no apenas uma parte isolada. Uma destas opes para testes de integrao so os testes que envolvem acesso ao banco de dados. Vamos fazer um pouco destes testes para que possamos validar, e experimentar, tudo que vimos em relao camada de persistncia at agora.
Prtica 15
43
A essa altura de nosso treinamento nos deparamos com um assunto muito polmico: O que deve ser colocado na camada de servios? Existem arquiteturas em que as regra de negcio so codificadas atravs de servios, uma delas a que citamos anteriormente no tpico Camada de Domnio,a arquitetura BO-LOVO. Para um desenvolvimento guiado pelo domnio (DDD), a tarefa desta camada extremamente reduzida. Pense nesta camada como uma camada fina, algo que acrescenta alguns detalhes ao comportamento de nosso sistema, mas que no contm cdigo para a implementao dos requisitos funcionais de nosso sistema. A prpria documentao do Grails nos diz para colocar lgica de negcio nos servios, ao invs de coloc-la nos controladores de tela. Porm no nosso estudo nem os servios e nem os controladores contero lgica de negcio, apenas os objetos de domnio. Para nosso estudo essa camada ser responsvel por adicionar aspectos nossa aplicao corporativa.
44
Vejam que no cdigo do servio existe uma propriedade esttica declarada como true, transactional. Essa configurao serve para dizer ao Grails que todas operaes deste servio sero realizadas em escopo transacional, isto , caso ocorra algum problema as alteraes no banco sero revertidas, caso ocorra tudo bem, elas sero comitadas no banco de dados. Os servios do Grails so criados no diretrio grails-app/services, e eles so injetados, da forma como foi exemplificado a cima, tanto em controladores quanto em classes de domnio e tambm em outros servios. J ia me esquecendo de um detalhe importantssimo: Servios no guardam estado! Isso uma condio sine qua non para nossa arquitetura. O Grails nos permite definir uma srie de escopos para os servios. Esses escopos esto relacionados ao ciclo de vida destes servios. Exemplo: criado um servio por sesso do banco, criado um servio por chamada, dentre outros. Como faremos o uso mais simples possvel dos servios, para nosso caso iremos usar o escopo padro, isto , singleton, que cria uma nica instncia do servio para todo ciclo de vida da aplicao.
45
J fizemos bastante coisa, porm voc deve estar bastante ansioso para ver a aplicao funcionando, eu estou! Falta pouco para termos esse primeiro contato, ento vamos a ele. O grails possui uma excelente ferramenta de scaffolding, que acelera muito o tempo de construo de nossas telas. Scaffold um procedimento que ir gerar suas telas, em GSP, e tambm seus controladores, seguindo o padro MVC. As telas geradas atendem s operaes CRUD (create, retrive, update, delete) para todos nossos objetos de domnio. Para compreender melhor suponha que seu sistema tenha duas classes: Livro e Autor. Com esse exemplo seriam geradas as seguintes telas: Tela de cadastro de livros; (Create) Tela de edio de livros; (Update) Tela de exibio de dados do livro; (Retrive, Delete) Tela de listagem de livros: (Retrive, Delete) E todas as telas acima tambm para autores; As telas para livro so criadas no diretrio grails-app/views/livro e as telas para autor em grails-app/views/autor; criado um nico controlador para cada objeto de domnio, nele so tratadas todas operaes de CRUD, para este caso teramos o LivroController, e o AutorController, ambos estariam dentro do diretrio grails-app/controllers. Para gerar as telas e controladores de nossos objetos de domnio usaremos o comando grails generate-all nomeDaClasseCompleto. (Os IDEs possuem atalhos e opes de menu para executar todos comandos do Grails) Para criar essas telas o Grails usa novamente a conveno sobre configurao. Ns no precisamos dizer a ele como queremos nossa tela, pois as telas de CRUD so muito semelhantes em aplicaes corporativas, por isso ele tem condio de cri-las para ns. A definio de como a tela ser criada na verdade a definio da prpria camada de domnio, se sua classe tem uma propriedade texto, ele cria um controle de texto, se tem uma propriedade data, ele cria um controle de data, e assim por diante. Novamente notamos que toda construo do nosso sistema parte das classes de domnio, o DDD em ao, lembra-se? Nesta introduo, alm de falarmos sobre Scaffolding, falamos tambm de MVC e de GSP, vamos agora estudar esses assuntos com mais detalhes.
46
Viso A viso formada por componentes que exibem dados ao usurio e que capturam as operaes vindas dele. Para um sistema web, por exemplo, a viso construda com controles HTML, JavaFX, Silverlight, Java Script, Flex, etc. A nica misso da viso a de exibir dados ao usurio e fornecer alguma maneira para que ele interaja com o sistema (atravs de comandos, botes, etc.). A viso no sabe como o trabalho ser feito, ela s sabe que o usurio deseja realizar a tarefa em questo. Controlador O controlador o elo de ligao entre o modelo e a viso. Para cada solicitao do usurio, o controlador que conhece como repassar esse pedido ao modelo. E dada a resposta do modelo, o controlador que sabe como repassar isso de volta para a viso.
Note que o controlador e a viso esto em uma regio destacada. Essa separao foi feita para evidenciar que a camada de apresentao formada pelo controlador e pela viso, enquanto o modelo constitudo pelos servios, pelo domnio e pela persistncia da aplicao. Para reforar esses conceitos vamos olhara para cada um destes componentes do MVC do ponto de vista de responsabilidades: Copyright 2011 @ FiboDev - http://fibodev.com.br
47
Responsabilidades Executar as polticas de negcios que iro satisfazer as solicitaes do usurio. Exibir os dados do domnio de forma visual para o usurio (por isso ele tem uma dependncia com o modelo, mais especificamente com a camada de domnio). Receber os comandos do usurio e repass-los ao controlador. Validar os dados inseridos pelo usurio. Exibir de forma visual a resposta do sistema em relao aos estmulos do usurio. A viso burra, ela no toma decises, apenas repassa pedidos e exibe dados da forma que o controlador determinar. Controlar o fluxo das telas. Decidir, dada uma solicitao vinda da tela, com o modelo dever trat-la. Decidir, de acordo com a resposta do modelo, como a tela dever se comportar.
Controlador
5.2 Controladores
Quando fazemos o comando grails generate-all nomeDaClasseDeDominio, tanto o controlador quanto as views em GSP so gerados, porem voc tem a opo de criar apenas o controlador com o comando grails generate-controller nomeDaClasseDeDominio. A primeira coisa que podemos compreender nos controladores so as aes. Elas so mtodos que so invocados pelas nossas telas da viso, as telas em GSP, ou seja, para cada interao que usurio pode realizar sobre o sistema uma ao de algum controlador deve ser definida. O comportamento dos controladores, e de suas aes, so definidos pela nossa to batida conveno sobre configurao. O acesso a eles dado pela seguinte conveno: UrlDaAplicacao/nomeDoControlador - para acesso ao controlador, este acesso ir invocar a ao default do controlador; UrlDaAplicacao/nomeDoControlador/nomeDaAcao para chamar uma ao especfica de um controlador; Obs.: nomeDoControlador representa o nome do controlador sem a extenso Controller o Ex.: Se o controlador se chama LivroController, uma das urls seria http://minhaapp.com.br/livro/list
A ao default dos controladores a ndex, caso voc deseja explicitar qual deve ser a ao default adicione uma propriedade a seu controlador, conforme o exemplo abaixo:
48
Veja na ao list que na primeira linha de cdigo a propriedade params acessada. atravs desta propriedade que a tela passa os dados para o controlador. Essa propriedade um map que contm todas as informaes necessrias para o processamento de uma requisio vinda da tela. O controlador realiza basicamente dois tipos de comandos das telas. Um deles so as mensagens de flash. Essas mensagens so usadas para dar informaes ao usurio sobre a operao que ele realizou, para mensagens de erro e de sucesso, e assim por diante. Veja um exemplo, com o trecho de cdigo abaixo:
49
Para simular esse erro eu digitei a seguinte url no browser: http://localhost:8080/inscricoesesportivas/eventoesportivo/show/2 Como no existia um evento esportivo com id = 2, ento meu controlador configurou a mensagem de flash, que foi exibida conforme a imagem acima, e logo aps isso o controlador direcionou o fluxo de tela para a ao de listagem. Note que a mensagem est em ingls. Essa uma mensagem padro de objeto no encontrado, voc pode retornar a mensagem que quiser. O Ideal continuar retornando as mensagens padro, porm voc deve alterar as configuraes para que o grails use um arquivo com as verses em portugus destas mensagens. A manipulao de todas configuraes sero vistas no captulo 05. Alm de informar essas mensagens para que as telas possam exibir, nas aes dos nossos controladores podemos tambm reenderizar o fluxo para outra tela ou ento redirecionar a chamada para outra ao. Para repassar a chamada para outra ao usamos o redirect, e para exibir uma nova tela usamos o render. Veja os dos casos no trecho de cdigo abaixo:
50
O primeiro caso um redirecionamento para outra ao, deste mesmo controlador. O mtodo invocado para realizar esta tarefa o redirect, os parmetros passados so a ao e, neste caso um id. Este id ser acessado na ao show, atravs de params.id. O segundo caso, o else do cdigo acima, ocorre uma mudana de pgina. Atravs do mtodo render ns solicitamos que seja exibida a tela de criao. Neste caso passamos tambm um objeto de domnio para que a tela seja preenchida, no item 5.3 veremos como as telas trabalham com esse objeto.
51
6.1 BootStrap.groovy //[TODO] 6.2 BuildConfig.groovy //[TODO] 6.3 DataSources.groovy //[TODO] 6.4 UrlMappings.groovy //[TODO] 6.5 Fazendo o deploy de uma aplicao Grails //[TODO] 6.6 Configuraes de Idioma //[TODO] 6.7 Customizando controles GSP com as taglibs //[TODO] 6.8 Scripts de customizao de Builds //[TODO]