Framework para Camada de Apresentação - Projetos

Propaganda
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE CIÊNCIAS DA COMPUTAÇÃO
Framework para Camada de
Apresentação
Claudio Ulisses Nunes Biava
Florianópolis
2004
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE CIÊNCIAS DA COMPUTAÇÃO
Framework para Camada de
Apresentação
Claudio Ulisses Nunes Biava
Orientador: Raul Sidnei Wazlawick
Banca Examinadora:
João Bosco M. Sobral
Mario Dantas
Florianópolis
2004
Aquilo que não nos mata, nos faz mais forte.
(Friedrich Nietzsche)
A mente que se abre a uma nova idéia jamais volta ao seu tamanho original.
(Albert Einstein)
Agradeço aos meus pais pelo investimento,
carinho e amor e confiança depositados em mim.
Ao meu orientador por ter me aceito como seu orientando.
Ao corpo docente pelo conhecimento a mim transmitido.
Sumário
Resumo ................................................................................................................................... 8
Abstract................................................................................................................................... 9
1. Apresentação .................................................................................................................. 1
1.1.
Motivação ............................................................................................................... 1
1.2.
Objetivos do Trabalho ............................................................................................ 1
1.3.
Justificativa............................................................................................................. 2
2. Padrões de Projetos......................................................................................................... 3
2.1.
Histórico ................................................................................................................. 3
2.2.
Padrão Observador ................................................................................................. 4
2.3.
Padrão Command ................................................................................................... 4
2.4.
Padrão Template Method ....................................................................................... 5
2.5.
Padrão Singleton..................................................................................................... 6
2.6.
Padrão Arquitetural MVC(Model View Controller) .............................................. 6
2.6.1.
Definições....................................................................................................... 7
2.6.2.
Como funciona ............................................................................................... 8
3. Frameworks Orientados a Objetos ............................................................................... 10
3.1.
Definição .............................................................................................................. 10
3.2.
Qualidade de um bom Framework ....................................................................... 11
3.2.1.
Generalidade................................................................................................. 11
3.2.2.
Alterabilidade ............................................................................................... 12
3.2.3.
Extensibilidade ............................................................................................. 12
3.2.4.
Simplicidade ................................................................................................. 12
3.2.5.
Clareza.......................................................................................................... 12
3.2.6.
Fronteiras ...................................................................................................... 12
4. Estudo do Framework Struts ........................................................................................ 14
4.1.
Projeto Jakarta ...................................................................................................... 14
4.2.
Framework Struts ................................................................................................. 14
4.2.1.
Introdução..................................................................................................... 14
4.2.2.
Motivação para criação do Framework Struts.............................................. 15
4.2.3.
Estrutura do Framework Struts..................................................................... 15
4.2.4.
Como funciona o struts................................................................................. 16
4.2.5.
Struts versus Framework Desenvolvido ....................................................... 17
5. Uso de Frameworks ...................................................................................................... 19
5.1.
Indivíduos Envolvidos com o Desenvolvimento e Uso de Frameworks.............. 19
5.2.
Questões-Chave para Usar um Framework .......................................................... 20
6. Framework Desenvolvido ............................................................................................ 22
6.1.
As principais classes do Framework .................................................................... 22
6.2.
Vantagens em usar o Framework ......................................................................... 22
6.3.
Estrutura do Framework ....................................................................................... 23
6.3.1.
Criação do model (modelo) .......................................................................... 24
6.3.2.
Criação da view (visão) ................................................................................ 24
6.3.3.
Criação da aplicação..................................................................................... 24
6.3.4.
Criando um novo Controlador...................................................................... 25
Criando uma aplicação sob o Framework Bmvc.......................................................... 26
7.1.
Criando a estrutura de diretórios .......................................................................... 26
7.2.
Criando a aplicação .............................................................................................. 26
7.2.1.
Criando a classe modelo ............................................................................... 26
7.2.2.
Criando as Views.......................................................................................... 28
7.2.2.1.
Criando a classe View Principal............................................................... 28
7.2.2.2.
Criando a classe View EnqueteResultadoView ....................................... 31
7.2.3.
Criando a classe Aplicação........................................................................... 33
8. Conclusão ..................................................................................................................... 36
9. Referências ................................................................................................................... 37
10.
Anexo A – Artigo ..................................................................................................... 39
11.
Anexo B – Código Fonte das Principais Classes...................................................... 44
7.
Lista de Figuras
Figura 1 – Aplicação sendo exibida por várias interfaces ...................................................... 7
Figura 2 - Fluxo de eventos e informações em uma arquitetura MVC .................................. 8
Figura 3 – MVC em nível de aplicação.................................................................................. 8
Figura 4 - Visão Conceitual da estrutura um Framework .................................................... 11
Figura 5 - Visão do framework Struts e do MVC. ............................................................... 15
Figura 6 – Struts e MVC ...................................................................................................... 16
Resumo
Frameworks orientados a objetos promovem reuso de projeto e código. Contudo, a
ampla adoção desta abordagem é dificultada pela complexidade para desenvolver e para
usar frameworks.
Este trabalho apresenta o framework Bmvc que é um framework para camada de
apresentação baseado na arquitetura MVC (Model View Controller).
Será abordado Design Patterns (Padrões de Projeto) que foram utilizados para
desenvolver o framework.
E finalmente será criado uma aplicação utilizando o framework Bmvc e explicando
passo a passo como fazê-la.
Palavras-Chaves: framework orientados a objetos, reuso, MVC, Design Patterns
Abstract
Object-oriented frameworks promote reuse design and code. However, the widespread
adoption of this approach is made difficult by the complexity to develop and to use
frameworks.
This work presents the framework Bmvc that is a framework for presentation layer
based on the architecture MVC (Model View Controller).
It will be approach Design Patterns that were used to develop the framework.
And finally will be created an application using framework Bmvc and explaining step
by step as to make it.
Keywords: Objects-oriented frameworks, reuse, MVC, Design Patterns.
1. Apresentação
Este projeto é referente ao trabalho de conclusão do curso de Ciências da Computação
da Universidade Federal de Santa Catarina. Este tem como propósito o desenvolvimento de
um framework para camada de Apresentação.
1.1. Motivação
O desenvolvimento de Frameworks se torna cada vez mais comum e necessário uma
vez que existe uma necessidade de criar sistemas corporativos de modo mais rápido e a um
baixo custo e de fácil manutenção.
Framework é o esqueleto-base sobre o qual uma aplicação é construída, constituída de
uma estrutura de classes com implementações incompletas, que estendidas permitem
produzir novos aplicativos. A grande vantagem desta abordagem é a reutilização de código
e projeto, que tem por intuito diminuir o tempo e o esforço no desenvolvimento de
softwares.
Este trabalho tem como objetivo implementar um framework para desenvolvimento de
um Framework para Camada de Apresentação utilizando padrão arquitetural MVC (Model
View Control). Seu desenvolvimento foi motivado pela necessidade de separar interface de
código, ou seja, de se criar códigos de aplicações genéricos, não para interface especificas.
1.2. Objetivos do Trabalho
Este trabalho tem como objetivo implementar um framework que facilite no
desenvolvimento de aplicativos, uma vez que o projetista não vai precisar preocupar-se
com a interação entre o modelo e a visão.
Estudar e utilizar padrões de projetos para guiar na implementação de sua estrutura e
relacionamento entre suas classes.
O Framework Struts foi escolhido como objeto de estudo pois é um framework que
implementa o Padrão Arquitetural MVC, padrão que foi implementado no framework
desenvolvido.
1
1.3. Justificativa
A principal justificativa para criação deste projeto é o fato de existirem poucas
ferramentas que utilizam o padrão MVC, o que traz como conseqüência que
desenvolvedores criem aplicações mal estruturas que muitas vezes é insuficiente para se ter
um software de qualidade.
Um grande benefício oferecido pelo padrão MVC é o fraco acoplamento caracterizado
pela independência do modelo que representa as entidades do mundo real em relações a
suas visões. Este fraco acoplamento permite um aumento de qualidade no aplicativo final
desenvolvido.
2
2. Padrões de Projetos
Nesta seção será dado um breve histórico dos Padrões de Projeto (Design Pattern), e
apresentado em detalhes os padrões que foram utilizados no framework desenvolvido neste
trabalho.
2.1. Histórico
Nos anos setenta, Christopher Alexander escreveu vários livros relatando padrões na
arquitetura e engenharia civil. A comunidade de software adotou a idéia de padrões baseada
em seu trabalho, embora já existisse um crescente interesse nessas idéias por parte da
comunidade.
Os padrões de software foram popularizados com o livro Design Patterns: Elements of
Reusable Object-Oriented Software de Erich Gamma, Richard Helm, Ralph Johnson e John
Vlissides (também conhecidos como Gang of Four, da onde veio à famosa sigla GoF).
Salientando que os padrões que eles descrevem não foram inventados por eles. O que eles
fizeram foi perceber que padrões se repetiam em numerosos projetos, eles identificaram e
documentaram. Eles catalogaram 23 padrões. Dividos em:
•
Padrões de Criação: abstraem o processo de instanciação de objetos
•
Padrões Estruturais: definem a forma como as classes e objetos são compostos
•
Padrões
Comportamentais:
definem
algoritmos
e
a
atribuição
de
responsabilidades entre objetos.
Os padrões se referem à comunicação de problemas e soluções. Em outras palavras, os
padrões permitem documentar um problema que se repete e sua solução em um contexto
especifico e comunicar esse conhecimento para outras pessoas.
Algumas características comuns dos padrões são:
•
São observados através da experiência.
•
Evitam a reinvenção da roda.
•
Suportam melhorias continuas.
•
Podem ser utilizados em conjunto para resolver problemas maiores.
3
2.2. Padrão Observador
Também conhecido como: Publisher-Subscriber, Event Generator, Dependents.
O padrão Observador permite que objetos interessados sejam avisados da mudança de
estado ou outros eventos ocorrendo num outro objeto. Com esse padrão parte da
responsabilidade de processamento decorrente da mudança de estado de um objeto é
distribuída a observadores. Também temos baixo acoplamento entre o objeto observado e
os observadores.
O objeto sendo observado é chamado de:
•
"Subject" (GoF)
•
"Observable" (java.util)
•
"Source" ou "Event Source" (java.swing e java.beans)
•
Provedor de informação (Bill Venners)
•
Gerador de eventos (Bill Venners)
O objeto que observa é chamado de
•
Observer (GoF e java.util)
•
Listener (java.swing)
Uma das motivações em utilizar esse padrão é que às vezes alterar um objeto requer
mudanças em outros e não se sabe quantos objetos precisam ser mudados.
No framework desenvolvido o objeto observado será o modelo e os objetos
interessados nas suas mudanças serão as views.
2.3. Padrão Command
O padrão Comando específica à definição de uma classe para cada mensagem ou
comando, cada uma com um método execute. A chave para este padrão é uma classe
abstrata Comando, que declara uma interface para execução de operações. Cada subclasse
de Comando tem um único método execute que especifica as ações para aquele comando.
Vantagens desse padrão:
•
Suportar “undo” (desfazer). A operação Execute do Comando pode armazenar
o estado para reverter seus efeitos no próprio comando. A classe Comando deve
4
ter uma operação adicional “unexecute” que reverte os efeitos de uma chamada
prévia para Execute.
•
Estruturar um sistema em volta de operações de alto nível construídas sobre
operações primitivas.
•
O padrão Comando separa o objeto que invoca a operação daquele que sabe
executá-la.
•
Permite que seja criado um “log” (registro) dos comandos que foram
executados.
Este padrão será utilizado pelo Controlador do framework em resposta aos eventos que
ocorram nas views. A cada evento que ocorra nas interfaces será chamado um objeto
comando responsável pela execução daquele evento.
2.4. Padrão Template Method
Define o esqueleto de um algoritmo em uma operação, postergando alguns passos para
subclasses. Esse padrão ilustra o Princípio de Hollywood: “não me chame, nos chamaremos
você”.
Um método template é um método que ao ser chamado invoca pelo menos um outro
método chamado método hook. Método hook é um método gancho que fornece
comportamento adicional ao método template.
O método template comporta a parte imutável de um procedimento. A flexibilização
do procedimento se da pelo overriding (sobrescrita) do(s) método(s) hook invocados.
O padrão Template Method pode ser usado:
•
Para implementar as partes invariantes de um algoritmo uma só vez e deixar
para as subclasses a implementação do comportamento que pode variar.
•
Para controlar extensões de subclasses. Você pode definir um método template
que chama métodos ganchos (hook) em pontos específicos, desta forma
permitindo extensões somente nestes pontos.
5
No framework desenvolvido o método template é o método que inicializa o
framework, e os métodos hook são os métodos de criação do modelo e visão, que darão
comportamento adicional ao método template.
2.5. Padrão Singleton
O objetivo desse padrão é assegurar que uma classe tenha uma única instância e prover
um ponto de acesso global a esta instância.
Com ele é fácil fazer com que seja crie um número fixo, ou um número máximo de
instâncias em vez de apenas uma única instância, apenas basta mudar implementação
interna do Singleton.
Este padrão foi utilizado para assegurar que a classe Aplicação do framework tem uma
única instância e um ponto de acesso global a esta instância.
2.6. Padrão Arquitetural MVC(Model View Controller)
Surgiu na comunidade de Smalltalk.A idéia é permitir que uma mesma lógica de
negócios (modelo, model) possa ser acessada e visualizada através de várias interfaces
(visão, view).
Sua principal função é "separar" o sistema em 3 camadas, facilitando assim o
entendimento, desenvolvimento e manutenção, deixando bem claras as funções
desempenhadas por cada camada.
O padrão MVC vem sendo amplamente usado em aplicações WEB, sendo
principalmente implementada com o auxílio de frameworks entre estes se destacam o
projeto "jakarta struts" que será discutido em frente, facilitando assim a criação de páginas
dinâmicas de fácil manutenção e acelerado desenvolvimento. O conceito MVC também
pode ser utilizado no desenvolvimento de aplicações desktop mantendo as mesmas
vantagens citadas.
Com as diversas possibilidades de interfaces que conhecemos hoje, a arquitetura MVC
é uma ferramenta indispensável para desenvolvimento de aplicações mais complexas
(Figura 1).
6
Figura 1 – Aplicação sendo exibida por várias interfaces
2.6.1.
Definições
Modelo (Model): contém os dados da aplicação junto com a lógica dos negócios que
define como alterar e acessar os dados; o modelo pode ser compartilhado entre vários
objetos, visões e controladores.
O modelo é usado para gerenciar informações e notificar aos observadores quando esta
informação sofre mudanças. O modelo encapsula mais do que somente dados e funções
que operam sobre ele. Um modelo é feito para servir como uma aproximação de um
modelo computacional, ou uma abstração de algum processo ou sistema do mundo
real. Ele captura não somente o estado de um processo ou sistema, mas também com o
sistema funciona.
Na arquitetura MVC, o modelo não sabe de quantas nem quais interfaces com o
usuário estão exibindo seu estado.
Visão (View): é a forma de apresentação dos dados do modelo para o mundo externo,
pode ser na forma de GUI (Graphical User Interface), fala, som, listagens ou mesmo em
uma saída não orientada a usuários, como ligar um ar condicionado.
Controlador (Controller): transforma eventos gerados pela interface em ações de
negócio, alterando o modelo. . Por exemplo, se o usuário clica o botão do mouse ou
7
seleciona um item de menu, o controlador é o responsável por determinar como a aplicação
deve responder.
Na Figura 2 é ilustrado a interação destes três componentes:
Figura 2 - Fluxo de eventos e informações em uma arquitetura MVC
Figura 3 – MVC em nível de aplicação
2.6.2.
Como funciona
O modelo, a visão e o controlador são intimamente relacionados e estão
constantemente se comunicando. Assim sendo, eles devem referenciar uns aos outros. A
Figura 3 ilustra basicamente uma relação no estilo Model-View-Controller.
8
Ela mostra as linhas de comunicação dentre as camadas de modelo, visão e
controlador. Na figura, o modelo aponta para a visão, que permite que ele envie
notificações de alterações. Esta é só uma associação básica o modelo não deve estar ciente
das visões que o observam, este baixo acoplamento é conseguido com o Padrão
Observador.
Em contraste a isto, a visão sabe exatamente que tipo de modelo ela está observando. A
visão também tem uma associação de alto nível com o modelo, permitindo que ela chame
qualquer outra função do mesmo.
O controlador é o responsável por determinar como a aplicação deve responder em
resposta as ações do usuário.
9
3. Frameworks Orientados a Objetos
3.1. Definição
Um framework é uma aplicação quase completa, mas com pedaços faltando. Criar uma
aplicação sob um framework consiste em prover os pedaços que são específicos para sua
aplicação. Um framework provê uma solução para uma família de problemas semelhantes.
Algumas definições de outros autores:
“Framework é um esqueleto de implementação de uma aplicação ou um subsistema de
aplicação, em um domínio de problema particular. É composto de classes abstratas e
concretas e provê um modelo de interação ou colaboração entre as instancias de classes
definidas pelo framework” [WIA 91].
“Um framework é utilizado através de configuração ou conexão de classes concretas e
derivação de novas classes concretas a partir das classes abstratas do framework” [WIR
90].
“Um framework é um conjunto de classes inter-relacionadas com o objetivo de facilitar
o desenvolvimento de um determinado domínio de aplicação. São compostas de classes
concretas e abstratas, estas ultimas possuindo implementações incompletas que devem ser
estendidas para compor as classes completas da aplicação final. A motivação para o
desenvolvimento de frameworks é a reutilização de código e projeto, com o intuito de
aumentar a produtividade no desenvolvimento de softwares” [SIR 00].
“Um framework captura as decisões de projeto que são comuns ao seu domínio de
aplicação. Assim, frameworks enfatizam a reutilização de projeto em relação à reutilização
de código, embora um framework, geralmente inclua subclasses concretas que o
desenvolvedor pode utilizar imediatamente” [GAM 02]. O que trás como conseqüência que
temos aplicações similares, que facilita no seu gerenciamento. Por outro lado, o
desenvolvedor perde um pouco de liberdade uma vez que muitas decisões de projetos já
foram tomas anteriormente.
A diferença fundamental entre um framework e a reutilização de classes de uma
biblioteca, é que neste caso as colaborações são criadas pela própria aplicação, cabendo ao
desenvolvedor estabelecê-las. E no caso do framework, as colaborações estão embutidas.
10
Figura 4 - Visão Conceitual da estrutura um Framework
3.2. Qualidade de um bom Framework
Para termos um bom Framework algumas características devem ser cumpridas:
generalidade, alterabilidade e extensibilidade. Para que isto ocorra, o projeto do framework
deve ser bem elaborado, buscando identificar que partes devem ser mantidas flexíveis para
produzir um projeto bem estruturado. Desta forma, deve-se utilizar os princípios de um
projeto orientado a objetos, como o uso da herança, polimorfismo, classes abstratas.
3.2.1.
Generalidade
Reflete a capacidade do framework em dar suporte a várias aplicações diferentes de um
mesmo domínio, sendo flexível o suficiente para que as características de alterabilidade e
extensibilidade possam ser aplicadas.
11
3.2.2.
Alterabilidade
Esta associada à capacidade do framework de alterar suas funcionalidades em função
da necessidade de uma aplicação especifica sem que estas alterações resultem em
conseqüências imprevistas no conjunto de sua estrutura.
3.2.3.
Extensibilidade
Reflete a capacidade do framework de ampliar sua funcionalidade sem conseqüências
imprevistas no conjunto de sua estrutura. Ligada diretamente na manutenção do framework,
permite que sua estrutura evolua.
3.2.4.
Simplicidade
A estrutura geral do framework deve ser de fácil compreensão de forma que o
desenvolvedor possa aprendê-lo em pouco tempo. Esta simplicidade é alcançada pelo
projeto de interfaces limpas e consistentes, pela utilização de padrões em seu projeto,
código, interfaces e nomenclaturas.
3.2.5.
Clareza
Os aspectos comportamentais do framework devem ser encapsulados. Não há
necessidade do desenvolvedor saber todos os detalhes do framework para que ele possa
utilizá-lo.
3.2.6.
Fronteiras
Um framework tem responsabilidades claras e sucintas, e deve acatá-las e nada mais.
Todas as funcionalidades exteriores a fronteira do framework devem ser tratadas pelo
desenvolvedor. Quando um framework ultrapassa esta fronteira, ele se torna complexo e
provavelmente o desenvolvedor ao tentar utilizá-lo precisará implementar código adicional
junto a framework para conseguir o comportamento desejado. Um framework não prove a
funcionalidade da aplicação, ele prove o esqueleto sobre o qual a aplicação é construída.
12
Caso o framework deseje prover classes mais especializadas, estas devem ser fornecidas em
bibliotecas de classes separadas como subclasses das classes do framework. Isto permitirá
ao desenvolvedor escolher usar ou não estas classes, fazendo assim uma clara distinção
entre framework e o kit de ferramentas do desenvolvedor.
13
4. Estudo do Framework Struts
Nesta seção será apresentado o Framework Struts, um framework que vem sendo
amplamente utilizado em aplicações na WEB. Ele será apresentado por implementar o
Padrão Arquitetural MVC, padrão que foi implementado no framework desenvolvido.
4.1. Projeto Jakarta
O projeto Jakarta tem como objetivo criar e manter soluções de código aberto na
Plataforma Java. Produtos de Jakarta são desenvolvidos e são distribuídos por vários
subprojetos. Dentro destes subprojetos temos o Framework Struts.
O projeto Jakarta é patrocinado por Apache Software Foundation.
4.2. Framework Struts
4.2.1.
Introdução
Struts foi criado por Craig R. McClanahan, e doado para Apache Software Foundation
em Maio de 2000.
O objetivo do Framework Struts é proporcionar um framework de código aberto para
construção de aplicações web.
O nome struts=suporte, que lembra partes que suportam construções, casas, pontes que
são de certa forma “invisíveis” para as mesmas.
Umas das principais características desse framework é que controle das camadas é
baseado em tecnologias como Java Servlets, JavaBeans, ResourceBundles, e Extensible
Markup Language (XML).
Struts é baseado no padrão MVC (Model-View-Controller)
Struts possui seu próprio componente controlador. Para o Modelo, Struts pode interagir
com qualquer tecnologia padrão de acesso de dados, incluindo Enterprise Java Beans,
JDBC, e Object Relational Bridge. Para Visão, struts pode utilizar JSP (JavaServer Pages),
incluindo JSTL (JavaServer Standard Tag Library) e JSF (JavaServer Faces).
14
4.2.2.
Motivação para criação do Framework Struts
Muito claramente desenvolvedores perceberam que JSPs (JavaServer Pages) e servlets
poderiam ser usados juntos para o desenvolvimento de aplicações web. Os servlets poderias
ajudar no controle de fluxo, e o JSPs com a escrita do código HTML. O que deu origem ao
Modelo Dois (usando JSPs e servlets juntos e JavaBeans) e no modelo 1(usava JSPs e
JavaBeans), nas Figura 5 e Figura 6 vemos respectivamente a representações do Modelo 1 e
do Modelo 2.
4.2.3.
Estrutura do Framework Struts
7
Figura 5 - Visão do framework Struts e do MVC.
Java Servlets: são projetados para manipular requisições feitas pelo Web browsers.
Vantagens:
•
•
•
•
•
•
Melhor que o padrão CGI (um dos primeiros mecanismos a permitir que um
servidor WWW criasse conteúdo de forma dinâmica).
Alta performance
Conveniência
Portabilidade
Segurança
Cria threads para cada requisição Web.
15
Java ServerPages são projetados para criar paginas Web dinâmicas.
Struts usa Servlet como um controlador das requisições feitas pelo Web browsers para
destinar para o ServerPage. Isto faz com que aplicações Web sejam mais fáceis de projetar,
criar e alterar.
Figura 6 – Struts e MVC
Na Figura 6 temos um detalhamento maior do framework Struts juntamente com o
MVC.
4.2.4.
Como funciona o struts
Num exemplo bem característico da arquitetura MVC, o framework struts, as views são
renderizadas por arquivos jsps, sendo que o modelo, ou a “lógica de negócio” ficam com as
classes Java e a parte do controle é praticamente todo implementada em um arquivo ”struts16
config.xml”, no qual são definidas as ações para determinadas requisições vindas do
cliente.
Os três componentes do MVC no struts:
Model: é tudo que envolve o Business Logic, sem considerações de interface.
JavaBeans (ou EJBs) são usados para Business Logic (Model).
View: representa numa interface o estado corrente do Model.
JSP são usados para representar a View.
Struts ajuda a validar formulários com classes "Form".
Controller: é usado para alimentar o Model quando ocorrem entradas na interface.
O Controller é um servlet que já vem pronto em struts
O que o Controller faz:
Intercepta requests HTTP vindo de um cliente.
Cada request recebe seu próprio thread.
Traduz o request numa operação específica a ser feita.
Chama a operação diretamente (ou delega para um Action Object).
O servlet roteia o request para o destino correto (o objeto Action).
Ajuda a selecionar a próxima View a mostrar para o cliente.
Retorna a View para o cliente.
4.2.5.
Struts versus Framework Desenvolvido
No framework desenvolvido foi usado o padrão Arquitetural MVC do Smalltalk que
usa o padrão de Notificação Observer, já no Struts é usado Modelo 2, também conhecido
como: MVC2, Web MVC.
Isso ocorre porque o padrão de notificação Observer não funciona bem em um
ambiente web. O HTTP é um protocolo de “extração”: cliente solicita e o servidor
responde. O padrão Observer requer um protocolo de anexação para a notificação, a fim de
17
que o servidor possa transferir uma mensagem para um cliente quando houver mudanças no
modelo.
Esse padrão funciona bem quando todos os recursos estão no mesmo servidor e os
clientes têm uma conexão aberta com esse servidor. Não funciona bem tão bem quando os
recursos são distribuídos em diversos servidores e os clientes não mantêm uma conexão
aberta com a aplicação.
18
5. Uso de Frameworks
Utilizar um framework consiste em criar aplicações a partir deste. A motivação para
produzir aplicações a partir de frameworks é a perspectiva de aumento de qualidade e
produtividade. Para produzir aplicações sob um framework deve-se estender sua estrutura.
Um dos obstáculos em desenvolver uma aplicação sob um framework está no fato que
um desenvolvedor de aplicações pode necessitar de um esforço superior para aprender a
usar um framework que desenvolver sua aplicação do início ao fim.
Para diminuir o esforço requerido pode-se criar ferramentas que auxiliem na
compreensão de como usar framework. Como documentação no estilo cookbook.
5.1. Indivíduos Envolvidos com o Desenvolvimento e Uso de
Frameworks
“O desenvolvimento tradicional de aplicações envolve dois tipos de individuo:
desenvolvedor de aplicação e usuário de aplicação (nos dois casos isto pode corresponder a
grupos de indivíduos com diferentes funções). Desenvolvedores devem levantar os
requisitos de uma aplicação, desenvolvê-la(o que inclui a documentação que ensina a usar a
aplicação, como manuais de usuário) e entregá-la aos usuários. Usuários interagem com
uma aplicação apenas através de sua interface.”
“O desenvolvimento de frameworks introduz outro individuo, alem do desenvolvedor e
usuário de aplicação: o desenvolvedor de framework. No contexto dos frameworks, o papel
do usuário de aplicação é o mesmo descrito acima. O papel do desenvolvedor de aplicações
difere do caso anterior pela inserção do framework no processo de desenvolvimento de
aplicações. Com isto, o desenvolvedor de aplicações é para a produção de aplicações. Ele
tem as mesmas funções do caso anterior: obter os requisitos da aplicação desenvolvê-la
usando o framework, (o que em geral, não dispensa completamente do desenvolvedor de
aplicações a necessidade de produzir código) e desenvolver a documentação da aplicação.
O novo papel criado no contexto dos frameworks, o desenvolvedor de framework, tem a
responsabilidade de produzir frameworks e algum modo de ensinar como usá-los para
produzir aplicações”. [SIR 00].
19
5.2. Questões-Chave para Usar um Framework
Usuários de frameworks desenvolvidos segundo a abordagem caixa-preta ou black-box
ou data-driven precisam apenas conhecer que objetos estão disponíveis e as regras para
combiná-los. As instanciações e composições feitas determinam as particularidades da
aplicação.
No caso dos frameworks caixa-branca (white-box ou architecture-driven) e caixacinza, necessitam saber quais classes devem ser geradas, quais classes podem ser geradas, e
precisam
diferenciar
os
dois
casos.
Também
necessitam
conhecer
quais
as
responsabilidades e as funcionalidades das classes a serem geradas.
“Assim, no caso geral, as três questões-chave a seguir devem ser respondidas:
Questão 1 – Quais classes? As classes concretas de uma aplicação podem ser criadas
ou reutilizadas do framework. Então, que classes devem ser desenvolvidas pelo usuário e
que classes concretas do framework podem ser reutilizadas?
Questão 2 – Quais métodos? Um método de uma classe abstrata pode ser classificado
como:
- abstrato: um método que tem apenas a sua assinatura definida na classe abstrata;
- template: é definido em termos de outros métodos (métodos hook);
- base: é completamente definido.
Na execução de um método template ocorre à chamada de pelo menos um método
hook, que pode ser um método abstrato, base ou template. Ao produzir uma aplicação:
- métodos abstratos precisam ser definidos;
- métodos template fornecem uma estrutura de algoritmo definida, mas permitem
flexibilidade através dos métodos hook chamados. A avaliação da necessidade ou
conveniência de produção de métodos deve ser estendida para os métodos hook.
- método base de acordo com o projeto do framework, não precisa ser alterado (mas é
possível sobrepô-los).
Assim ao gerar uma classe concreta para uma aplicação (considerando o caso de
subclasse de classe abstrata do framework), que métodos devem ser definidos e que
métodos herdados podem ser reutilizados?
20
Questão 3 – O que os métodos fazem?: Os métodos cuja estrutura deve ser definida
pelo usuário do framework produzem o comportamento especifico da aplicação sob
desenvolvimento. Assim, definidas as classes e os respectivos métodos a desenvolver, quais
as responsabilidades destes métodos, em que situações de processamento eles atuam e
como eles implementam a cooperação entre diferentes objetos?“ [SIR 00].
21
6. Framework Desenvolvido
O principal padrão de projeto utilizado nesse framework é o padrão MVC(Model View
Controller) que tem o objetivo de separar a aplicação em três camadas. No framework
modelo será a classe BmvcModel, a visão classe BmvcView, e o controlador a classe
BmvcController.
6.1. As principais classes do Framework
BmvcModel: responsável pelo modelo de dados. Esta classe deve ser extendida e
implementada ao se criar uma aplicação sob o framework.
BmvcView: responsável pela apresentação do dados. Para cada visão teremos uma
subclasse da BmvcView.
BmvcController: controla a aplicação. Para cada componente visual que gere eventos
na interface deve ser implementado um controlador. Exemplo para controlador eventos que
são
gerados
por
botões
deve
ser
implementado
um
controlador.
A
classe
BmvcButtonCTRL implementa um controlador para botões.
BmvcCommand: executa os eventos gerados na interface.
BmvcAplic: classe a aplicação.
6.2. Vantagens em usar o Framework
Para melhor expor as vantagens do uso do framework foi criado uma aplicação sem
usá-lo, o código fonte se encontra no anexo.
Entre elas temos que a arquitetura de camadas já está definida. Diminuindo o esforço
do desenvolvedor uma vez que esta decisão já foi tomada, cabendo a ele seguí-la. Sem ter
que se preocupar com colaborações entre as classes da aplicação, já que elas estão
embutidas no framework.
Por exemplo, o desenvolvedor não precisaria preocupar-se com interação entre modelo
e visão, pois o próprio framework faz isso através do padrão MVC. Na aplicação sem o uso
do framework ocorreu um forte acoplamento entre modelo e visão, visto que sempre que
ocorrem alterações do modelo às visões devem ser notificadas dessas alterações o que trás
como conseqüência que o modelo faça referência direta às visões. Porquanto muitas vezes
22
nem sabemos quais visões devem ser alteradas e tendo que novas visões poderiam ser
criadas no futuro, toda vez que isso ocorre teríamos que mudar o modelo. Este fraco
acoplamento permite um aumento de qualidade no aplicativo final desenvolvido.
Com os controladores do framework não precisamos ter conhecimento sobre os
controladores Swing do Java. Além que todos eventos dos controladores são executados
pelo padrão Command que tem várias vantagens como: ele separa o objeto que invoca a
operação daquele que sabe executá-la, a operação execute do padrão Command pode
armazenar o estado para reverter seus efeitos no próprio comando, termos log dos
comandos executados.
Finalizando, se fosse criar uma aplicação sem o framework utilizando os padrões
usados no framework teríamos consideravelmente um aumento de complexidade na
aplicação. E o código não ficaria tão limpo quanto o código de uma aplicação desenvolvida
sob o framework. Perderíamos em qualidade, tempo, esforço no desenvolvimento da
mesma.
6.3. Estrutura do Framework
O framework desenvolvido (Bmvc) foi feito na linguagem Java. Para desenvolver uma
aplicação sob ele é necessário conhecimento básico na mesma.
Para criar uma aplicação sob o Bmvc os seguintes passos devem ser seguidos, a
seqüência é mais por motivos didáticos, mas não necessariamente precisa ser na ordem
apresentada.
1) Criar o model (modelo) da aplicação
2) Criar a view (visão) ou as views da aplicação
3) Criar aplicação
Note-se que apesar de estarmos usando o padrão MVC, não será necessário criar o
Controlador, apenas será reutilizado os controladores que já vem com o framework. Sempre
que houver necessidade pode-se facilmente criar novos controladores garantindo a
extensibilidade do framework.
23
6.3.1.
Criação do model (modelo)
Para criar o modelo deve-se estender a classe BmvcModel, e nela deverá ser colocado
apenas o que pertence ao Model sem nenhuma ligação com a View (apresentação dos
dados). Para facilitar coloque o nome da classe como xxxModel.java. Essa classe é bem
simples de definir a única coisa necessária é estender do framework a classe BmvcModel
usando xxxModel extends BmvcModel.
No construtor da classe inicialize os dados do modelo.
6.3.2.
Criação da view (visão)
Para criar a view estenda a classe BmvcView, a sua classe por padronização ficaria
assim xxxView.java. Na view é necessário criar o método updateView, que será chamado
pela classe BmvcView, toda a vez que a view for atualizada. No corpo desse método
coloque o código que produz a alteração da View. Esse método ficaria assim: public void
updateView() { ... }
No construtor da classe deve-se pegar uma referência do modelo, está referência é
conseguida pedindo para a aplicação o modelo (com temos baixo acoplamento), em seguida
será mostrado a classe aplicação com mais detalhes.
6.3.3.
Criação da aplicação
Para criar a classe aplicação deve-se estender a classe BmvcAplic. O nome da sua
classe aplicação pode ser MinhaAplicacao.java. Nessa classe será instanciado o modelo e
todas as views. Métodos que devem ser definidos nessa classe:
1) public void criaModelo () { ... } esse é um método hook, que será chamado pela
classe BmvcAplic. Nele deve ser instanciado o modelo e setado o modelo para que
o framework saiba quem é o modelo da aplicação para isso use o método:
setModel(seuModelo);
2) public void criaVisao () { ... } esse é um método hook, que será chamado pela
classe BmvcAplic. Nele deve ser instanciado as views e adicionado as views para o
framework , para isso use o método: addInternalFrame(suaView)
3) public static void main(String[] args) { … }
24
Aqui deve ser instanciado a própria classe aplicação no caso MinhaAplicacao, usando:
MinhaAplicacao aplic = new MinhaAplicacao("Esta é a minha aplicação"). E em
seguida showAplicacao(para mostrar a aplicação).
6.3.4.
Criando um novo Controlador
O framework já vem com alguns controladores prontos, mas é possível criar novos
controladores. Para isso estenda a classe BmvcController, que é a classe controladora
principal.
No construtor chame o construtor da superclasse passando como parâmetros o
componente para o qual está sendo criado o controlador e o comando que deve ser
executado quando ocorre uma ação nesse componente. Para esse componente também é
necessário adicionar um listener. Em seguida será mostrado um controlador em detalhes.
25
7. Criando uma aplicação sob o Framework Bmvc
Nesse tópico será mostrado os principais pontos para criação de uma aplicação sob o
framework
Bmvc.
A
aplicação
criada
será
de
uma
Enquete
de
Sistemas
Operacionais.Algumas partes do código não será explicitada, todo o código da aplicação
está no anexo do trabalho.
7.1. Criando a estrutura de diretórios
Siga os passos abaixo para criar a estrutura de diretórios:
1) Inicialmente crie uma nova pasta (c:\minhaAplicacao);
2) Nessa pasta criada, coloque uma copia do framework Bmvc, nela constará três
pastas: model, view, controller;
3) Agora cria outra pasta (c:\minhaAplicacao\Enquete)
4) Dentro dela cria as pastas: model, view, recursos
Na pasta model ficará o modelo;
Na pasta view as visões;
Na pasta recursos ficará imagens, etc...
7.2. Criando a aplicação
7.2.1.
Criando a classe modelo
1) Vá ao seu editor java e crie um novo arquivo e salve ele como:
(C:\minhaAplicacao\aplicacao\enquete\model\ EnqueteModel.java)
2) Código comentado:
//nome do seu pacote
package enquete.model;
//importação da classe BmvcModel do framework.model
import framework.model.BmvcModel;
26
//estendendo a super classe Model
public class EnqueteModel extends BmvcModel {
//dados do modelo
…
public EnqueteModel() {
//coloque aqui a inicialização do modelo
}
public void votar (String opcao) {
//coloque aqui o código de quando ocorre um voto
...
//notifica as view que houve mudança
notifyViews();
}
//outros métodos
...
Na parte do modelo o que deve ser ressaltado é o método notifyViews() que informa as
views que houve mudança.
27
7.2.2.
Criando as Views
Criaremos aqui duas views, no código em anexo foram criado quatro views.
7.2.2.1. Criando a classe View Principal
Chamaremos de MainView a view principal.
1) Crie um novo arquivo no seu editor e salve
(C:\minhaAplicacao\aplicacao\enquete\view\MainView.java).
2) Código comentado:
//nome do seu pacote
package aplicacao.enquete.view;
//pacotes importados
//utiliza o modelo para pegar os dados do mesmo e apresentá-los na tela
import aplicacao.enquete.model.*;
//aqui fica as imagens que são exibidas na tela, existe uma classe(Recursos.java) que
captura o diretório onde as mesmas estão.
import aplicacao.enquete.recursos.*;
//utilizada para ter acesso à classe Aplicação que tem um ponto global de
acesso(padrão Singleton), no anexo existe uma implementação simples desse padrão de
projeto (SingletonPattern.java) ou na própria classe do framework (BmvcAplic.java).
import framework.*;
// utiliza os controladores que serão responsáveis por trocar informação entre a View e
Model.
import framework.controller.*;
//superclasse view
import framework.view.*;
//estendendo a superclasse do framework
28
public class MainView extends BmvcView
{
…
//a view tem uma referência ao modelo
private EnqueteModel modelo;
public MainView() {
//pegando uma referencia do modelo
modelo = (EnqueteModel) BmvcAplic.getModel();
// aqui é utilizado o padrão Observador.
// O padrão Observador permite que objetos interessados sejam avisados
// da mudança de estado ou outros eventos ocorrendo num outro objeto. No nosso caso
//a view será notificada quando houve mudanças no modelo.
modelo.addView(this);
//menu principal para a view principal
JMenu aplicacaoMenu = new JMenu("Aplicação");
aplicacaoMenu.setMnemonic('A');
//Padrão Command (no anexo a uma implementacao simples de padrão
//CommandPattern.java)
//note que aqui é criado o comando que será executado quando houver uma ação sobre,
//esse caso será dado um voto no Sistema Operacional Windows.
BmvcCommand cmdVotarWindows = new BmvcCommand () {
public void execute(ActionEvent event) { modelo.votar("Windows"); }
};
// submenus Aplicacao->Windows
//aqui está sendo utilizado uns dos controladores do framework, e note que está sendo
//passado para ele o comando que deve ser executado(cmdVotarWindows) quando
29
//houver um evento.
BmvcMenuItemCTRL aplicacaoWindows =
New BmvcMenuItemCTRL(aplicacaoMenu, "Windows",
Recursos.getRecursos("win.gif"), 'W', "F2", cmdVotarWindows );
....
}
30
7.2.2.2. Criando a classe View EnqueteResultadoView
Chamaremos de EnqueteResultadoView a view que mostrara a quantidade de votos.
1) Crie um novo arquivo no seu editor e salve
(C:\minhaAplicacao\aplicacao\enquete\view\ EnqueteResultadoView.java).
2) Código comentado:
// nome do seu pacote
package aplicacao.enquete.view;
//pacotes utilizados
import aplicacao.enquete.model.*;
import framework.*;
import framework.view.*;
...
public EnqueteResultadoView(int x, int y) {
//pega uma referencia do modelo
modelo = (EnqueteModel) BmvcAplic.getModel();
// aqui novamente é utilizado o padrão Observador.
// O padrão Observador permite que objetos interessados sejam avisados
// da mudança de estado ou outros eventos ocorrendo num outro objeto. No nosso caso
//a view será notificada quando houve mudanças no modelo.
modelo.addView(this);
…
}
31
// esse método será chamado pela classe BmvcView, toda a vez que a view for
//atualizada. No corpo desse método coloca-se o código que produz a alteração
//da View
public void updateView() {
....
}
32
7.2.3.
1)
Vá
Criando a classe Aplicação
ao
seu
editor
java
e
crie
um
novo
arquivo
e
salve
ele:
(C:\minhaAplicacao\aplicacao\enquete\model\EnqueteModel.java)
2)
Código comentado:
// nome do seu pacote
package aplicacao.enquete;
//pacotes utilizados
import aplicacao.enquete.model.*;
import framework.*;
import framework.model.*;
import aplicacao.enquete.view.MainView;
import aplicacao.enquete.view.EnqueteResultadoView;
import aplicacao.enquete.view.EnqueteResultadoPorcView;
import aplicacao.enquete.view.EnqueteResultadoGraficoView;
//estendendo a superclasse do framework
public class Enquete extends BmvcAplic {
// construtor
public Enquete(String name) {
super(name, true, true);
// aplicação criada com menu(segundo parâmetro) e
toolbar(segundo parâmetro)
}
...
//aqui temos um método hook, que será chamada por um método template(Padrão
//Template). Um método template é um método que ao ser chamado invoca pelo menos
//um outro método chamado método hook. Método hook é um método gancho que
33
//fornece comportamento adicional ao método template.
public void criaModelo() {
// criar o modelo
EnqueteModel modelo = new EnqueteModel();
// setado o modelo para que o framework saiba quem é o modelo da aplicação
setModel( (BmvcModel) modelo);
// povoa o modelo
modelo.addItem("Linux");
modelo.addItem("Mac SO");
modelo.addItem("Windows");
};
//método hook
public void criaVisao() {
// cria as views
mainView = new MainView();
enqueteResultadoView = new EnqueteResultadoView(20, 30);
enqueteResultadoPorcView = new EnqueteResultadoPorcView(20, 190);
enqueteResultadoGraficoView = new EnqueteResultadoGraficoView(255, 30);
//adiciona as views ao framework
BmvcAplic.addInternalFrame(enqueteResultadoView.getInternalFrame());
BmvcAplic.addInternalFrame(enqueteResultadoPorcView.getInternalFrame());
BmvcAplic.addInternalFrame(enqueteResultadoGraficoView.getInternalFrame());
};
//finalmente temos o método main, aqui é instanciado a classe Enquete.
public static void main(String[] args) {
34
final Enquete termometro = new Enquete("Aplicação - Enquete de Sistemas
Operacionais");
//mostra a aplicação.
BmvcAplic.showAplicacao();
}
}
35
8. Conclusão
A abordagem de frameworks contribui significativamente para reutilização no
desenvolvimento de artefatos de software. Frameworks é uma abordagem que está sendo
cada vez mais utilizada, com o objetivo de diminuir o tempo e esforços no desenvolvimento
de artefatos de software.
Para se ter um bom projeto, este deve ser bem estruturado e planejado. Padrões de
projeto ajudam o projetista no desenvolvimento de projetos melhor estruturados,
oferecendo soluções que foram desenvolvidas e aperfeiçoadas ao longo do tempo.
O framework desenvolvido permite a separação das camadas de dados, controle e
visualização. Esta separação oferece vantagens para desenvolvedores como a otimização
das habilidades de equipes e a redução de custos associados ao desenvolvimento, além de
favorecer a extensibilidade e reutilização do código.
Temos também o reuso de projeto e código proporcionado pelo framework. O fraco
acoplamento do modelo de dados permite um aumento de qualidade no aplicativo final
desenvolvido. Outro ponto é que o framework força o desenvolvedor a criar aplicações
mais bem estruturadas.
Para testar o framework foram criados para um mesma aplicação três versões da
mesma: a primeira utilizando o framework, segunda sem usar o framework e sem padrões
de projeto e a ultima sem usar o framework e usando padrões de projeto. Para as três
versões a que teve menos linhas de códigos escritas e também levou menos tempo para
desenvolver foi a utilizando o framework.
36
9. Referências
[WIR 90] WIRFS-BROCK, R, Johnson, R. E. Surveying current research in object-oriented
design. Communications of the ACM. V.33, n.9. sep. 1990.
[WIA 91] WIRFS-BROCK, A. et. Al. Designing reusable designs: Experiences designing
object-oriented frameworks. In: Object-Oriented Programming Systems, Languages and
Applications Conference; European on Object-Oriented Programming, 1991.
[SIR 00] SILVA, Ricardo P. Suporte ao desenvolvimento e uso de frameworks e
componentes. Tese para a obtenção do grau de Doutor em Ciências da Computação.
Universidade Federal do Rio Grande do Sul, UFRGS. Porto Alegre, 2000.
[GAM 02] GAMMA, Eric, HELM, Richard, JOHNSON, Ralph, VLISSIDES, John.
Padrões de Projeto: soluções reutilizáveis de software orientado a objetos. Porto Alegre:
Bookman, 2002.
LARMAN, Craig. Utilizando UML e padrões: Uma introdução à análise e ao projeto
orientado a objetos. Tradução Luiz A. M. Salgado. Porto Alegre: Bookman, 2000.
LARMAN, Craig.Applying UML and Patterns: A introduction to object-oriented analysis
and design and the unified process. 2 ed: Prentice Hall, 2000.
JAKARTA, Projeto Jakarta. Disponível em <http://jakarta.apache.org>. Acesso em 10 jun.
2003.
STRUTS, Framework Struts. Disponível em <http://jakarta.apache.org/struts/>. Acesso em
11 jun. 2003.
37
JAVA
WORLD,
Exploring
the
MVC
design
pattern.
Disponível
em
<http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html>. Acesso em 11
jun. 2003.
HUSTED,
Framework
Struts.
Disponível
em
<http://www.husted.com/struts/resources/struts-intro.ppt >. Acesso em 12 jun 2003.
38
10. Anexo A – Artigo
Framework para Camada de Apresentação
Claudio Ulisses Nunes Biava
Departamento de Informática e Estatística – Universidade Federal de Santa Catarina
(UFSC)
[email protected]
Resumo
Frameworks orientados a objetos promovem reuso de projeto e código. Contudo, a
ampla adoção desta abordagem é dificultada pela complexidade para desenvolver e para
usar frameworks.
Este trabalho apresenta o framework Bmvc que é um framework para camada de
apresentação baseado na arquitetura MVC (Model View Controller).
Será abordado Design Patterns (Padrões de Projeto) que foram utilizados para
desenvolver o framework.
E finalmente será criado uma aplicação utilizando o framework Bmvc e explicando
passo a passo como fazê-la.
Palavras-Chaves: framework orientados a objetos, reuso, MVC, Design Patterns
Abstract
Object-oriented frameworks promote reuse design and code. However, the widespread
adoption of this approach is made difficult by the complexity to develop and to use
frameworks.
This work presents the framework Bmvc that is a framework for presentation layer
based on the architecture MVC (Model View Controller).
It will be approach Design Patterns that were used to develop the framework.
And finally will be created an application using framework Bmvc and explaining step
by step as to make it.
Keywords: Objects-oriented frameworks, reuse, MVC, Design Patterns.
1. Introdução
O desenvolvimento de Frameworks se torna cada vez mais comum e necessário uma
vez que existe uma necessidade de criar sistemas corporativos de modo mais rápido e a um
baixo custo e de fácil manutenção.
Framework é o esqueleto-base sobre o qual uma aplicação é construída, constituída de
uma estrutura de classes com implementações incompletas, que estendidas permitem
39
produzir novos aplicativos. A grande vantagem desta abordagem é a reutilização de código
e projeto, que tem por intuito diminuir o tempo e o esforço no desenvolvimento de
softwares.
Este trabalho tem como objetivo implementar um framework para desenvolvimento de
um Framework para Camada de Apresentação utilizando padrão arquitetural MVC (Model
View Control), ou seja, separação de modelo e visão. Seu desenvolvimento foi motivado
pela necessidade de separar interface de código, ou seja, de se criar códigos de aplicações
genéricos, não para interface especificas.
2. Padrões de Projeto
Os padrões de software foram popularizados com o livro Design Patterns: Elements of
Reusable Object-Oriented Software de Erich Gamma, Richard Helm, Ralph Johnson e John
Vlissides (também conhecidos como Gang of Four, da onde veio à famosa sigla GoF).
Salientando que os padrões que eles descrevem não foram inventados por eles. O que eles
fizeram foi perceber que padrões se repetiam em numerosos projetos, eles identificaram e
documentaram. Eles catalogaram 23 padrões. Dividos em:
• Padrões de Criação: abstraem o processo de instanciação de objetos
• Padrões Estruturais: definem a forma como as classes e objetos são compostos
• Padrões Comportamentais: definem algoritmos e a atribuição de
responsabilidades entre objetos.
Os padrões se referem à comunicação de problemas e soluções. Em outras palavras, os
padrões permitem documentar um problema que se repete e sua solução em um contexto
especifico e comunicar esse conhecimento para outras pessoas.
Nesse trabalho foram utilizados os seguintes padrões: Observador, Command,
Template Method, Singleton, Padrão Arquitetural MVC
3. Padrão Arquitetural MVC
Sua principal função é "separar" o sistema em 3 camadas, facilitando assim o
entendimento, desenvolvimento e manutenção, deixando bem claras as funções
desempenhadas por cada camada.
O padrão MVC vem sendo amplamente usado em aplicações WEB, sendo
principalmente implementada com o auxílio de frameworks entre estes se destacam o
projeto "jakarta struts" que será discutido em frente, facilitando assim a criação de páginas
dinâmicas de fácil manutenção e acelerado desenvolvimento. O conceito MVC também
pode ser utilizado no desenvolvimento de aplicações desktop mantendo as mesmas
vantagens citadas.
Modelo (Model): contém os dados da aplicação junto com a lógica dos negócios que
define como alterar e acessar os dados; o modelo pode ser compartilhado entre vários
objetos, visões e controladores.
40
Visão (View): é a forma de apresentação dos dados do modelo para o mundo externo,
pode ser na forma de GUI (Graphical User Interface), fala, som, listagens ou mesmo em
uma saída não orientada a usuários, como ligar um ar condicionado.
Controlador (Controller): transforma eventos gerados pela interface em ações de
negócio, alterando o modelo. . Por exemplo, se o usuário clica o botão do mouse ou
seleciona um item de menu, o controlador é o responsável por determinar como a aplicação
deve responder.
4. Frameworks Orientados a Objetos
Um framework é uma aplicação quase completa, mas com pedaços faltando. Criar uma
aplicação sob um framework consiste em prover os pedaços que são específicos para sua
aplicação. Um framework provê uma solução para uma família de problemas semelhantes.
5. Qualidade de um bom Framework
Para termos um bom Framework algumas características devem ser compridas:
generalidade, alterabilidade e extensibilidade. Para que isto ocorra, o projeto do framework
deve ser bem elaborado, buscando identificar que partes devem ser mantidas flexíveis para
produzir um projeto bem estruturado. Desta forma, deve-se utilizar os princípios de um
projeto orientado a objetos, como o uso da herança, polimorfismo, classes abstratas.
Características de um bom framework: Generalidade, Alterabilidade, Extensibilidade,
Simplicidade, Clareza, Fronteiras.
6. Framework Desenvolvido
O principal padrão de projeto utilizado nesse framework é o padrão MVC(Model View
Controller) que tem o objetivo de separar a aplicação em três camadas. No framework
modelo será a classe BmvcModel, a visão classe BmvcView, e o controlador a classe
BmvcController.
As principais classes do Framework:
BmvcModel: responsável pelo modelo de dados. Esta classe deve ser extendida e
implementada ao se criar uma aplicação sob o framework.
BmvcView: responsável pela apresentação do dados. Para cada visão teremos uma
subclasse da BmvcView.
BmvcController: controla a aplicação. Para cada componente visual que gere eventos
na interface deve ser implementado um controlador. Exemplo para controlador eventos que
são gerados por botões deve ser implementado um controlador. A classe
BmvcButtonCTRL implementa um controlador para botões.
BmvcCommand: executa os eventos gerados na interface.
BmvcAplic: classe a aplicação.
41
Entre as vantagens do framework temos que a arquitetura de camadas já está definida.
Diminuindo o esforço do desenvolvedor uma vez que esta decisão já foi tomada, cabendo a
ele seguí-la. Sem ter que se preocupar com colaborações entre as classes da aplicação, já
que elas estão embutidas no framework.
Com os controladores do framework não precisamos ter conhecimento sobre os
controladores Swing do Java. Além que todos eventos dos controladores são executados
pelo padrão Command que tem várias vantagens como: ele separa o objeto que invoca a
operação daquele que sabe executá-la, a operação execute do padrão Command pode
armazenar o estado para reverter seus efeitos no próprio comando, termos log dos
comandos executados.
Finalizando, se fosse criar uma aplicação sem o framework utilizando os padrões
usados no framework teríamos consideravelmente um aumento de complexidade na
aplicação. E o código não ficaria tão limpo quanto o código de uma aplicação desenvolvida
sob o framework. Perderíamos em qualidade, tempo, esforço no desenvolvimento da
mesma.
O framework desenvolvido (Bmvc) foi feito na linguagem Java. Sendo assim para criar
uma aplicação sob ele é necessário conhecimento básico na mesma.
Para criar uma aplicação sob o Bmvc os seguintes passos devem ser seguidos, a
seqüência dos passos é mais por motivos didáticos, mas não necessariamente precisa ser na
ordem apresentada.
1. Criar o model (modelo) da aplicação
2. Criar a view (visão) ou as views da aplicação
3. Criar aplicação
Note-se que apesar de estarmos usando o padrão MVC, não será necessário criar o
Controlador, apenas será reutilizado os controladores que já vem com o framework. Sendo
que se houver necessidade pode-se facilmente criar novos controladores garantindo a
extensibilidade do framework.
7. Conclusão
O framework desenvolvido permite a separação das camadas de dados, controle e
visualização. Esta separação oferece vantagens para desenvolvedores como a otimização
das habilidades de equipes e a redução de custos associados ao desenvolvimento, além de
favorecer a extensibilidade e reutilização do código.
Temos também o reuso de projeto e código proporcionado pelo framework, O fraco
acoplamento do modelo de dados permite um aumento de qualidade no aplicativo final
desenvolvido. Outro ponto é que o framework força o desenvolvedor a criar aplicações
mais bem estruturadas.
Para testar o framework foram criados para um mesma aplicação três versões da
mesma: a primeira utilizando o framework, segunda sem usar o framework e sem padrões
de projeto e a ultima sem usar o framework e usando padrões de projeto. Para as três
versões a que teve menos linhas de códigos escritas e também levou menos tempo para
desenvolver foi a utilizando o framework.
42
8. Referências
[WIR 90] WIRFS-BROCK, R, Johnson, R. E. Surveying current research in object-oriented
design. Communications of the ACM. V.33, n.9. sep. 1990.
[WIA 91] WIRFS-BROCK, A. et. Al. Designing reusable designs: Experiences designing
object-oriented frameworks. In: Object-Oriented Programming Systems, Languages and
Applications Conference; European on Object-Oriented Programming, 1991.
[SIR 00] SILVA, Ricardo P. Suporte ao desenvolvimento e uso de frameworks e
componentes. Tese para a obtenção do grau de Doutor em Ciências da Computação.
Universidade Federal do Rio Grande do Sul, UFRGS. Porto Alegre, 2000.
[GAM 02] GAMMA, Eric, HELM, Richard, JOHNSON, Ralph, VLISSIDES, John.
Padrões de Projeto: soluções reutilizáveis de software orientado a objetos. Porto Alegre:
Bookman, 2002.
LARMAN, Craig. Utilizando UML e padrões: Uma introdução à análise e ao projeto
orientado a objetos. Tradução Luiz A. M. Salgado. Porto Alegre: Bookman, 2000.
LARMAN, Craig.Applying UML and Patterns: A introduction to object-oriented analysis
and design and the unified process. 2 ed : Prentice Hall, 2000.
JAKARTA, Projeto Jakarta. Disponível em <http://jakarta.apache.org>. Acesso em 10 jun.
2003.
STRUTS, Framework Struts. Disponível em <http://jakarta.apache.org/struts/>. Acesso em
11 jun. 2003.
JAVA
WORLD,
Exploring
the
MVC
design
pattern.
Disponível
em
<http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html>. Acesso em 11
jun. 2003.
HUSTED,
Framework
Struts.
Disponível
em
<http://www.husted.com/struts/resources/struts-intro.ppt >. Acesso em 12 jun 2003.
43
11. Anexo B – Código Fonte das Principais Classes
Classe - BmvcModel.java
/*
* BmvcModel - a superclasse modelo(MVC) para o framework Bmvc
*/
package framework.model;
import java.util.*;
import framework.view.BmvcView;
public class BmvcModel
extends Observable {
// Observable usada para implementação do padrão Observador
// O padrão Observador permite que objetos interessados sejam avisados
// da mudança de estado ou outros eventos ocorrendo num outro objeto.
public BmvcModel() {
super();
}
public void addView(BmvcView view) {
addObserver( (Observer) view); //método addObserver faz parte da classe Observable
}
public void deleteView(BmvcView view) {
deleteObserver( (Observer) view); //método deleteObserver faz parte da classe
Observable
}
public void notifyViews() {
setChanged();
notifyObservers();
}
}
Classe - BmvcView.java
/*
44
* BmvcView - a superclasse view(MVC) para o framework Bmvc
*/
package framework.view;
import java.util.*;
public class BmvcView
implements Observer {
// implementação da interface Observer
public void update(Observable observed, Object value) {
updateView();
}
public void updateView() {
}
}
Classe - BmvcController.java
/*
* BmvcController - implementação de um Controlador genérico usando o padrão
Comando
*
para o framework Bmvc, simplifica os controles do Swing
*/
package framework.controller;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.WindowEvent;
public class BmvcController
implements ActionListener,ItemListener,AdjustmentListener {
protected JComponent componente;
private BmvcCommand BmvcCommand; // objeto executor
public BmvcController(JComponent comp,
String tip,
BmvcCommand bExec) {
componente = comp;
BmvcCommand = bExec;
if (tip != null) {
45
componente.setToolTipText(tip);
}
}
public BmvcCommand getBmvcCommand() {
return BmvcCommand;
}
/*
* Implementação dos Listeners para os componentes.
* Cada listener enviará uma mensagem apropriada ao método execute que está
associado ao BmvcCommand. O tipo de evento determina a assinatura do método
execute.
*/
// implementa o ActionListener
public void actionPerformed(ActionEvent event) {
if (BmvcCommand != null) {
BmvcCommand.execute(event);
}
}
// implementa o ItemListener
public void itemStateChanged(ItemEvent event) {
if (BmvcCommand != null) {
BmvcCommand.execute(event);
}
}
// implementa o AdjustmentListener
public void adjustmentValueChanged(AdjustmentEvent event) {
if (BmvcCommand != null) {
BmvcCommand.execute(event);
}
}
/* public void windowClosing(WindowEvent event) {
if (BmvcCommand != null) {
BmvcCommand.execute(event);
}
}*/
}
Classe - BmvcCommand.java
46
/*
* BmvcCommand - Classe suporte para implementação do BmvcController
* seguindo o Padrão Command
*/
package framework.controller;
import java.awt.event.*;
import javax.swing.event.*;
public abstract class BmvcCommand {
// um execute para cada tipo de evento que existir.
public void execute(ActionEvent event) {
}
public void execute(ItemEvent event) {
}
public void execute(ChangeEvent event) {
}
public void execute(AdjustmentEvent event) {
}
public void execute(WindowEvent event) {
}
}
Classe - BmvcScrollbarCTRL.java
/*
* BmvcScrollbarCTRL - implementa o controle para JScroolBar
*/
package framework.controller;
import javax.swing.*;
import framework.BmvcAplic;
public class BmvcScrollbarCTRL
47
extends BmvcController {
private JScrollBar scrollBar;
public BmvcScrollbarCTRL(String tip, boolean horizontal,
BmvcCommand bExec) {
super ( (JComponent)new JScrollBar(horizontal? JScrollBar.HORIZONTAL:
JScrollBar.VERTICAL, 0, 10,-46, 160), tip, bExec);
scrollBar = (JScrollBar) componente;
scrollBar.addAdjustmentListener(this); // adiciona o listener
}
public JScrollBar getJScrollBar() {
return scrollBar;
}
}
Classe - BmvcButtonCTRL.java
/*
* BmvcButtonCTRL - implements JButton controller for Jbutton
*/
package framework.controller;
import javax.swing.*;
import framework.BmvcAplic;
import java.net.URL;
public class BmvcButtonCTRL
extends BmvcController {
private JButton botao;
// construtor
public BmvcButtonCTRL(String text,
URL icon,
String tip,
BmvcCommand bExec) {
super( (JComponent)new JButton(), tip, bExec);
botao = (JButton) componente;
if (text != null) {
48
botao.setText(text);
}
if (icon != null) {
Icon icone = new ImageIcon(icon);
botao.setIcon(icone);
}
botao.addActionListener(this); // adiciona o listener
BmvcAplic.getToolBar().add(botao);
}
public JButton getJButton() {
return botao;
}
}
Classe - BmvcMenuItemCTRL.java
/*
* BmvcMenuItemCTRL - implementa o controle para JMenuItem
*/
package framework.controller;
import java.net.*;
import javax.swing.*;
public class BmvcMenuItemCTRL
extends BmvcController {
private JMenu menu;
private JMenuItem menuItem;
//construtor
public BmvcMenuItemCTRL(JMenu menu,
String texto,
URL icon,
char mnemonic,
String atalho,
BmvcCommand bExec) {
super( (JComponent)new JMenuItem(), texto, bExec);
menu = menu;
menuItem = (JMenuItem) componente;
49
if (texto != null) {
menuItem.setText(texto);
}
if (mnemonic != ' ' && mnemonic != 0) {
menuItem.setMnemonic(mnemonic);
}
if (atalho != null) {
KeyStroke ks = KeyStroke.getKeyStroke(atalho);
menuItem.setAccelerator(ks);
}
if (icon != null) {
Icon icone = new ImageIcon(icon);
menuItem.setIcon(icone);
}
menuItem.addActionListener(this); // adiciona o listener
menu.add(menuItem);
}
public JMenu getJMenu() {
return menu;
}
public JMenuItem getJMenuItem() {
return menuItem;
}
}
Classe - BmvcWindowCTRL.java
package framework.controller;
import javax.swing.*;
import framework.BmvcAplic;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
public class BmvcWindowCTRL
extends BmvcController {
private JScrollBar scrollBar;
private WindowListener window;
50
public BmvcWindowCTRL(String tip,
BmvcCommand bExec) {
super( (JComponent)new JScrollBar(JScrollBar.HORIZONTAL, 0, 10,-46, 160), tip,
bExec);
scrollBar = (JScrollBar) componente;
scrollBar.addAdjustmentListener(this); // add listener
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
BmvcAplic.getAplic().aplicacaoClose();
}
};
}
/* new WindowAdapter() {
public void windowClosing(WindowEvent e) {
BmvcAplic.getAplic().aplicacaoClose();
System.exit(0);
}
};
*/
}
Classe - Enquete.java
/*
* Enquete - Aplicação teste para Framework Bmvc
*/
package aplicacao.enquete;
import aplicacao.enquete.model.*;
import framework.*;
import framework.model.*;
import aplicacao.enquete.view.MainView;
import aplicacao.enquete.view.EnqueteResultadoView;
import aplicacao.enquete.view.EnqueteResultadoPorcView;
import aplicacao.enquete.view.EnqueteResultadoGraficoView;
public class Enquete
extends BmvcAplic {
51
private MainView mainView;
private EnqueteResultadoView enqueteResultadoView;
private EnqueteResultadoPorcView enqueteResultadoPorcView;
private EnqueteResultadoGraficoView enqueteResultadoGraficoView;
// construtor
public Enquete(String name) {
super(name, true, true); // criado com menu e toolbar
}
public static void main(String[] args) {
final Enquete termometro = new Enquete("Aplicação - Enquete de Sistemas
Operacionais");
BmvcAplic.showAplicacao();
}
//método hook
public void criaModelo() {
// criar o modelo
EnqueteModel modelo = new EnqueteModel();
setModel( (BmvcModel) modelo);
// povoa o modelo
modelo.addItem("Linux");
modelo.addItem("Mac SO");
modelo.addItem("Windows");
};
//método hook
public void criaVisao() {
// criar view/controlador
mainView = new MainView();
enqueteResultadoView = new EnqueteResultadoView(20, 30);
enqueteResultadoPorcView = new EnqueteResultadoPorcView(20, 190);
enqueteResultadoGraficoView = new EnqueteResultadoGraficoView(255, 30);
BmvcAplic.addInternalFrame(enqueteResultadoView.getInternalFrame());
BmvcAplic.addInternalFrame(enqueteResultadoPorcView.getInternalFrame());
BmvcAplic.addInternalFrame(enqueteResultadoGraficoView.getInternalFrame());
};
}
52
Classe - EnqueteModel.java
/*
* EnqueteModel - implementação do modelo
*/
package aplicacao.enquete.model;
import framework.model.BmvcModel;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
public class EnqueteModel
extends BmvcModel {
//dados do modelo
private Map dados;
private int nDados;
public EnqueteModel() {
dados = new HashMap();
nDados = 0;
}
public void addItem(String descricao) {
dados.put(descricao, new Integer(0));
nDados++;
}
public void setVotos(String opcao, int votos) {
dados.put(opcao, new Integer(votos));
notifyViews(); //notifica as view que houve mudança
}
public void votar(String opcao) {
int votoAtual = ( (Integer) dados.get(opcao)).intValue();
dados.put(opcao, new Integer(++votoAtual));
notifyViews(); //notifica as view que houve mudança
}
public int getVotos(String opcao) {
return ( (Integer) dados.get(opcao)).intValue();
}
public Float getVotosEmPorc(String opcao) {
53
Float r = new Float(0);
float valor = ( (Integer) dados.get(opcao)).floatValue();
int total = getTotalVotos();
if (total > 0) {
r = new Float(valor / total);
}
return r;
}
public Iterator getItens() {
return dados.keySet().iterator();
}
public int getTotalVotos() {
Iterator votos = dados.values().iterator();
int total = 0;
while (votos.hasNext()) {
total = total + ( (Integer) votos.next()).intValue();
}
return total;
}
public int getNDados() {
return nDados;
}
}
Classe - MainView.java
/*
* MainView - View para Enquete
*/
package aplicacao.enquete.view;
import java.awt.event.*;
import javax.swing.*;
import aplicacao.enquete.model.*;
import aplicacao.enquete.recursos.*;
import framework.*;
54
import framework.controller.*;
import framework.view.*;
public class MainView
extends BmvcView {
private EnqueteModel modelo;
public MainView() {
modelo = (EnqueteModel) BmvcAplic.getModel();
modelo.addView(this);
JMenu aplicacaoMenu = new JMenu("Aplicação");
aplicacaoMenu.setMnemonic('A');
// Aplicacao->Windows
BmvcCommand cmdVotarWindows = new BmvcCommand() {
public void execute(ActionEvent event) { modelo.votar("Windows"); }
};
BmvcMenuItemCTRL aplicacaoWindows = new BmvcMenuItemCTRL(aplicacaoMenu,
"Windows",
Recursos.getRecursos("win.gif"),
'W',
"F2",
cmdVotarWindows
);
// Aplicacao->Mac
BmvcMenuItemCTRL aplicacaoMac = new BmvcMenuItemCTRL(aplicacaoMenu,
"Mac SO",
Recursos.getRecursos("mac.gif"),
'M',
"F3",
new BmvcCommand() {
public void execute(ActionEvent event) {
modelo.votar("Mac SO");
}
});
// Aplicacao->Linux
BmvcMenuItemCTRL aplicacaoLinux = new BmvcMenuItemCTRL(aplicacaoMenu,
"Linux",
Recursos.getRecursos("linux.gif"),
'L',
"F4",
new BmvcCommand() {
public void execute(ActionEvent event) {
55
modelo.votar("Linux");
}
});
// Aplicacao=>Sair
BmvcMenuItemCTRL aplicacaoSair = new BmvcMenuItemCTRL(aplicacaoMenu,
"Sair", Recursos.getRecursos("sair.gif"), 'S', "F12", new BmvcCommand() {
public void execute(ActionEvent event) {
BmvcAplic.getAplic().aplicacaoClose();
}
});
BmvcAplic.addMenu(aplicacaoMenu);
BmvcButtonCTRL btWindows = new BmvcButtonCTRL(
"Votar", Recursos.getRecursos("win.gif"), "Votar em Windows",
aplicacaoWindows.getBmvcCommand());
BmvcButtonCTRL btMac = new BmvcButtonCTRL(
"Votar", Recursos.getRecursos("mac.gif"), "Votar em Mac SO",
aplicacaoMac.getBmvcCommand());
BmvcButtonCTRL btLinux = new BmvcButtonCTRL(
"Votar", Recursos.getRecursos("linux.gif"), "Votar em Linux",
aplicacaoLinux.getBmvcCommand() );
BmvcButtonCTRL btSair = new BmvcButtonCTRL(
"Sair", Recursos.getRecursos("sair.gif"), "Sai da aplicação",
aplicacaoSair.getBmvcCommand());
}
}
Classe - EnqueteResultadoView.java
/*
* EnqueteResultadoView - implementação da view
*/
package aplicacao.enquete.view;
import java.util.*;
import java.awt.*;
import javax.swing.*;
56
import aplicacao.enquete.model.*;
import framework.*;
import framework.view.*;
public class EnqueteResultadoView
extends BmvcView {
private JInternalFrame internalFrame;
private EnqueteModel modelo;
private JLabel[] labelValores;
public JInternalFrame getInternalFrame() {
return internalFrame;
}
public EnqueteResultadoView(int x, int y) {
modelo = (EnqueteModel) BmvcAplic.getModel();
modelo.addView(this);
internalFrame = new JInternalFrame("Enquete Resultado", false,true,false);
internalFrame.getContentPane().setLayout(new GridLayout(3,2));
Iterator descricoes = modelo.getItens();
JLabel labelTexto;
String texto;
labelValores = new JLabel[modelo.getNDados()];
int valor;
int i = 0;
while(descricoes.hasNext()) {
texto = descricoes.next().toString();
labelTexto = new JLabel("
" + texto);
labelTexto.setForeground(Color.blue);
internalFrame.getContentPane().add(labelTexto);
labelValores[i] = new JLabel();
labelValores[i].setForeground(Color.red);
internalFrame.getContentPane().add(labelValores[i++]);
}
internalFrame.setLocation(x,y);
internalFrame.setSize(220, 140);
internalFrame.setVisible(true);
updateView();
}
57
public void updateView() {
Iterator descricoes = modelo.getItens();
int valor;
int i = 0;
String sufixo;
while(descricoes.hasNext()) {
valor = modelo.getVotos(descricoes.next().toString());
if (valor>1) sufixo = "votos";
else sufixo = "voto";
labelValores[i++].setText(""+ valor+ " " +sufixo );
}
}
}
Classe - EnqueteResultadoPorcView.java
/*
* EnqueteResultadoPorcView - implementação da view
*/
package aplicacao.enquete.view;
import framework.view.BmvcView;
import javax.swing.JInternalFrame;
import aplicacao.enquete.model.EnqueteModel;
import framework.BmvcAplic;
import java.awt.GridLayout;
import java.util.Iterator;
import javax.swing.JLabel;
import java.awt.Color;
import java.text.DecimalFormat;
public class EnqueteResultadoPorcView
extends BmvcView {
private JInternalFrame internalFrame;
private EnqueteModel modelo;
private JLabel[] labelValores;
public JInternalFrame getInternalFrame() {
return internalFrame;
}
public EnqueteResultadoPorcView(int x, int y) {
58
modelo = (EnqueteModel) BmvcAplic.getModel();
modelo.addView(this);
internalFrame = new JInternalFrame("Enquete Resultado em %", false,true,false);
internalFrame.getContentPane().setLayout(new GridLayout(modelo.getNDados(),2));
Iterator descricoes = modelo.getItens();
JLabel labelTexto;
String texto;
labelValores = new JLabel[modelo.getNDados()];
int valor;
int i = 0;
while(descricoes.hasNext()) {
texto = descricoes.next().toString();
labelTexto = new JLabel("
" + texto);
labelTexto.setForeground(Color.blue);
internalFrame.getContentPane().add(labelTexto);
labelValores[i] = new JLabel();
labelValores[i].setForeground(Color.red);
internalFrame.getContentPane().add(labelValores[i++]);
}
internalFrame.setLocation(x,y);
internalFrame.setSize(220, 140);
internalFrame.setVisible(true);
updateView();
}
public void updateView() {
Iterator descricoes = modelo.getItens();
Float valor;
int i = 0;
DecimalFormat formatador = new DecimalFormat();
formatador.applyPattern("0%");
while(descricoes.hasNext()) {
valor = modelo.getVotosEmPorc(descricoes.next().toString());
labelValores[i++].setText(""+ formatador.format(valor));
}
}
}
59
Classe - EnqueteResultadoGraficoView.java
/*
* EnqueteResultadoGraficoView - implementação da view
*/
package aplicacao.enquete.view;
import framework.view.BmvcView;
import javax.swing.JInternalFrame;
import aplicacao.enquete.model.EnqueteModel;
import framework.BmvcAplic;
import java.awt.GridLayout;
import java.util.Iterator;
import javax.swing.JLabel;
import java.awt.Color;
//biblioteca net.sourceforge.chart2d é software livre, tirada do site: www.sourceforge.net
import aplicacao.enquete.recursos.net.sourceforge.chart2d.*;
public class EnqueteResultadoGraficoView
extends BmvcView {
private JInternalFrame internalFrame;
private EnqueteModel modelo;
private Dataset dataset;
private PieChart2D grafico2D;
public JInternalFrame getInternalFrame() {
return internalFrame;
}
public EnqueteResultadoGraficoView(int x, int y) {
modelo = (EnqueteModel) BmvcAplic.getModel();
modelo.addView(this);
internalFrame = new JInternalFrame("Enquete Resultado Gráfico", true, true, false);
Object2DProperties object2DProps = new Object2DProperties();
object2DProps.setObjectTitleText("Enquete");
Chart2DProperties chart2DProps = new Chart2DProperties();
chart2DProps.setChartDataLabelsPrecision(0);
60
MultiColorsProperties multiColorsProps = new MultiColorsProperties();
PieChart2DProperties pieChart2DProps = new PieChart2DProperties();
//legendas
LegendProperties legendProps = new LegendProperties();
Iterator descricoes = modelo.getItens();
String[] legendas = new String[modelo.getNDados()];
int i = 0;
while (descricoes.hasNext()) legendas[i++] = descricoes.next().toString();
legendProps.setLegendLabelsTexts(legendas);
//seta os dados
int numCats = 1, numItems = 1;
dataset = new Dataset(modelo.getNDados(), numCats, numItems);
grafico2D = new PieChart2D();
grafico2D.setObject2DProperties(object2DProps);
grafico2D.setChart2DProperties(chart2DProps);
grafico2D.setLegendProperties(legendProps);
grafico2D.setDataset(dataset);
grafico2D.setMultiColorsProperties(multiColorsProps);
grafico2D.setPieChart2DProperties(pieChart2DProps);
internalFrame.getContentPane().add(grafico2D);
internalFrame.setLocation(x, y);
internalFrame.setSize(360, 300);
internalFrame.setVisible(true);
updateView();
}
public void updateView() {
Iterator descricoes = modelo.getItens();
int valor;
int i = 0;
String sufixo;
while (descricoes.hasNext()) {
valor = modelo.getVotos(descricoes.next().toString());
dataset.set(i++, 0, 0, valor);
}
grafico2D.repaint();
}
}
61
Classe - Recursos.java
package aplicacao.enquete.recursos;
import java.net.URL;
public class Recursos {
public static URL getRecursos(String name) {
return Recursos.class.getResource(name);
}
}
Classe - SingletonPattern.java
package padroes;
final class Singleton {
private static Singleton s = new Singleton(1);
private int i;
private Singleton(int x) {
i = x;
}
public static Singleton getReference() {
return s;
}
public int getValue() {
return i;
}
public void setValue(int x) {
i = x;
}
}
public class SingletonPattern {
public void testar() {
Singleton s = Singleton.getReference();
System.out.println(s.getValue());
62
s.setValue(2);
System.out.println(s.getValue());
Singleton s2 = Singleton.getReference();
System.out.println(s.getValue());
}
public static void main(String[] args) {
SingletonPattern s = new SingletonPattern();
s.testar();
}
}
Classe - TemplateMethod.java
package padroes;
abstract class FrameworkTeste {
public FrameworkTeste() {
templateMethod();
}
abstract void ajuste1();
abstract void ajuste2();
final void templateMethod() {
for (int i = 0; i < 3; i++) {
ajuste1();
ajuste2();
}
}
}
// uma aplicação sob o FrameworkTeste
class MinhaAplicacao
extends FrameworkTeste {
void ajuste1() {
System.out.print("Olá ");
}
void ajuste2() {
System.out.println("Mundo!");
}
63
}
public class TemplateMethod {
public static void main(String args[]) {
new MinhaAplicacao();
}
}
Classe - CommandPattern.java
package padroes;
import java.util.*;
interface Command {
void execute();
}
class Hello
implements Command {
public void execute() {
System.out.print("Hello ");
}
}
class World
implements Command {
public void execute() {
System.out.print("World! ");
}
}
// Guarda os comandos
class Macro {
private List commands = new ArrayList();
public void add(Command c) {
commands.add(c);
}
public void run() {
Iterator it = commands.iterator();
while (it.hasNext()) {
( (Command) it.next()).execute();
}
64
}
}
public class CommandPattern {
public CommandPattern() {
Macro macro = new Macro();
macro.add(new Hello());
macro.add(new World());
macro.run();
}
public static void main(String args[]) {
CommandPattern c = new CommandPattern();
}
}
65
Download