Sie sind auf Seite 1von 22

O suficiente para programadores sem muita experiência em Java:

padrão MVC, documentação de código, persistência, testes


unitários e programação para computação de alto desempenho.
Prof. Dr. Joubert de Castro Lima

DECOM-UFOP - agosto de 2013

Precisamos de um exemplo único e simples, que seja suficientemente complexo para demonstrar
o desenvolvimento de uma aplicação Java por meio do padrão de projeto de software Model-
View-Controler (MVC). Maiores informações sobre MVC em
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. Vamos usar a
calculadora como exemplo. Nossa calculadora efetuará operações de soma, subtração, divisão e
multiplicação.

Nas entrevistas com o usuário conseguimos compreender que o mesmo almeja uma calculadora
simples, que efetue as operações básicas e que permita inserir n operandos e não somente dois
operandos, como são comuns nas calculadoras convencionais. Neste sentido, nossa calculadora
efetuará somas, divisões, subtrações e multiplicações de n números, sejam reais ou inteiros. O
usuário poderá listar quais foram as operações realizadas na calculadora desde sempre!

Após identificar os requisitos, a primeira pergunta que devemos fazer como programador é: Como
o usuário deverá usar a calculadora? Certamente da forma mais simples e intuitiva possível. Neste
sentido, iremos inicialmente modelar a View (o V do MVC). Iremos usar uma interface gráfica do
tipo desktop, porém graças ao nosso projeto MVC não iremos ter muitas recodificações se
almejarmos trocar nossa calculadora por uma interface gráfica Web ou mesmo Android.

Como iremos usar o Java, precisamos de uma IDE para Java. Neste tutorial iremos usar o Eclipse
como IDE Java. Para o desenvolvimento dos componentes gráficos como botões, caixas de texto,
rótulos, botões de rádio, entre outros, iremos usar o WindowBuilderPro. Trata-se de uma solução
Google para rápida prototipação de interfaces gráficas Java Swing. O WindowBuilderPro funciona
como um plugin Eclipse. Faça o download do WindowBuilderPro, siga as recomendações do site,
reinicie o Eclipse e vamos a construção do V do MVC. De uma forma geral, nesta parte do tutorial
iremos entender a necessidade do usuário, podendo assim apresenta-la graficamente e
efetivamente funcionando. Com isto, conseguiremos prototipar telas até que o usuário aprove.

Lista de espelhos para instalar o WindowBuilderPro no Eclipse:

Eclipse 3.7 (Indigo): http://dl.google.com/eclipse/inst/d2wbpro/latest/3.7


Eclipse 3.6 (Helios): http://dl.google.com/eclipse/inst/d2wbpro/latest/3.6
Eclipse 3.5 (Galileo): http://dl.google.com/eclipse/inst/d2wbpro/latest/3.5
Nosso projeto Java no Eclipse se chamará MVC_Java, conforme ilustra a Figura 1. Trata-se de um
projeto Java simples em que só definimos o nome e nada mais. Na pasta src iremos inserir nossas
classes e pacotes do projeto calculadora, portanto como boa prática devemos inicialmente criar os
pacotes model, view e controller, assim como ilustra a Figura 1. Se você não sabe como criar um
projeto Java no Eclipse, basta ir em File => New => Java Project e depois definir um nome para o
seu projeto. Simples assim !!!

Figura 1. Projeto MVC_Java no Eclipse

Uma vez criado o projeto, iremos criar a classe Java responsável pela interface gráfica. Interfaces
gráficas sofisticadas requerem n classes similares a que iremos fazer neste tutorial. Para isto, basta
clicar no pacote view com o botão direito do mouse e depois no menu new => other. Daí basta
escolher uma nova classe jgoodies, conforme ilustra a Figura 2. Note que no Eclipse o JGoodies
aparece como WindowBuilder.
Figura 2. Classe View com o JGoodies

Iremos escolher um JFrame como componente principal de nossa interface gráfica. Note que é
possível construir applets web e diversas outras interfaces, algumas sendo internas a sua aplicação
como é o caso do JInternalFrame. A nova classe chama GUI_calculadora, conforme ilustra a Figura
3. Para que você consiga programar visualmente sua classe com o JGoodies, basta clicar na aba
design. Em suma, ao clicar em design o JGoodies lhe provê programar visualmente a classe
GUI_calculadora. Na Figura 4 ilustramos o painel da aplicação calculadora, assim como os
inúmeros componentes Java Swing disponíveis para que possamos construir interfaces gráficas
para nossos softwares com tecnologia Java.
Figura 3. Classe GUI_calculadora, gerada a partir do JGoodies

Figura 4. Classe GUI_calculadora, visão gráfica da interface sendo construída

A primeira tarefa é inserir um layout que mantenha os componentes visuais de sua tela ajustados
e formatados adequadamente. Neste tutorial escolhemos o FormLayout. Basta selecionar o
FormLayout e o arrastar para a interface gráfica em construção. O resultado é ilustrado na Figura
5. Com o FormLayout temos uma matriz onde podemos inserir os componentes e os ajustar
dentro de uma célula de tal matriz de componentes Swing. Notem que é possível desenvolver
interfaces gráficas extremamente sofisticadas com o JGoodies como plugin Eclipse.

Figura 5. Usando o FormLayout para garantir formatação e ajustamento nos componentes da tela

Após definir o layout, passamos a definir os componentes que o usuário irá interagir. Perceba a
importância desta fase de desenvolvimento de software, pois é nela que nos colocamos como
usuários do sistema, definindo para isto o conjunto de eventos e componentes visuais que tornem
a aplicação simples e que resolva o problema definido pelo usuário. No nosso caso trata-se de uma
calculadora que efetue as operações básicas sobre n operandos, sejam eles reais ou inteiros. Na
Figura 6 ilustramos como ficará a interface gráfica da calculadora. Usamos para isto alguns
JTextFields para permitir que o usuário insira textos, JComboBox para que o usuário informe qual
operação almeja executar, um botão que inicia o cálculo, um botão que lista os cálculos já
realizados e uma JTextArea para exibir tal listagem. Note que podemos programar em JGoodies
outras inúmeras maneiras de atender os requisitos do usuário, portanto nossa solução é apenas
uma das alternativa que atende aos requisitos e que busca SEMPRE A SIMPLICIDADE E A
USABILIDADE. Assumimos daqui para frente que o usuário aprovou a GUI ilustrada na Figura 6.
Agora é desenvolver o M e o C do MVC!
Figura 6. Proposta de interface gráfica para calculadora.

Uma vez que usuário concordou com as interfaces gráficas desenvolvidas rapidamente com o
JGoodies, passamos a implementar também visualmente os eventos necessários. Nesta etapa
iniciamos o desenvolvimento do M (model) do MVC. Na Figura 7 ilustramos a adição do evento
mouseClicked à partir de um simples clique com o botão direito do mouse no componente que
você almeja adicionar o evento (no nosso caso o botão com label Executar), em seguida add event,
em seguida mouse e por fim mouse clicked. O resultado é apresentado na forma de código, como
ilustra a Figura 8.
Figura 7. Inserção de forma visual de eventos a componentes Java Swing

Figura 8. Código gerado pelo JGoodies para o evento mouseClicked

Quando o usuário clica no botão executar o código da Figura 8 é executado, portanto podemos
assumir que uma operação da calculadora será solicitada. Neste sentido, definimos parte do
modelo (M do MVC), pois de alguma forma nossa solução deverá controlar uma operação,
provendo o cálculo da mesma. Neste tutorial a classe operação deverá possuir os atributos: (i)
operandos como uma lista de números, (ii) o operador e (iii) o resultado. Outro requisito a ser
atendido é listar os cálculos já realizados. Para atendê-lo inserimos a classe calculadora. Uma
calculadora possui um conjunto de operações já realizadas. Nossa classe calculadora possui: (i) um
identificador e (ii) uma lista de operações. O projeto já possui seu modelo, composto pelas classes
Operação e Calculadora, conforme ilustra a Figura 9. O modelo pode possuir "v" Views e "c"
Controllers. Esta é a grande vantagem do MVC. Iremos apresentar a calculadora em GUIs desktop,
web e Android. Além disto, iremos efetuar o controle local e distribuído, mostrando com isto que
o projeto MVC_Java possui fraco acoplamento entre seus módulos e consequentemente alta
flexibilidade. O controle de uma simples calculadora se resume a alguns filtros e as operações
básicas. Por outro lado, alguns controles podem exigir lógicas complexas, elevado número de
componentes, assim como alta dependabilidade entre os componentes. Nestes cenários, o
número de classes de controle aumenta, ser escalável se torna árduo e ter manutenibilidade é
praticamente um pesadelo!

Já sabemos que deveremos ter as classes Operacao e Calculadora. Já temos ideia de quais são os
atributos de cada classe, assim como os requisitos da calculadora. Então, já podemos construir
diagrama de classes UML para o modelo de nosso aplicativo. Assim, permitimos que o projeto
Java_MVC possa ser conduzido em equipe, facilitando a comunicação de sua estrutura e
aumentando significativamente seu tempo de vida. A Figura 9 ilustra um diagrama de classes para
o modelo de nosso projeto Java. Usamos o produto Gliffy, pois é online, gratuito em algumas
licenças e possui um enorme catálogo de diagramas, incluindo UML, ER. Basta criar uma conta em
http://www.gliffy.com e começar a usar!

Temos as classes Operacao, Calculadora e a superclasse Model. A superclasse Model é uma boa
pratica de projeto. É comum as classes do modelo terem que ser persistidas em disco ou em um
banco de dados relacional (Oracle, SQL Server, MySQL ou PosGreSQL). Outra necessidade comum
nos projetos é termos que transferir classes (objetos no caso!!!) do modelo pela rede. Diante da
justificativa exposta, adicionamos a superclasse Model que todas as demais classes do modelo
devem herdar. A classe Model possui um identificador e estende as interfaces Java Serializable,
Cloneable e Comparable. A Figura 10 ilustra a classe Model de nosso projeto Java e suas relações.
Com esta simples atitude conseguimos implementar um modelo que pode ser persistido e enviado
pela rede. A outra opção seria colocar implements Serializable, Comparable, Cloneable para cada
classe de seu modelo. Iremos EVITAR esta opção por ser suscetível a erros da equipe de
programação. É obrigatório as classes do Modelo (M do MVC) implementarem os métodos equals,
compareTo, clone e hashCode. Desta forma estaremos implementando um modelo robusto! Mais
a frente voltaremos a este assunto.

Figura 9 – Diagrama de classe UML do modelo do projeto MVC_Java


Figura 10. Classe Model genérica e que todas as demais classes do modelo são filhas

Note que as variáveis de cada classe devem ser privadas, conforme ilustra a Figura 11. A Figura 12
ilustra como gerar os métodos get e set para todas ou algumas variáveis globais. Não há
necessidade de gerar os métodos get e set para cada variável. Ao invés disto, basta clicar com o
botão direito em qualquer ponto da área onde você programa no Eclipse e escolher a opção
generate getters and setters.

Figura 11. Classe Operação do Model


Figura 12. Gerar métodos de acesso no Eclipse

Ao codificar uma classe devemos documentá-la. Usaremos o padrão JavaDoc. Maiores


informações em: http://www.oracle.com/technetwork/java/javase/documentation/index-jsp-
135444.html. Para o programador basta selecionar a classe ou o método e depois clicar em
shift+alt+J. O Eclipse insere as tags como author, return, nome dos argumentos das funções e
muitos outros. Cabe ao programador informar o significado da classe, assim como de seus
métodos, seus argumentos e seus retornos. A Figura 13 ilustra a classe Operacao e sua
documentação JavaDoc.

Figura 13. Classe Operacao devidamente documentada para geração JavaDoc


Para gerar o JavaDoc, basta clicar no projeto MVC_Java com botão direito e em seguida export,
depois cabe selecionar JavaDoc e prosseguir. As Figuras 14 e 15 ilustram este passo.

Figura 14. Geração JavaDoc do projeto MVC_Java

Figura 15. Passo final na geração do javadoc usando eclipse

Após geração, verifique o JavaDoc gerado no seu navegador preferido. O resultado deve ser
similar ao ilustrado na Figura 16 para classe Operacao.
Figura 14. Javadoc criado para o projeto MVC_Java

Para fecharmos as tarefas com a classe Operacao devemos construir a classe que testará se
Operacao funciona adequadamente, isto é, o teste unitário para a classe Operacao. Iremos usar o
JUnit para realizar os testes unitários do projeto MVC_Java.

À medida que o projeto avança, o mesmo procedimento adotado para a classe Operacao deverá
ser realizado para demais classes do projeto MVC_Java (todos os pacotes M, V e C), ou seja: (i)
concepção, (ii) modelagem UML, (iii) implementação da classe, (iv) documentação javadoc, (v)
geração do javadoc e (vi) teste. Gostaríamos de destacar a importância dos TESTES por serem
frequentemente desconsiderados nos projetos devido aos prazos, porém não realiza-los pode sair
muito mais caro.

O plugin JUnit já se encontra instalado em sua IDE Eclipse (versão 3.7), portanto basta clicar com o
botão direito em cima da classe Operacao e selecionar JUnit, depois JUnit Test Case. A Figura 15
ilustra a GUI Eclipse para este passo.

Após a criação da classe OperacaoTest percebemos que há um método de teste para cada método
publico de Operacao (getters e setters). Na Figura 16 ilustramos os métodos de teste para os
métodos públicos getOperador e setOperador da classe Operacao. A regra de preenchimento não
é complexa se feita desde o início do projeto. Em todos os métodos da classe de testes unitários,
um objeto da classe Operacao é criado e a partir daí efetuamos dois testes: se o operador não for
atribuído deve retornar null e se o operador se chamar teste retorne teste. No caso do método
setOperador o teste se resume a verificar inserções positivas ou negativas. O método assertEquals
exige uma String como mensagem, o resultado esperado e o objeto a ser testado. Simples e
robusto. Maiores informações sobre JUnit em: http://www.junit.org/.
Figura 15. Explorer Eclipse para criação de classes de testes unitários

Figura 16. Métodos de teste da classe Operacao, mais precisamente os métodos get/set operador

Mais a frente ensinaremos como criar suítes de teste, ou seja, a execução de inúmeras classes de
teste. Por agora para testar Operacao basta clicar com o botão direito do mouse na classe
OperacaoTest, em seguida run as, depois em JUnit Test. A Figura 17 ilustra este passo. A Figura 18
ilustra o resultado da execução da classe OperacaoTest. Notem na Figura 18 que não existem erros
segundo os testes feitos na classe Operacao. Conduza sempre testes com resultados nulos, para
resultados numéricos sempre use negativo, zero e algum positivo, seja real ou inteiro. Nunca
passe para a próxima classe sem antes conduzir testes unitários com êxito.

Figura 17. Como executar um teste unitário isolado

Figura 18. Resultado esperado de um teste unitário

Até o momento ainda não concebemos como iremos resolver os eventos executar operação e
listar operações realizadas. O que fizemos até agora foi implementar as classes do model
responsáveis por armazenar os dados necessários ao projeto MVC_Java. A partir de agora
dedicaremos as classes Controllers, responsáveis pela lógica ou controle do projeto sendo
desenvolvido. Note que projetos com uma lógica complexa ou projetos extensos irão requerer n
classes Controllers, uma para cada ação ou requisito da aplicação.

No nosso exemplo temos como requisito prover o cálculo de uma operação e listar os cálculos já
realizados. Iremos implementar duas classes Controller para este fim. A primeira se chamara
ControladorOperacao e a segunda ControladorCalculadora. Na Figura 19 ilustramos o diagrama de
classes completo do projeto MVC_Java, no qual é possível verificar a presença das classes dos
pacotes View, Model e Controller.
Figura 19. Diagrama de classes do projeto MVC_Java

Na Figura 19 temos a classe ControladorPersistencia e a informação que todas as classes


controloradoras seguem o padrão de projeto de software Singleton
(http://en.wikipedia.org/wiki/Singleton_pattern). Este detalhe é explicado mais a frente no
documento.

Nas Figuras 20 e 21 especificamos as responsabilidades das classes ControladorOperacao e


ControladorCalculadora como uma interface Java. Note que uma interface Java não possui a
implementação, mas somente as assinaturas de seus métodos. Não implementaremos interfaces
para as classes Model e View por não trazerem benefícios diretos ao projeto MVC_Java. Interfaces
para as classes de Controle é uma boa prática de projeto de software. Consideramos sempre fazer
e sempre começar por um conjunto pequeno de métodos no controle que o usuário interage
diretamente. No nosso exemplo os controles são simples, porém poderiam exigir outras inúmeras
classes também de controle, porém de segunda, terceira, n-ésima ordem. Assumimos classes de
controle de primeira ordem as que são acessadas diretamente por outros componentes ou pela
View. Segunda ordem as que são acessadas pelas classes de primeira e assim sucessivamente.
Para o usuário, o controle de nosso projeto MVC_Java se resume a calcular (Operacao op,
Calculadora calc): boolean e listar (Calculadora calc): List<Operacao>. Apenas dois métodos e a
GUI controla na nossa calculadora.
Figura 20. Interface ControladorOperacao

Figura 21. Interface ControleCalculadora

As implementações das classes ControladorCalculadora e ControladorOperacao estão no projeto


que acompanha este tutorial (MVC_Java.rar). Na Figura 22 apresentamos a ideia da classe
controladorOperacaoImpl, implementação da interface ControladorOperacao. O Método calcular
verifica se o operador da Operacao op começa com “Adi”, “Mult”, “Div” e “Sub”. Então, a
operação é feita no vetor de operandos e o resultado é salvo em op. Por fim, a Calculadora recebe
mais uma operação. Se o calculo der errado retorna-se false e a calculadora permanece intacta.
Figura 22. Implementação do método calcular.

Note na Figura 22 a presença da instrução Java try. Trata-se de mais uma fundamental informação
deste projeto. Sempre use as cláusulas try e catch para TODOS os métodos de suas classes do
controle. Tais cláusulas adicionam robustez ao seu código, pois adicionam execuções extras no
caso de qualquer erro no bloco principal. No bloco de código secundário, chamado catch, você
sempre possui a chance de arquivar o erro em logs, chamar nova computação com novos
argumentos, entre outras possibilidades.

A classe GUI ou View de nosso projeto é a nossa próxima observação. Na classe GUI_Calculadora,
quando o usuário clica em calcular, uma operação é criada sem o resultado e submetida ao
controle ControladorOperacao para que o mesmo proceda o cálculo. O resultado da operação é
exibido na GUI. O evento listar operações acontece de maneira similar ao explicado
anteriormente. Maiores informações no projeto Java que acompanha este tutorial. Na Figura 23
temos o trecho de código que submete o cálculo de uma nova operação na calculadora.

Figura 23. Classe GUI_Calculadora - Calculo de uma nova operação na calculadora


Assim como o pacote model, o pacote controller deve possuir classes de testes unitários. Não as
explicaremos por serem similares aos testes já explicados anteriormente. Novamente, as
informações estão no arquivo Java do projeto, bastando fazer download do projeto MVC_Java.

Perceba na Figura 23 que o ControladorOperacao é invocado de maneira estática, usando o


método getInstance. A partir de agora iremos explicar a importância da afirmação no digrama de
classes do projeto MVC_Java de que “todas as classes de controle são singletons”. Isto significa
que almejamos apenas uma instancia da classe ControladorOperacao por processo criado, seja
multithread ou não. Ter mais instancias não é necessário, nem desejado, em nossa aplicação. O
mesmo ocorre com inúmeros outros controles, portanto sempre opte por tornar sua classe de
controle um singleton. A implementação de uma classe singleton de forma correta está na Figura
24. Maiores informações sobre o padrão de projeto singleton, assim como muitos outros em:
http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software. Um livro bem didático
sobre o tema é o Use a Cabeça! Padrões de projeto, ISBN 8576081741.

Figura 24. Singleton na classe ControladorOperacaoImpl

Até o momento temos o MVC implementado e o nosso projeto plenamente funcional, porém
ainda falta explicar o motivo da classe ControladorPersistencia. Entramos finalmente na reta final
deste primeiro tutorial.

A interface ControladorPersistencia é ilustrada na Figura 25. Esta interface possui apenas dois
métodos (salvar e retornar) e permite inúmeras implementações. Neste primeiro tutorial iremos
implementar apenas a persistência como OBJETO SERIALIZADO no sistema de arquivos do seu
Sistema Operacional. A classe calculadora e o que calculadora possui (Operacao, por exemplo)
podem ser serializados facilmente, pois ou são tipos primitivos ou implementam Java Serializable
interface.
Figura 25. Interface ControloadorPesistencia

A implementação realizada neste primeiro tutorial é ilustrada nas Figuras 26 e 27. A classe
ControladorPersistenciaImpl usa as classes de I/O Java chamadas FileOutputStream e
FileInputStream. Tais classes permitem que objetos java sejam convertidos em arquivos binários e
salvos em disco facilmente. Buffers são usados e encapsulam a leitores de arquivos, permitindo
que a instrução oos.writeObject(calc); seja otimizada. Java permite um reuso absurdo quando o
assunto é I/O. Seu desenho permite o programador trocar facilmente leituras ou gravações de
arquivos, por leituras ou envios via socket (TCP) ou datagrama (UDP). Maiores detalhes sobre I/O
em Java no link http://docs.oracle.com/javase/tutorial/essential/io/. No próximo tutorial iremos
implementar a possibilidade de salvar Calculadora num banco de dados relacional (Oracle, MySQL
ou qualquer outro) e também a armazenar calculadora num cluster de PCs, usando para isto o
middleware JavaCá&Lá, projeto coordenado pelo prof. Joubert e distribuído gratuitamente no link
www.joubertlima.com.br/calapp.

Figura 26. Implementação da classe ControladorPersistencia para salvar objetos Java em disco
Figura 27. Implementação da classe ControladorPersistencia para recuperar objetos Java em disco

A interface ControladoraPeristencia é considerada classe de controle, assim como as classes


ControladoraCalculadora e ControladoraOperacao. Neste tutorial iremos chamar
ControladorPeristencia a partir da classe do pacote view chamada GUI_calculadora. A cada calculo
a classe ControladorPeristencia é usada para recuperar e salvar uma calculadora. No caso da
operação listar, usa-se ControladorPersistencia para recuperar uma calculadora. Na Figura 28
ilustramos como calcular uma operação a partir da GUI_calculadora.java.

Figura 28. Interação entre as classes GUI_calculadora e ControladorPersistencia

O arquivo calc1 criado em disco é ilustrado na Figura 29. O arquivo é a versão de Calculadora com
suas n operações armazenadas. Desta forma, podemos inicializar quantas vezes quisermos a
aplicação calculadora e NENHUMA OPERAÇÃO SE APAGARÁ, pois estão sempre armazenadas em
disco. Para inicializarmos a calculadora basta apagarmos o arquivo calc1 do diretório.

Figura 29. Arquivo calc1 gerado para persistir a calculadora e suas operações

Por fim, iremos criar um suíte de testes, facilitando desta forma a execução de testes em mais de
uma classe. Durante o ciclo de vida do projeto o suíte de testes deverá ser executado inúmeras
vezes. Qualquer nova implementação deverá ser acompanhada de um novo teste, porém não o
unitário e sim o suíte inteiro. Na Figura 30 ilustramos como criar um suíte de teste com o JUnit.

Figura 30. Como montar um suíte de teste no Eclipse


NO PROXIMO TUTORIAL:
1) NOVAS IMPLEMENTAÇÕES DE VIEWS (WEB E ANDROID)
2) NOVAS IMPLEMENTAÇÕES DE ControladorPersistencia para banco de
dados relacionais e ambientes distribuídos.

Das könnte Ihnen auch gefallen