Professional Documents
Culture Documents
Sumrio
Contedo sobre Boas Prticas, Artigo no estilo Soluo Completa
Casos de Uso
Este diagrama descreve o que o usurio pode fazer. Como exem-
plo, vejamos, na Figura 1, o primeiro caso de uso da aplicao em
desenvolvimento: Cadastro de Fornecedor.
Note que o usurio deve ter acesso a quatro funcionalidades
relacionadas entidade Fornecedor: criao, edio, excluso e
listagem.
A Figura 2 apresenta outro caso de uso, de nome Cadastro de
Unidade. Nele, de modo semelhante ao exemplo anterior, so
descritas as iteraes que o usurio do sistema ter com a enti- Figura 1. Caso de Uso Cadastro de Fornecedor
dade unidade. Assim, deve ser possvel criar, editar, excluir e
consultar unidades de medida, que sero usadas no cadastro de
produtos como ser mostrado mais frente.
Encerrando a modelagem dos casos de uso, especificamos ainda
os diagramas Cadastro de Produto e Cadastro de Pedido (vide
Figuras 3 e 4), que, como verificado, seguem a mesma tendncia
apresentada pelos outros exemplos.
Note que atravs dos casos de uso j estabelecemos uma diviso
para o sistema, de forma que o usurio possa modificar cada parte
do sistema separadamente. Com o auxlio destes, os diagramas
subsequentes na anlise consideram as informaes levantadas e
modelam outras caractersticas, como veremos a seguir.
Figura 2. Caso de Uso Cadastro de Unidade
Diagrama de Classes
atravs da criao de classes que a informao gerenciada pelo
sistema organizada em entidades separadas. Sabendo disso, para
que o software tenha um cdigo com boa legibilidade e fcil manu-
teno, cada entidade deve conter apenas os atributos e mtodos a
ela relacionados. A partir disso, para estabelecer o funcionamento
do sistema e tambm para compor entidades mais complexas, so
definidos os relacionamentos entre essas classes.
O diagrama de classes se encaixa exatamente nesse contexto e
nada mais do que uma forma de representar as classes/interfa-
ces, atributos, mtodos e relacionamentos de um sistema de forma
visual. A partir dele o desenvolvedor ter um mapa do que
implementar, o que facilita o trabalho de implementao e reduz
o risco de criar cdigos desnecessrios. A Figura 5 apresenta o Figura 3. Caso de Uso Cadastro de Produto
diagrama de classes da aplicao exemplo.
Note que organizamos os dados da aplicao em cinco entidades:
Fornecedor, Unidade, Pedido, ItemPedido e Produto. Alm disso,
especificamos seus atributos, mtodos e relacionamentos.
Ao analisar a entidade Fornecedor, por exemplo, verificamos
que ele tem os atributos codigoFornecedor, endereo, telefone e
nome. Como mtodos, foram especificados o criarFornecedor(),
editarFornecedor(), excluirFornecedor(), consultarFornecedor()
e consultarFornecedores(). Ademais, note que ele se relacionada
com a entidade Pedido. Com esta ligao estamos indicando que
um fornecedor pode ter zero ou muitos pedidos. Esta mesma lgi-
ca se aplica s demais entidades, respeitando sempre as diferenas
de cada tipo de relacionamento. Figura 4. Caso de Uso Cadastro de Pedidos
Fase de Projeto de Software dados, e uma classe DTO, que contm os atributos de cada entidade.
Concluda a fase de anlise, deve-se prosseguir para a fase de Em definio simples, um objeto DTO representa um objeto de
projeto de software, onde os diagramas obtidos anteriormente dados que pode ser enviado entre camadas distintas do software.
so convertidos em documentos ou outros diagramas de forma
que seja mais fcil ao programador se basear neles para realizar Criao do Banco de Dados
o desenvolvimento do software. Durante a fase de projeto so Uma vez que se tenha evoludo na especificao do diagrama
produzidos documentos e diagramas semelhantes aos da fase de classes da fase de projeto, pode-se partir para a criao das
de anlise, porm tal informao sofre um detalhamento maior tabelas no banco de dados, elementos que sero responsveis
e os processos so expandidos, muitas vezes empregando-se de pela persistncia dos objetos que forem criados durante o ciclo
pseudocdigo para descrever procedimentos. de vida do software.
Alm disso, na fase de projeto que so especificados os design Em muitos projetos, uma das primeiras coisas a serem defini-
patterns para facilitar e organizar a implementao do software, das o banco de dados. Nestes casos, comumente, um modelo
pois existe uma tendncia das classes originais conterem muita ER (Entidade Relacionamento) pode ser a nica documentao
informao pertencente a diferentes camadas da aplicao, o disponvel no sistema. Entretanto, essa estratgia no adequada,
que causa uma forte vinculao entre essas camadas e prejudica uma vez que antecipa e distorce o processo de desenvolvimento
diretamente a manuteno e legibilidade do cdigo. de software, alm de centralizar todo o conhecimento do sistema
Hoje j existem diversas formas de se organizar um software sobre as poucas pessoas envolvidas no processo de anlise.
em camadas. Dentre elas, uma das mais conhecidas o padro Outro aspecto importante em um projeto de software eficiente
Model-View-Controller, que amplamente empregado em Java para e robusto criar no banco de dados todas as verificaes neces-
organizar o software em camada de apresentao, de modelo e srias sobre os dados para evitar o estado inconsistente da base,
de controle. o que pode acontecer devido ao mau uso do sistema por parte do
Alm deste, outro padro bastante adotado o Data Access Ob- usurio ou em decorrncia de falhas no software, como bugs ou
ject, opo que leva a uma diviso das classes em uma estrutura falta de validaes de dados de formulrios.
que abstrai e reduz o acoplamento do cdigo com as tecnologias Portanto, importante criar corretamente as chaves primrias,
utilizadas para acesso a dados. chaves estrangeiras e chaves nicas (campos que no se repetem)
Em nosso exemplo, cada classe presente na Figura 5 ser refato- a fim de barrar na camada de persistncia a repercusso de even-
rada em duas: uma classe DAO, que contm os mtodos de acesso a tuais falhas que possam ocorrer nas outras camadas.
Para que DatabaseManager funcione corretamente, necessrio Listagem 3. Cdigo da classe FornecedorSQL.
ter o banco de dados MySQL instalado e em execuo com a base de 01. package database;
dados descrita na Listagem 1. A partir disso, para que a aplicao 02.
03. public class FornecedorSQL {
consiga se conectar base, deve-se adicionar o conector de acesso ao
04.
banco no classpath da aplicao. Este conector, tambm conhecido 05. public static String insert = insert into Fornecedor
como driver JDBC, pode ser baixado do site do MySQL. 06. + (codigoFornecedor, endereco, telefone, nome)
07. + values (?,?,?,?);
Na Listagem 2, o driver de acesso carregado na linha 6. Na
08.
linha 7, declarada a URL de acesso ao banco (repare no sufixo 09. public static String update = UPDATE Fornecedor SET +
o nome do banco), e nas linhas 8 e 9 so informados o usurio e 10. codigoFornecedor = ?, +
11. endereco = ?, +
a senha da base. 12. telefone = ?, +
Nesta classe tambm foram implementados os mtodos execu- 13. nome = ? +
teSQL() e executeQuery(), responsveis por executar diretamente 14. WHERE codigoFornecedor = ?;
15.
qualquer comando SQL (vide linhas 17 a 28), e o mtodo prepa- 16. public static String delete = delete from Fornecedor
rarStatement(), criado para que seja possvel preparar comandos 17. + where codigoFornecedor = ?;
SQL que so executados com frequncia mais alta e assim garantir 18.
19. public static String selectAll = select * from Fornecedor;
um melhor desempenho (vide linhas 30 a 34). 20.
Por fim, tem-se o mtodo setAutoCommit(), que permite 21. public static String select = select * from Fornecedor
criar transaes, ou seja, executar conjuntos de comandos SQL 22. + where codigoFornecedor = ?;
23. }
de forma atmica. Para tanto, basta iniciar a transao com
setAutoCommit(false), o que faz com que os prximos comandos Listagem 4. Cdigo da classe UnidadeSQL.
SQL enviados atravs da conexo com o banco de dados no sejam 01. package database;
executados prontamente, e terminar com setAutoCommit(true), 02.
o que efetiva todos os SQLs pendentes na conexo. 03. public class UnidadeSQL {
04.
Visto que optamos por usar PreparedStatements para otimizar a 05. public static String insert = insert into Unidade
eficincia da aplicao e do banco de dados, deixaremos os scripts 06. + (codigoUnidade, sigla, descricao)
SQL de criao, edio, excluso e consulta de registros de cada 07. + values (?,?,?);
08.
entidade em uma classe especfica. O primeiro exemplo disso 09. public static String update = UPDATE Unidade SET +
pode ser verificado na Listagem 3. 10. codigoUnidade = ?, +
O cdigo-fonte apresentado nessa listagem contm os comandos 11. sigla = ?, +
12. descricao = ? +
SQL voltados para as operaes bsicas de cadastro de fornece- 13. WHERE codigoUnidade = ?;
dores a serem usados em PreparedStatements. Note que para 14.
15. public static String delete = delete from Unidade
especificar os parmetros de cada comando so utilizadas inter-
16. + where codigoUnidade = ?;
rogaes, como demonstram as instrues de insert (linha 5), 17.
update (linha 9), delete (linha 16) e select (linhas 21). Observe 18. public static String selectAll = select * from Unidade;
19.
ainda que existem dois comandos select: um para consultar um
20. public static String select = select * from Unidade
fornecedor pelo cdigo (linha 21) e outro para consultar todos os 21. + where codigoUnidade = ?;
fornecedores (linha 19). 22. }
Uma melhoria que pode ser realizada ao esquema apresentado
adicionar o comando LIMIT nos SQLs de consulta, a fim de
evitar o alto uso de memria no caso de as tabelas conterem um De acordo com os padres selecionados na fase de projeto, esta
nmero muito grande de registros. camada ser dividida em DTOs e DAOs, artefatos que correspon-
De forma semelhante, na Listagem 4 so apresentados os coman- dem a objetos de transmisso de dados e objetos de acesso a dados,
dos SQL para o cadastro de unidades. Como o padro de consulta respectivamente. Comecemos a implementao, ento, pela classe
o mesmo, no necessrio explicar o seu cdigo. O mesmo vale FornecedorDto, que responsvel por conter todas as regras de
para as classes que implementam as operaes relacionadas a negcio relacionadas ao cadastro de fornecedores. O seu cdigo
produtos, pedidos e itens pedidos. O cdigo-fonte destas pode apresentado na Listagem 5 e para manter as boas prticas da
ser verificado no arquivo disponibilizado para download nesta organizao de pacotes, crie-a dentre do pacote negocio.dto.
edio. Como verificado, essa classe deve ser implementada de forma
que cada objeto contenha todos os dados relativos a um forne-
Camada de Negcio cedor, o que envolve os atributos codigoFornecedor, endereco,
Concluda a camada de persistncia, pode-se partir para a telefone e nome (vide linhas 4 a 7). Essa classe tambm contm o
camada de negcios, local onde devemos implementar, dentre construtor default (linhas 9 a 10), que possibilita criar um objeto
outras coisas, as regras de negcio da aplicao. sem informar os valores dos campos. Para definir o valor de cada
campo podem ser utilizados os respectivos setters, definidos nesta atravs de PreparedStatements os scripts SQL de insero, edio,
classe. E para recuperar o valor de um campo, pode ser utilizado excluso e consulta so executados mais rapidamente, pois o banco
o getter correspondente. de dados os mantm preparados em memria, alterando apenas
Outro mtodo presente na classe FornecedorDto o toString(). os parmetros a cada vez que so chamados.
Este retorna uma representao na forma de String do objeto e Os PreparedStatements declarados em UnidadeDao so inicia-
ser usado na camada de apresentao para criar uma descrio lizados no construtor atravs da chamada ao mtodo prepararS-
curta de um fornecedor. tatement(), da classe DatabaseManager, deixando os mesmos
Em seguida, classes semelhantes devem ser criadas para im- SQLs prontos no banco de dados para execuo quando a aplicao
plementar os DTOs das unidades de medida, produtos, pedidos estiver rodando. Assim no ser preciso construir novamente os
e itens pedidos. SQLs caso seja criada uma nova instncia de UnidadeDao. Note,
Como existe uma relao entre as classes Produto e Unidade, ainda, que a inicializao dos mesmos acontece no construtor.
conforme indicado no diagrama de classes (vide Figura 5), em Nas linhas 29 a 39 declarado o mtodo criarUnidade(). Este
ProdutoDto criada uma referncia para UnidadeDto, de forma recebe UnidadeDto como parmetro, a partir deste define os
que cada produto tenha uma unidade de medida. parmetros no PreparedStatement insert e executa o SQL para
O mesmo ocorre em PedidoDto, o qual, alm dos campos es- criar uma nova unidade de medida no banco de dados. De
pecificados no diagrama de classes, possui o campo fornecedor, forma anloga, os mtodos editarUnidade(), excluirUnidade()
de tipo FornecedorDto, por causa do relacionamento da classe e consultarUnidade() recebem um DTO como parmetro, ali-
Pedido com Fornecedor, sinalizando um pedido de compra. mentam o PreparedStatement com os valores por ele esperados
Concluindo a implementao dos DTOs, um raciocnio seme- e executam o SQL correspondente para aplicar as alteraes no
lhante pode ser verificado em ItemPedidoDto, que declara os banco de dados.
atributos produto e pedido, derivados dos relacionamentos de Uma exceo o mtodo consultarTodasUnidades(), que no
ItemPedido com Produto e Pedido. recebe parmetros por ser responsvel por consultar e retornar
Outro padro de projeto usado na aplicao exemplo o DAO. todos os registros da tabela Unidade.
Este define objetos que encapsulam o cdigo de acesso ao banco O cdigo de FornecedorDao segue a mesma proposta de Unida-
de dados. Para tanto, os DAOs acessam a camada de persistncia deDao e, portanto, no ser exibido. J o cdigo de ProdutoDao
para obter a conexo com o banco, executar SQLs para inserir, apresentado nas Listagens 8 e 9. Essa classe funciona de forma
editar, excluir ou consultar registros, entre outras funes. Nas anloga aos demais DAOs, porm o tratamento do seu campo
Listagens 6 e 7 apresentado o cdigo da classe UnidadeDao. unidade (do tipo UnidadeDto) diferente, uma vez que ele pro-
Nas linhas 13 a 17 dessa classe so declarados um PreparedS- veniente de um relacionamento entre as classes ProdutoDto e Uni-
tatement para cada SQL definido em UnidadeSQL, pertencente dadeDto. Sendo assim, o cdigo da unidade obtido atravs da
camada de persistncia. Um ganho importante com isso que chamada ao mtodo getCodigoUnidade() do objeto unidade.
Alm disso, nas consultas, para cada objeto do tipo ProdutoDto Concluda essa etapa, vlido ressaltar que podemos implemen-
criado, criado tambm um UnidadeDto, que consultado no tar o cdigo relacionado ao acesso a dados de uma maneira mais
banco de dados usando o DAO UnidadeDao informado no cons- simples, explorando frameworks Java criados exatamente com
trutor. Deste modo, a informao consultada no se restringe esse intuito. Um bom exemplo o Hibernate, que abstrai, dentre
apenas aos dados do produto, pois tambm so buscados os dados outras coisas, a necessidade de escrita do cdigo SQL. Dito isso,
da unidade de medida do mesmo. a partir de artigos j publicados nesta revista sobre esse tema, o
Com cdigo semelhante, temos ainda os DAOs PedidoDao e leitor pode buscar realizar essa refatorao em nosso exemplo e
ItemPedidoDao, que foram omitidos por questo de espao. consequentemente explorar novos conceitos.
Camada de Apresentao
A camada de apresentao proposta para a aplicao exemplo
foi implementada usando Swing. No entanto, outras tecnologias
poderiam ter sido empregadas como, por exemplo, AWT, JavaFX
ou, ainda, considerando-se que a camada de apresentao se
torne acessvel via web, tecnologias como JSP (JavaServer Pages) e
JSF (JavaServer Faces).
As telas da aplicao sero mostradas nas imagens a seguir,
mas o cdigo-fonte foi omitido, por no fazer parte do escopo
deste artigo. Na Figura 6 temos a tela principal do software, que
permite o acesso a todos os casos de uso da aplicao de controle
de estoque.
Ao selecionar a primeira opo, Cadastro de Fornecedor, a janela
exposta na Figura 7 apresentada a qual contm todos os casos
de uso relacionados a fornecedor (vide Figura 1) oferecendo
acesso s operaes de criao, edio e excluso de fornecedo-
res. O mesmo vale para as telas exibidas nas Figuras 8, 9 e 10,
Figura 6. Tela principal da aplicao exemplo que viabilizam o acesso s funcionalidades de listagem, criao,
edio e excluso de unidades de medidas, produtos e pedidos,
respectivamente.
Como verificado, a linguagem UML uma poderosa ferramenta
de modelagem de software e apresenta diversos diagramas que
auxiliam as atividades de desenvolvimento. Consequentemente,
sua adoo possibilita um aumento da qualidade da documen-
tao produzida nas fases de anlise e projeto, assim como uma
melhora da legibilidade e manutenibilidade do cdigo, da comu-
nicao entre os desenvolvedores, entre outros fatores.
Figura 7. Tela do cadastro de fornecedores Diante disso, empresas que primam por qualidade e bons pro-
jetos de software exigem dos desenvolvedores cada vez mais o
domnio dos principais diagramas dessa linguagem de modela-
gem, pois isso implica diretamente na boa converso dos mesmos
em cdigo-fonte correto e eficiente.
Autor
John Soldera
johnsoldera@gmail.com
Figura 8. Tela do cadastro de unidades de medida bacharel em Cincias da Computao pela UCS (Universidade
de Caxias do Sul), mestre em Computao Aplicada pela Uni-
sinos e doutor em Cincias da Computao pela UFRGS (Universidade
Federal do Rio Grande do Sul). Trabalha com Java h 12 anos e possui
a certificao SCJP.
Links:
O
desenvolvimento de software de qualidade
um processo que exige tempo e um elevado Fique por dentro
esforo por parte da equipe do projeto. Para A utilizao de padres de projeto permite o desenvolvimento de
manter o padro alto primordial evitar o uso de m- um cdigo limpo, flexvel e testvel, assim como facilita a comunica-
todos antiquados ou inapropriados, como codificar de o entre arquitetos e desenvolvedores ao viabilizar um vocabulrio
forma estruturada. Alm disso, necessrio escrever comum, amenizando possveis problemas de interpretao, algo
cdigo pensando tambm na sua facilidade de manu- presente em projetos de software. Com base nisso, este artigo til
teno e evoluo. Com essas medidas o processo de por apresentar uma maneira prtica para deteco de problemas de
desenvolvimento tende a se tornar mais caro, mas o design no cdigo e como refator-lo empregando boas prticas ao
custo para corrigir os problemas e manter o software introduzir padres de projeto ao ciclo de desenvolvimento.
ser ainda mais alto sem aplic-las.
Em sistemas em que no houve essa preocupao a
refatorao ser um processo bastante complexo ou mes- sibilita focar no que um objeto e qual comportamento ele ter
mo invivel, pois o cdigo provavelmente apresentar antes mesmo de comear a ser implementado.
baixa coeso, alto acoplamento, entre outros indcios J o encapsulamento consiste em adicionar segurana aplica-
que sinalizam a baixa qualidade. Em alguns casos chega o. Isso porque atravs deste conceito haver a separao entre
a ser mais aconselhvel criar um novo sistema do que aspectos externos e implementaes internas de um objeto, como
tentar modific-lo. viabilizado pelos modificadores de acesso. Assim, evita-se que o
Diante disso, aplicar tcnicas que amenizem a pro- software crie uma interdependncia excessiva, que normalmente
duo de cdigo ruim essencial, como a orientao a chamamos de alto acoplamento, entre objetos e que uma mudana
objetos e padres de projeto, utilizadas para alcanar possa gerar efeitos colaterais em todo o sistema.
um alto nvel de satisfao na produo do cdigo. Es- O conceito de herana, por sua vez, proporciona que estruturas
sas tcnicas, se aplicadas corretamente, permitiro um comuns sejam compartilhadas entre diferentes classes, e assim,
cdigo mais fcil de ser mantido. Alm disso, permitir mtodos e atributos podem ser reutilizados, evitando possveis
que o sistema seja estendido, isto , receba novas fun- problemas como cdigo duplicado.
cionalidades, de forma mais simples. Esses fundamentos da orientao a objetos, junto com os concei-
Com base no que foi apresentado, este artigo dar uma tos de padres de projeto, ajudaro o profissional a produzir um
viso geral sobre padres de projeto e como eles so cdigo de qualidade e a reduzir o esforo necessrio no decorrer
utilizados na linguagem Java. Em seguida, explanar do desenvolvimento do software e de sua manuteno.
sobre como refatorar um projeto exemplo aplicando os
padres Prototype, Strategy e Adapter. Padres de projeto ou Padres GoF
O conceito padro de projeto surgiu com o arquiteto austraco
Fundamentos da orientao a objetos Christopher Alexander. Ele constatou que por conta do emprego
O paradigma da orientao a objetos estabelece fun- de padres as cidades medievais eram mais bonitas e harmnicas.
damentos que influenciam diretamente a organizao e O resultado dessa observao foi a publicao do livro A Pattern
qualidade do cdigo, como abstrao, encapsulamento Language, em meados de 1970, em que ele apresenta como utilizar
e herana. O conceito da abstrao, por exemplo, pos- padres em construes futuras ou na melhoria das j existentes.
J no mbito da Engenharia de Software, o termo comeou a classe e objeto. A utilizao desses padres auxilia o sistema
ser utilizado por Kent Beck e Ward Cunningham, em meados de a ser independente de como seus objetos so criados, compos-
1980. Porm, somente em 1995, quando Erich Gamma, Richard tos e representados. Isso ocorre devido ao encapsulamento do
Helm, Ralph Johnson e John Vlissides publicaram o livro Design conhecimento sobre as classes concretas que sero usadas pela
Patterns Elements of Reusable Object-Oriented Software, considerado aplicao e tambm pela ocultao do modo como essas classes
a referncia mais importante sobre o assunto, os padres de projeto so criadas e formadas.
comearam a ter notoriedade na rea da computao. Aps isso, os A Tabela 1 apresenta os seis padres criacionais e os seus
autores ficaram conhecidos como a A Gangue dos Quatro, ou Gang objetivos.
of Four (GoF). Foi da que surgiu a nomenclatura Padres GoF.
O livro est dividido em trs categorias, a saber: padres de Padres estruturais
criao, estruturais e comportamentais. Ao todo so vinte e trs Como o prprio nome diz, os padres dessa categoria esto
padres catalogados e que descrevem solues para diversos relacionados com a estrutura dos objetos. Eles se preocupam com
problemas recorrentes durante o processo de desenvolvimento, a composio das classes e dos objetos e com o relacionamento
como ser visto a seguir. entre eles.
O objetivo destes padres, descritos na Tabela 2, facilitar o
Padres de criao design do sistema identificando maneiras de realizar o relaciona-
Os padres de criao tm a funo de abstrair o processo de mento entre as entidades, deixando o desenvolvedor livre desta
criao de objetos e podem ser divididos em duas categorias: preocupao.
A inteno da equipe, com isso, foi isolar pequenos trechos do Listagem 2. A implementao da classe Robo.
jogo a fim de identificar, com mais facilidade, problemas que pos-
public class Robo {
sam ser sanados com boas prticas. A primeira delas, inclusive,
acabou de ser citada: dividir para conquistar. static enum MovimentoEnum {
AGRESSIVO, DEFENSIVO, ALEATORIO
}
Listagem 1. Cdigo da classe Jogo que simula o tabuleiro de batalha dos robs.
private String nome;
public class Jogo {
// Cdigo com os demais atributos suprimido
public static void main(String[] args) {
//Cria uma instncia de rob public Robo() {
Robo rambo = new Robo(); inicializar();
rambo.setNome(Rambo); }
//Cria outra instncia de rob /**
Robo chuckNorris = new Robo(); * Resgata os dados de um banco de dados para inicializar o rob.
chuckNorris.setNome(Chuck Norris); * Todos os robs so iguais, exceto o nome!
*/
//Cria mais uma instncia de rob private void inicializar() {...}
Robo bigHero = new Robo();
bigHero.setNome(Big Hero 6); public void setNome(String string) {
this.nome = nome;
//Solicita que o rob se movimente de forma agressiva }
rambo.mover(Robo.MovimentoEnum.AGRESSIVO);
//Solicita que o rob se movimente de forma defensiva /**
chuckNorris.mover(Robo.MovimentoEnum.DEFENSIVO); * Executa o comando de movimentao.
//Solicita que o rob se movimente de forma aleatria * Pode ser um ataque, uma defesa ou movimentos aleatrios!
bigHero.mover(Robo.MovimentoEnum.ALEATORIO); *
} * @param acao A ao de movimentao.
} */
public void mover(MovimentoEnum acao) {
if (MovimentoEnum.AGRESSIVO.equals(acao)) {
J na Listagem 2, temos o cdigo da classe Robo. Em seu cons- // Algoritmo para movimentao agressiva
trutor, note que h uma chamada ao mtodo inicializar(), respon- } else if (MovimentoEnum.DEFENSIVO.equals(acao)) {
// Algoritmo para movimentao defensiva
svel por acessar um banco de dados e resgatar as informaes
} else if (MovimentoEnum.ALEATORIO.equals(acao)) {
necessrias para instanciar um rob, como fora e velocidade. // O algoritmo de movimentao aleatria implementado
O mtodo mover(), por sua vez, tem a responsabilidade de realizar // por terceiros atravs do mtodo MovimentoAleatorio.execute()
new MovimentoAleatorio().execute();
a movimentao do rob. Para isso, ele recebe como parmetro
}
qual tipo de movimento o rob dever executar. Ademais, esse }
mtodo tambm possui a implementao dos algoritmos referen- }
tes ao movimento solicitado. Note que para cada movimento h Listagem 3. Classe responsvel pelo algoritmo de movimentao aleatrio do
uma lgica implementada na estrutura condicional if/else. rob.
Perceba tambm que somente a lgica de movimento aleatrio
/**
(MovimentoEnum.ALEATORIO), no mtodo mover(), apresenta * Implementao da estratgia de movimento aleatrio.
um trecho de cdigo que invoca o mtodo MovimentoAleatorio. */
public class MovimentoAleatorio {
execute(). Isso ocorre devido ao uso de uma biblioteca de terceiros
que j implementava um algoritmo de movimentao aleatria public void execute() {
para um rob. Os demais algoritmos de movimentao no foram //Algoritmo para executar a movimentao aleatria
}
analisados e por isso o cdigo dos mesmos no foi exibido.
}
A Listagem 3 apresenta o cdigo da classe MovimentoAleatorio
e como verificado, o mtodo execute() implementa o algoritmo
que realiza a movimentao aleatria de um rob. Por se tratar O primeiro problema est relacionado forma como o objeto
de uma biblioteca de terceiros, a equipe de desenvolvimento no Robo criado, pois j que os robs so todos iguais (exceto pelo
tem acesso ao cdigo fonte com a implementao real da classe. nome) e o custo para criar um rob elevado, devido necessidade
Portanto no possvel realizar modificaes. de acesso ao banco de dados, este anti-pattern pode ser resolvido
Ao analisar o cdigo das Listagens 1, 2 e 3, repare que ele possui com a aplicao do padro de projeto Prototype. Atravs desse
uma srie de anti-patterns, isto , solues para resolver problemas padro os robs podero ser clonados, em vez de ser criada uma
aplicando prticas muito utilizadas, mas que apesar de aparen- nova instncia para cada um.
temente benficas, na verdade prejudicam a manutenibilidade, Outro ponto questionvel est relacionado ao mtodo mover().
flexibilidade, reuso, entre outros. Note que ele acopla todo o conhecimento de como um rob se
Aps a refatorao da classe Robo preciso atualizar o cdigo No primeiro caso, as opes para se deslocar de um lugar para
da classe Jogo para que faamos uso dos benefcios adquiridos outro podem variar de acordo com a preferncia do usurio, que
com a adoo de Prototype, como pode ser visto na Listagem 5. pode escolher fazer o caminho a p, carro ou nibus. Assim, con-
Esta alterao consiste em criar somente um objeto rob utili- forme a estratgia escolhida, o caminho para chegar ao destino
zando o operador new. Os demais robs sero criados a partir pode ser diferente.
do mtodo clone(). J para o segundo caso (a ordenao de elementos em uma lis-
ta), lembre-se que pode haver uma quantidade muito grande de
Listagem 5. Refatorao do jogo para utilizao do mtodo clone(). algoritmos de ordenao implementados e que eles podem ser
escolhidos de acordo com cada situao.
public class Jogo {
Aplicando os conceitos desse padro para soluo do problema
public static void main(String[] args) { arquitetural do mtodo mover() (vide Listagem 2), a primeira
//Cria a instncia prottipo
Robo robo = new Robo();
alterao a ser realizada criar as estratgias de movimentao
dos robs, conforme apresentado na Listagem 6.
//Cria um novo rob atravs do clone da instncia prottipo A interface MovimentoStrategy representa o artefato Strategy
Robo rambo = robo.clone();
rambo.setNome(Rambo); exposto no diagrama da Figura 1, e o mtodo executar() o res-
ponsvel pela implementao da estratgia de movimentao.
Robo chuckNorris = robo.clone();
chuckNorris.setNome(Chuck Norris);
/**
Aplicando o padro Strategy * Interface que define a assinatura do mtodo a ser
O padro Strategy trata diretamente de problemas relacionados * adotado para implementao das estratgias
*/
ao acoplamento do cdigo. Ele resolve esses problemas ao definir public interface MovimentoStrategy {
uma famlia de algoritmos, encapsular cada um deles e os tornar
/**
intercambiveis. Assim, estabelecida uma separao dos algo- * Execuo da movimentao definida pela estratgia.
ritmos de quem os usa, separao esta que possibilita escolher */
public void executar();
qual algoritmo utilizar de forma dinmica. Por exemplo, a opo }
de gravar informaes em um banco de dados ou em disco rgido
pode variar de acordo com a disponibilidade de espao. /**
* Implementao da estratgia de movimento agressivo.
Portanto, a abordagem proposta na definio do Strategy aco- */
plar a classe que far uso dos algoritmos apenas a uma abstrao e public class MovimentoAgressivo implements MovimentoStrategy{
//Cdigo suprimido...
/**
* Executa o comando de movimentao, sem ter o conhecimento
* de sua implementao.
*/
public void mover(MovimentoStrategy movimento) {
//Faz alguma coisa
movimento.executar();
//Faz mais alguma coisa Figura 3. Diagrama do padro Adapter Fonte: http://www.dofactory.com
}
/** Listagem 8. Refatorao para adequar a chamada ao mtodo mover com as
* Cria e retorna a cpia do objeto Robo estratgias.
*/
@Override public class Jogo {
protected Robo clone(){
return this.clone(); public static void main(String[] args) {
} //Cria a instncia prottipo
} Robo robo = new Robo();
da padronizao realizada pela ABNT. Aps a padronizao, os Listagem 10. Classe com a refatorao para adaptar o movimento aleatrio.
produtos devem ter somente os plugues com a nova forma de trs
public class Jogo {
pinos redondos. Porm, muitas residncias no possuem tomadas
de trs pinos para receber os aparelhos com esse tipo de plugue public static void main(String[] args) {
e para isso necessrio um adaptador. //Cria a instncia prottipo
Robo robo = new Robo();
J um exemplo no desenvolvimento de software pode ser
demonstrado no nosso jogo de robs. Lembra que a adoo do //Cria um novo rob atravs do clone da instncia prottipo
Robo rambo = robo.clone();
padro Strategy impossibilitou o uso da classe MovimentoAle- rambo.setNome(Rambo);
atorio? A aplicao do Adapter pode solucionar esse problema.
Robo chuckNorris = robo.clone();
Correlacionando os artefatos desse padro ao nosso exemplo, a chuckNorris.setNome(Chuck Norris);
interface MovimentoStrategy corresponde Target, e a classe
MovimentoAleatorio corresponde Adaptee. Para completar, Robo bigHero = robo.clone();
bigHero.setNome(Big Hero 6);
necessrio implementar a classe que far a adaptao de Mo-
vimentoAleatorio para ser utilizada junto s outras estratgias /**
* O mtodo mover agora recebe a estratgia de movimentao,
definidas pelo padro Strategy. * ao invs de necessitar implementar o movimento.
Para isso, criamos a classe MovimentoAleatorioAdaptado, */
rambo.mover(new MovimentoAgressivo());
apresentada na Listagem 9. Ela deve implementar a interface chuckNorris.mover(new MovimentoDefensivo());
MovimentoStrategy e encapsular MovimentoAleatorio. Assim o
jogo poder fazer uso do movimento fornecido por essa classe. /**
* A classe de movimento aleatrio agora est adaptada
* interface MovimentoStrategy, permitindo o seu uso
Listagem 9. Classe para adaptar MovimentoAleatorio. * no mtodo de movimentao do rob.
*/
/** bigHero.mover(new MovimentoAleatorioAdaptado());
* Adaptador para encapsular a classe de movimento aleatrio }
* em uma estratgia }
*/
public class MovimentoAleatorioAdaptado implements MovimentoStrategy{
Eles podem ser aplicados em situaes do cotidiano, como de-
private MovimentoAleatorio comportamento;
monstrado no artigo. E em sistemas computacionais, saiba que eles
@Override no foram especificados para serem aplicados em uma linguagem
public void executar() {
comportamento.execute();
de programao especfica. Uma prova disso que no livro de
} referncia do GoF os exemplos so ilustrados em C++.
}
Autor
Por fim, a classe Jogo (vide Listagem 10) precisa ser refatorada
Gabriel Feitosa
mais uma vez para que faa uso da nova classe Movimento- gabfeitosa@gmail.com www.gabrielfeitosa.com
AleatorioAdaptado. Pronto! Com isso, todas as estratgias de Bacharel em Cincia da Computao pela Universidade Federal
movimentao voltam a ser utilizadas. de Campina Grande (UFCG), Ps-Graduando em Engenharia de
Escrever cdigo de qualidade depende de fatores como experi- Software na Faculdade 7 de Setembro (FA7), engenheiro de software,
ncia da equipe de desenvolvimento e da aplicao de conceitos j desenvolve aplicando conceitos como TDD e reviso em pares, especialista
difundidos, como o caso dos padres de projetos. Como prova em Java e em aplicaes que utilizam o conceito de Single-Page Application (SPA).
disso, a refatorao que foi realizada no cdigo do jogo resultou
em um cdigo menos acoplado, mais coeso e possibilitou a reduo Links e Livros:
no processamento para se criar objetos complexos.
Alm disso, ficou muito mais simples criar novas possibilidades de Exemplos prticos de padres de projetos com foco na plataforma Java. http://
movimentao para o rob e de test-las. Isso ocorreu devido ao iso- www.tutorialspoint.com/design_pattern/index.htm
lamento dos algoritmos de movimentao em classes separadas. Coletnea de exemplos prticos com UML de padres de projetos aplicados
Ainda que padres de projeto sejam solues abstratas para a linguagem Java.
resoluo de determinados problemas, eles so uma referncia http://www.oodesign.com/
que auxilia o profissional a produzir cdigo de melhor qualidade. Design Patterns: Elements of Reusable Object-Oriented Software, Erich Gamma,
Ademais, eles propiciam uma linguagem de comunicao comum Richard Helm, Ralph Johnson, John Vlissides, Addison-Wesley, 1995.
a ser utilizada pelos desenvolvedores para debater a resoluo de Livro de referncia quando o assunto padres de projeto.
problemas na construo de sistemas computacionais. Head First Design Patterns, Eric Freeman, Elisabeth Robson, Bert Bates, Kathy
Lembre-se que os padres de projeto no foram definidos apenas Sierra, 2004.
para serem utilizados no mbito computacional. Livro que exemplifica os padres usando comparaes com o mundo real.
A Figura 6 demonstra o fluxo do nosso projeto exemplo, ilus- As camadas de modelo e persistncia
trando seus estados e transies. Vamos iniciar a nossa implementao criando, dentro do pacote
model, a classe Docente, nico JavaBean do nosso projeto. Sen-
do assim, com o boto direito sobre o pacote, selecione a opo
New > Class. Em seguida, digite o nome Docente e clique em Finish.
O cdigo-fonte desse artefato pode ser visto na Listagem 3. Nele,
podemos observar anotaes (vide BOX 3) do Hibernate que asso-
ciam esta classe/entidade sua respectiva tabela no banco de dados
(atravs da anotao @Table). Como podemos observar tambm, cada
atributo da classe associado a um campo em sua respectiva tabela,
por meio da anotao @Column. Finalizando, vamos configurar o
mapeamento objeto-relacional de Docente no arquivo hibernate.cfg
.xml, para habilitar o Hibernate a persistir os objetos no banco de
dados, o que pode ser feito com o cdigo da Listagem 4.
BOX 3. Anotaes
Anotaes so recursos para a declarao de metadados dados que descrevem outros dados
teis para localizar dependncias, configuraes ou para fazer verificaes lgicas. Essas definies
sero, ento, interpretadas pelo compilador para realizar uma determinada tarefa.
import br.com.devmedia.gestaoacademicaweb.Docente;
Implementando o fluxo com o Spring Web Flow
Com as camadas de modelo, controle, servio e persistncia con-
public interface DocenteService { cludas, j possvel implementar o fluxo da aplicao, bem como
public void adicionarDocente(Docente docente);
public void removerDocente(int id); a camada de viso, que conter as pginas que correspondero
public List<Docente> listarDocentes(); aos estados declarados no fluxo.
}
Para manter o cdigo estruturado alm de permitir um even-
Listagem 8. Cdigo-fonte da implementao do servio DocenteServiceImpl. tual reuso dos fluxos criados recomendamos a criao de um
arquivo XML para cada fluxo da aplicao. No nosso caso arma-
package br.com.devmedia.gestaoacademicaweb.service;
zenaremos estes arquivos XML dentro de WEB-INF/flows.
import java.util.List; Dito isso, dentro do diretrio flows crie o arquivo inserirDocente
import br.com.devmedia.gestaoacademicaweb.Docente;
import br.com.devmedia.gestaoacademicaweb.dao.DocenteDAO;
.xml, o que feito clicando com o boto direito sobre este diretrio
import org.springframework.beans.factory.annotation.Autowired; e selecionando New > File. Uma vez que necessrio realizar as
import org.springframework.stereotype.Service; configuraes correspondentes ao SWF no arquivo spring-context.
import org.springframework.transaction.annotation.Transactional;
xml, ainda no alteraremos o XML recm-criado. Vamos, agora,
@Service modificar as configuraes do Spring alterando seu arquivo de con-
public class DocenteServiceImpl implements DocenteService {
figurao para que fique conforme demonstrado na Listagem 10.
@Autowired As principais modificaes que fizemos em spring-context.
private DocenteDAO docenteDAO;
xml para configurar o SWF se referem ao mapeamento dos
@Transactional fluxos que nosso website possui. No nosso caso chamamos o
public void adicionarDocente(Docente docente) {
fluxo de inserirDocente. Podemos verificar sua descrio no n
docenteDAO.adicionarDocente(docente);
} <webflow:flow-registry>, onde h a declarao <webflow:flow-
@Transactional location path=/W EB -I N F / f lows / inse r irDoc e nte. x ml
public void removerDocente(int id) {
docenteDAO.removerDocente(id); id=inserirDocente />, que especifica que o fluxo identificado
} por inserirDocente est declarado no arquivo de mesmo nome,
@Transactional com extenso XML, localizado em /WEB-INF/flows/.
public List<Docente> listarDocentes() { Seguindo em frente, declaramos os controllers da nossa aplica-
return docenteDAO.listarDocentes();
}
o utilizando a tag <bean>, como verificado no trecho <bean
name=docenteController class=br.com.devmedia.gestaoaca-
} demicaweb.control.DocenteController />. Vale lembrar que no
Listagem 9. Cdigo-fonte da classe DocenteController. nosso exemplo temos apenas um controller, que ser identificado
pelo nome docenteController.
package br.com.devmedia.gestaoacademicaweb.control;
No mais, foram includas em spring-context.xml as configuraes
import java.util.*; padro do SWF, especialmente das classes FlowHandlerMapping
import org.springframework.beans.factory.annotation.Autowired;
e FlowHandlerAdapter, os chamados flow handlers do Spring
import org.springframework.stereotype.Controller;
import br.com.devmedia.gestaoacademicaweb.model.Docente; Web Flow.
import br.com.devmedia.gestaoacademicaweb.service.DocenteService;
Listagem 10. Cdigo-fonte do arquivo spring-context.xml, incluindo as configu- Listagem 11. Cdigo-fonte do formulrio de cadastro de docentes.
raes do SWF.
<%@taglib uri=http://www.springframework.org/tags prefix=spring%>
<?xml version=1.0 encoding=UTF-8?> <%@taglib uri=http://www.springframework.org/tags/form prefix=form%>
... <html>
<context:annotation-config /> <head>
<context:component-scan base-package=br.com.devmedia.gestaoacademicaweb /> <title>Cadastro de Docentes</title>
</head>
<body>
<bean id=jspViewResolver
class=org.springframework.web.servlet.view.InternalResourceViewResolver>
<h3>Formulrio de Cadastro de Docentes</h3>
<property name=viewClass
value=org.springframework.web.servlet.view.JstlView /> <form:form method=post modelAttribute=docenteModel>
<property name=prefix value=/WEB-INF/views/ />
<property name=suffix value=.jsp /> <table>
</bean> <tr>
<td>Nome:</td>
<bean id=propertyConfigurer <td><form:input path=nome /></td>
class=org.springframework.beans.factory.config.PropertyPlaceholderConfigurer </tr>
p:location=/WEB-INF/jdbc.properties /> <tr>
<td>Matrcula:</td>
<bean id=dataSource <td><form:input path=matricula /></td>
</tr>
class=org.apache.commons.dbcp.BasicDataSource destroy-method=close
<tr>
p:driverClassName=${jdbc.driverClassName}
<td>Titulao:</td>
p:url=${jdbc.databaseurl} p:username=${jdbc.username}
<td><form:input path=titulacao /></td>
p:password=${jdbc.password} /> </tr>
<tr>
<bean id=sessionFactory <td>
class=org.springframework.orm.hibernate4.LocalSessionFactoryBean> <input type=submit name=_eventId_inserir value=Salvar/>
<property name=dataSource ref=dataSource /> </td>
<property name=configLocation> <td>
<value>classpath:hibernate.cfg.xml</value> <input type=submit name=_eventId_cancelar value=Cancelar/>
</property> </td>
</tr>
<property name=hibernateProperties> </table>
</form:form>
<props>
<prop key=hibernate.dialect>${jdbc.dialect}</prop>
</body>
<prop key=hibernate.show_sql>true</prop>
</html>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id=transactionManager
class=org.springframework.orm.hibernate4.HibernateTransactionManager>
<property name=sessionFactory ref=sessionFactory />
</bean>
<webflow:flow-executor id=flowExecutor/>
<webflow:flow-registry id=flowRegistry>
<webflow:flow-location path=/WEB-INF/flows/inserirDocente.xml
id=inserirDocente />
</webflow:flow-registry>
Figura 7. Formulrio de cadastro de docentes
<bean class=org.springframework.webflow.mvc.servlet.FlowHandlerMapping>
<property name=flowRegistry ref=flowRegistry/>
Para construir esse formulrio fizemos uso dos pacotes de taglibs
<property name=order value=0/>
</bean> do Spring; em especial, do pacote form, como mostrado nos
trechos de cdigo iniciados por <form:input>. Essa taglib utili-
<bean class=org.springframework.webflow.mvc.servlet.FlowHandlerAdapter> zada para criar os campos do formulrio conforme verificado em
<property name=flowExecutor ref=flowExecutor/>
<form:input path=nome />. J a associao entre os formulrios
</bean>
e as respectivas classes na camada de modelo feita por meio da
<bean name=docenteController class=br.com.devmedia.gestaoacademicaweb propriedade modelAttribute na tag <form>, como vemos em
.control.DocenteController /> <form:form method=post modelAttribute=docenteModel>.
</beans>
Nesse trecho constatamos que o formulrio de cadastro de do-
dispar-lo. Por exemplo, o boto Salvar no formulrio de cadastro <%@taglib uri=http://java.sun.com/jsp/jstl/core prefix=c%>
de docentes identificado por _eventId_inserir, como pode ser vis-
to no trecho <input type=submit name=_eventId_inserir <html>
<head>
value=Salvar/>. <title>Listagem de Docentes</title>
Agora vamos criar os arquivos cancelado.jsp e listar_docentes. </head>
jsp, que representam, respectivamente, a pgina de resposta de <body>
</body>
</html>
utilizamos os ns <view-state> e <end-state> para declarar Para isso, especificamos o n <evaluate>, como mostra o trecho <eva-
esses estados. luate expression=docenteController.adicionarDocente(docente-
Por sua vez, especificamos o handler do formulrio de cadastro Model)/>. Esse recurso utilizado novamente na listagem de docen-
de docentes com o n <action-state>, no trecho <action-state tes, conforme a marcao <evaluate expression=docenteController
id=inserirDocenteAction>, e definimos as transies em ns .listarDocentes() result=viewScope.docenteList/>, que faz com
<transition>. A propriedade on de uma transio indica em que que o mtodo listarDocentes() seja executado na renderizao da
evento ela deve ser disparada; enquanto a propriedade to, para listagem de docentes.
qual estado o usurio direcionado. Por exemplo, na marcao Nesse segundo exemplo vemos outro recurso do SWF ser
<transition on=cancelar to=cancelado />, uma vez dispa- utilizado: o retorno do mtodo armazenado em uma vari-
rado o evento cancelar o usurio ser encaminhado para o estado vel que pode ser acessada na camada de viso. A propriedade
cancelado. result da tag <evaluate> define o armazenamento do retorno
do mtodo listarDocentes() em uma varivel chamada do-
centeList. Nesse trecho, note que tambm indicado o escopo
Listagem 14. Cdigo-fonte do fluxo inserirDocente.xml.
da varivel (viewScope, que significa que a varivel estar
<?xml version=1.0 encoding=UTF-8?> disponvel apenas no estado em que ela foi declarada; no caso,
a view-state listar). Outros escopos existem, mas no os explo-
<flow xmlns=http://www.springframework.org/schema/webflow
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance ramos nesse artigo.
xsi:schemaLocation=http://www.springframework.org/schema/webflow Com isso, a ltima coisa que falta para nosso projeto ser concludo
http://www.springframework.org/schema/webflow/
spring-webflow-2.0.xsd>
criar o banco de dados. Para tanto, vamos usar o script de criao
da tabela descrito na Listagem 15. Com isso nosso exemplo est
<var name=docenteModel class=br.com.devmedia.gestaoacademicaweb.model. pronto para ser testado, o que pode ser feito aps iniciar o Tomcat e
Docente/>
digitar, no navegador, a URL http://localhost:8080/inserirDocente.
<view-state id=form view=/WEB-INF/views/inserir_docente_form.jsp
model=docenteModel>
Listagem 15. Script de criao da tabela DOCENTES.
<transition on=inserir to=inserirDocenteAction />
<transition on=cancelar to=cancelado />
CREATE TABLE DOCENTES (
</view-state>
ID INT PRIMARY KEY AUTO_INCREMENT,
NOME VARCHAR(100),
<action-state id=inserirDocenteAction>
MATRICULA VARCHAR(100),
<evaluate expression=docenteController.adicionarDocente(docenteModel) />
TITULACAO VARCHAR(100)
<transition to=listar />
);
</action-state>