21 de fev. de 2008

Padrões de Projeto - Gerador de Gráficos com Template Method


Dae gurizada...

Algum tempo atrás eu e um amigo, Marcos Brião, fizemos uma oficina (workshop) na Confraria do Java, grupo de estudos da Ulbra em Canoas/RS, sobre Desgin Patterns.


Esses dias tava revirando meus arquivos e encontrei essa apresentação. Nessa oficina fizemos um Gerador de Gráficos simples com alguns patterns. O sistema ficou bem interessante.

Screenshot:



Faça os downloads:


Essa aplicação basicamente gera gráficos com informações digitadas na tela. Com o uso de Design Patterns como Template Method e Facade, conseguimos ter uma aplicação fácil de fazer manutenção e entendimento.
Utilizamos o framework JFreeChart(link) para gerar os gráficos.


Esse é o diagrama de classes:





Template Method
Definição:
Definir o esqueleto de um algorítimo em uma operação, postergando (deferring) alguns passos para subclasses. Template Method (Gabaríto de Método) permite que subclasses redefinam certos passos de um algorítimo sem mudar a estrutura do mesmo.

Padroes de Projeto -GoF
Vamos imaginar um algorítimo qualquer, com esse exemplo, gerar gráficos.

Quando vamos gerar gráficos a lógica para criar o ojeto JFreeChart é sempre a mesma. A única parte que muda, de um gráfico para outro, é quando vamos adicionar os dados ao gráfico.

Nesse contexto poderíamos ter uma classe que faria a lógica para gerar o gráfico e quando fosse adicionar dados, passaria a responsabilidade para uma classe filha.

Fizemos exatamente isso. Temos uma classe
abstrata chamda GraficoTemplate, que tem a lógica para gerar os gráficos.

Veja a classe:


Como vocês podem ver essa clase é bem simples.

Temos um método criarGráfico, que recebe uma lista de dados e retorna um objeto JFreeChart. Esse método esta declarado como final. Isso significa que nenhuma classe que extender esa classe poderá alterar essa lógica. Esse detalhe do método ser final não faz parte do padrão Template Method.

Dentro do método criarGrafico eu chamo dois métidos: "carregarDados" e "configurarLegenda".
O método "configurarLegenda" é implementado dentro dessa classe mesmo. Ou seja, tem uma implementação padrão, mas qualquer classe que pode sobrescrever o método e alterar essa configuração de legenda.

O método "carregarDados", muita anteção! Aqui que está o Pattern.

Viu que o método esta marcado como "abstract" e por isso não tem implemetação ?

Na linguagem java todo método declarado como "abstract" indica que esse método deverá ser implementado na primeira classe concreta que estender essa classe.

O comportamento é igual ao de uma interface. Até por que uma interface, para o compiladora java, é uma classe abstrata com métodos abstrados, mas isso é outra história.
Vamos ver uma classe que estende a GraficoTemplate.

Vamos ver a classe que gerar o grafico de Pizza:


A classe GraficoPizza estende a GraficoTemplate e, obrigatoriamente, implementa o método "carregarDados(List dados)".

É aqui, na classe filha, que é definido como será carregado o gráfico.

Simplesmente itero a lista e populo o objeto "grafico", que está definido como protected na classe GraficoTemplate.

Veja que nessa implementação eu usso o método "createPieChart3D" da classe ChartFactory.

Quando fomos implementar outra classe, como a GraficoLinha, esse método "carregarDados" será diferente.

Veja:


A implementação do método "carregarDados" na classe "GraficoLinha" está um pouco diferente.


Esse exempo é bem simples. Mas se você conseguiu entender a "lógica"do pattern com certeza irá utlizar muitas vezes esse.

O que fizemos aqui é delegar parte da lógica de gerar gráficos para suas classes filhas.

Você pode estar pensando que a lógica que está no classe GraficoTemplate é bem simples. E realmente é. Mas poderías implementar nela outros métodos como alterar as cores do gráfico, definir um padráo de tamaho, etc..

Isso seria simples e se aplicaria a todos os gráficos da aplicação.


Esse exemplo foi construído para explicar, de forma simples, a lógica de 1 padrão de projeto e como é vantajoso sua utilização.

Tem pontos da aplicação que estão "feias" quanto a Design. Como por exemplo, não ter utilizado interfaces e utlizar Array de object para transferir dos dados da View para os gráficos.


Mas, nem tudo é perfeito...heheheh

Conforme irei estudando os Design Patterns vou postando ai...

Mais uma vez: Críticas sempre são bem vindas, obrigado.

Abraço a todos!

2 comentários:

Alexandre Simundi disse...

Quem tiver dúvida sobre o JFreeChart pode postar aqui ou mandar e-mails.
Abraço!

Anônimo disse...

Olá Alexandre, td bem?

Bom, meu problema é o seguinte:
Meu programa faz a conexão com o banco realizando uma consulta. O resultados desta consulta(no caso as tabelas), sõa colocados em uma tabela no meu jframe.
Em função desta tabela, é gerado um gráfico de linhas(que possui uma linha somente), só que por ter muitos dados nesta table, não dá p/ ver a legenda do eixo X.
Vc tem alguma idéia como posso classificar esta legenda? Por exemplo:de 10.000 em 10.000. Teria como fazer isso???

Bom, se vc ppuder me ajudar, ficarei muito grata...


Meu e-mail: nathalyawislet@gmail.com