Framework para Camada de Apresentação · A principal justificativa para criação deste projeto...

74
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

Transcript of Framework para Camada de Apresentação · A principal justificativa para criação deste projeto...

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 7. 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

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.

1.2.

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.

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.

2.3.

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.

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.

2.6.

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.

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.

4.2.

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.

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 ”struts-

16

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 caixa-

cinza, 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.

6.2.

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.

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.

7.2.

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...

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. Criando a classe Aplicação

1) Vá 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