CENTRO UNIVERSITÁRIO FEEVALE CELSO LORENZETTI FRAMEWORK PARA PERSISTÊNCIA DE DADOS Novo Hamburgo, junho de 2004. CELSO LORENZETTI FRAMEWORK PARA PERSISTÊNCIA DE DADOS Centro Universitário Feevale Instituto de Ciências Exatas e Tecnológicas Curso de Ciência da Computação Trabalho de Conclusão de Curso Orientadora: Sandra Teresinha Miorelli Novo Hamburgo, junho de 2004. DEDICATÓRIA Dedico esta monografia a minha família e amigos. Em especial a minha esposa, pelo seu apoio e incentivo. AGRADECIMENTOS Agradeço a todos os professores que tive o prazer de conviver durante minha vida acadêmica e que me transmitiram muitas coisas boas, e aos outros que direta ou indiretamente contribuíram para minha formação cultural. Um agradecimento especial a minha orientadora Sandra Teresinha Miorelli e ao professor Rodrigo Goulart, com os quais trabalhei neste último ano e que me auxiliaram muito no desenvolvimento desta monografia. Agradeço a minha esposa, pelo seu apoio e principalmente sua compreensão pela minha ausência em muitos finais de semana, que foram dedicados ao desenvolvimento deste trabalho. A minha mãe, minha irmã e meu irmão, pelo apoio e incentivo que me deram durante mais esta jornada. A todos os amigos e colegas que de alguma forma contribuíram para que eu pudesse chegar onde estou. Muito obrigado! RESUMO Um framework para persistência de dados é geralmente escrito para trabalhar em conjunto com um banco de dados relacional ou com uma API (Application Programming Interface) para serviços de dados orientados a registros. Tipicamente, um framework de persistência de dados pretende traduzir um objeto em um registro de banco de dados a fim de armazená-lo, e posteriormente recuperá-lo e recriar o objeto original. Frameworks para persistência de dados são desenvolvidos tendo como alvo primariamente o conceito de software orientado a objetos, ditando outros aspéctos arquiteturais da aplicação. Tal framework definirá o particionamento e organização da aplicação em classes e objetos instanciados a partir delas, bem como o fluxo de dados e controle. O padrão IOC (Inversion of Controll) é uma característica importante encontrada em tais frameworks, já que muitas chamadas de métodos ocorrem dentro do framework e não no código final de regras de negócios. Assim, o papel do framework se torna a coordenação e sequenciamento das atividades da aplicação. Tal inversão de controle dá ao framework, força para servir como um esqueleto extensível. O objetivo desse trabalho é demostrar as contribuições que a construção de um framework para persistência de dados pode trazer para o desenvolvimento de software, principalmente no que diz respeito a flexibilidade, reusabilidade e extensibilidade da aplicação. Palavras-chave: framework, reuso de software, desenvolvimento de software. ABSTRACT Title: “Data persistence framework” An data persistence framework is usually written to work together with a relational database or with an API (Application Programming Interface) for record-oriented data services. Tipicaly, an data persistence framework intends to translate an object into a database record in order to store it, and later on to retrieve it and recreate the original object. Data persistence frameworks are developed targeting primarily the object-oriented software concept, dictating other architectural aspects of the application. Such a framework will define the application’s partitioning and organization in classes and objects instantiated from them as well as the data and controll flows. The IOC (Inversion of Controll) pattern is an important feature found in such frameworks, since many method calls take place within the framework and not in the final business logic code. Thus, the framework’s role becomes the coordination and sequencing of the applications activities. Such inversion gives the framework the strength to serve as an extensible skeleton. The overall goal of this work is show the contributions that the construction of an object persistence framework can bring to software development, mostly in what concerns the flexibility, reusability and extensibility of the application. Keywords: framework, software reuse, software development. LISTA DE FIGURAS Figura 2-1 Diagrama de classes................................................................................................ 26 Figura 2-2 Diagrama de objetos ............................................................................................... 27 Figura 2-3 Diagrama de componentes...................................................................................... 28 Figura 2-4 Diagrama de implantação ....................................................................................... 28 Figura 2-5 Diagrama de caso de uso ........................................................................................ 29 Figura 2-6 Diagrama de seqüência ........................................................................................... 30 Figura 2-7 Diagrama de colaboração........................................................................................ 30 Figura 2-8 Diagrama de estados ............................................................................................... 31 Figura 2-9 Diagrama de atividade ............................................................................................ 32 Figura 3-1 Elementos de padrões segundo GoF....................................................................... 37 Figura 4-1 Frameworks x bibliotecas de classes (MALDONADO, 2001, P. 22).................... 45 Figura 4-2 Framework caixa branca (MALDONADO, 2001, p. 23)....................................... 47 Figura 4-3 Framework caixa preta (MALDONADO, 2001, p. 24) ......................................... 47 Figura 4-4 Custo x benefício de framework (TALIGENT, 1993)............................................ 49 Figura 4-5 Elementos do desenvolvimento tradicional de aplicações...................................... 51 Figura 4-6 Elementos do desenvolvimento de aplicações baseadas em frameworks............... 51 Figura 5-1 Caso de uso acessar formulário .............................................................................. 62 Figura 5-2 Caso de uso realizar uma consulta.......................................................................... 64 Figura 5-3 Caso de uso incluir registros................................................................................... 66 Figura 5-4 Caso de uso copiar registros ................................................................................... 67 Figura 5-5 Caso de uso modificar registros.............................................................................. 69 Figura 5-6 Caso de uso excluir registros .................................................................................. 71 Figura 5-7 Caso de uso consultar chave estrangeira................................................................. 72 Figura 5-8 Caso de uso salvar .................................................................................................. 75 Figura 5-9 Diagrama de classes dos formulários...................................................................... 78 Figura 5-10 Objeto do tipo TFrmBase ..................................................................................... 79 Figura 5-11 Objeto do tipo TFrmCadastro ............................................................................... 79 Figura 5-12 Objeto do tipo TFrmBrowse ................................................................................. 79 Figura 5-13 Objeto do tipo TFrmConsulta ............................................................................... 80 Figura 5-14 Objeto do tipo TFrmErros..................................................................................... 80 Figura 5-15 Objeto do tipo TFrmSobre.................................................................................... 80 Figura 5-16 Diagrama de classe dos componentes de edição .................................................. 82 Figura 5-17 Objeto do tipo TClDbData.................................................................................... 82 Figura 5-18 Objeto do tipo TClDbValor .................................................................................. 82 Figura 5-19 Objeto do tipo TClDbEdit..................................................................................... 82 Figura 5-20 Seqüência de realizar consulta.............................................................................. 83 Figura 5-21 Seqüência de incluir registros ............................................................................... 84 Figura 5-22 Seqüência de copiar registros ............................................................................... 85 Figura 5-23 Seqüência de modificar registros.......................................................................... 86 Figura 5-24 Seqüência de excluir registros .............................................................................. 87 Figura 5-25 Seqüência de consultar chave estrangeira............................................................. 88 Figura 5-26 Diagrama de estado da classe TFrmCadastro ....................................................... 89 Figura 6-1 Formulário inicial da aplicação............................................................................... 91 Figura 6-2 Formulário - incluir registros.................................................................................. 91 Figura 6-3 Formulário - copiar registros .................................................................................. 92 Figura 6-4 Formulário - excluir registros ................................................................................. 93 Figura 6-5 Formulário - consultar ............................................................................................ 94 Figura 6-6 Formulário - visualizar registros............................................................................. 95 Figura 6-7 Formulário - modificar registros............................................................................. 96 Figura 6-8 Formulário - consultar chave estrangeira................................................................ 97 Figura 6-9 Salvando as informações ........................................................................................ 98 LISTA DE TABELAS Tabela 2-1 Diagramas da UML (GAMMA, 2000)................................................................... 25 Tabela 3-1 Catálogo de padrões de projeto (GAMMA, 2000)................................................. 39 Tabela 3-2 Organização do catálogo de padrões (MALDONADO, 2001, p. 12) .................... 40 LISTA DE ABREVIATURAS E SIGLAS API Application Programming Interface CD Compact Disc CEP Código de Endereçamento Postal CFOP Código Fiscal de Operações e Prestações CNPJ Cadastro Nacional da Pessoa Jurídica CPF Cadastro de Pessoas Físicas GoF Gang of Four IOC Inversion of Controll OMG Object Management Group OMT Object Modeling Technique OO Orientação a Objetos OOSE Object Oriented Software Engineering ORB Object Request Broker SQL Structured Query Language UML Unified Modeling Language SUMÁRIO Introdução................................................................................................................................. 14 1 Conceitos de Orientação a Objetos................................................................................... 18 1.1 Objetos.......................................................................................................................... 18 1.2 Classes .......................................................................................................................... 19 1.3 Herança versus Composição......................................................................................... 20 1.4 Polimorfismo ................................................................................................................ 21 1.5 Bibliotecas de Classes (toolkits) ................................................................................... 22 2 UML ................................................................................................................................. 23 2.1 Origem .......................................................................................................................... 23 2.2 Aplicação ...................................................................................................................... 24 2.3 Diagramas da UML ...................................................................................................... 25 2.3.1 Diagrama de Classes............................................................................................. 26 2.3.2 Diagrama de Objetos ............................................................................................ 26 2.3.3 Diagrama de Componentes................................................................................... 27 2.3.4 Diagrama de Implantação..................................................................................... 28 2.3.5 Diagrama de Caso de Uso .................................................................................... 29 2.3.6 Diagrama de Seqüência ........................................................................................ 29 2.3.7 Diagrama de Colaboração .................................................................................... 30 2.3.8 Diagrama de Estados ............................................................................................ 31 2.3.9 Diagrama de Atividade......................................................................................... 31 2.4 Diagramas e Ferramentas Utilizadas ............................................................................ 32 3 Padrões ............................................................................................................................. 34 3.1 Descrevendo Padrões de Projeto .................................................................................. 34 3.2 O Catálogo de Padrões de Projeto ................................................................................ 37 3.3 Organização do Catálogo.............................................................................................. 40 3.4 Metapadrões.................................................................................................................. 40 3.5 Padrões de Projeto e Frameworks ................................................................................ 42 4 Frameworks ...................................................................................................................... 44 4.1 Classificação dos Frameworks ..................................................................................... 45 4.2 Frameworks Caixa Branca X Caixa Preta.................................................................... 46 4.3 Vantagens e Desvantagens ........................................................................................... 48 4.4 Compreensão e Uso de Frameworks ............................................................................ 49 4.5 Personagens Envolvidos com o Desenvolvimento e Uso de Frameworks................... 50 4.6 Etapas da Construção de Frameworks ......................................................................... 52 4.7 Aprendendo como usar Frameworks............................................................................ 53 5 Análise e Modelagem do Framework .............................................................................. 54 5.1 Requisitos do Sistema................................................................................................... 54 5.2 Cenários ........................................................................................................................ 56 5.2.1 Acessar Formulário .............................................................................................. 56 5.2.2 Realizar Consulta.................................................................................................. 56 5.2.3 Incluir Registros ................................................................................................... 57 5.2.4 Copiar Registros ................................................................................................... 58 5.2.5 Modificar Registros .............................................................................................. 59 5.2.6 Excluir Registros .................................................................................................. 60 5.2.7 Consultar Chave Estrangeira ................................................................................ 60 5.3 Casos de Uso ................................................................................................................ 61 5.3.1 Acessar Formulário .............................................................................................. 62 5.3.2 Realizar Consulta.................................................................................................. 64 5.3.3 Incluir Registros ................................................................................................... 66 5.3.4 Copiar Registros ................................................................................................... 67 5.3.5 Modificar Registros .............................................................................................. 69 5.3.6 Excluir Registros .................................................................................................. 71 5.3.7 Consultar Chave Estrangeira ................................................................................ 72 5.3.8 Salvar .................................................................................................................... 75 5.4 Diagramas de Classes ................................................................................................... 76 5.4.1 Formulários........................................................................................................... 76 5.4.2 Componentes de Edição ....................................................................................... 80 5.5 Diagramas de Seqüência............................................................................................... 83 5.5.1 Realizar Consulta.................................................................................................. 83 5.5.2 Incluir Registros ................................................................................................... 84 5.5.3 Copiar Registros ................................................................................................... 85 5.5.4 Modificar Registros .............................................................................................. 86 5.5.5 Excluir Registros .................................................................................................. 87 5.5.6 Consultar Chave Estrangeira ................................................................................ 88 5.6 Diagrama de Estados .................................................................................................... 89 6 Prototipação ...................................................................................................................... 90 6.1 Aplicação Principal....................................................................................................... 90 6.2 Incluir Registros ........................................................................................................... 91 6.3 Copiar Registros ........................................................................................................... 92 6.4 Excluir Registros .......................................................................................................... 93 6.5 Consultar....................................................................................................................... 94 6.6 Visualizar Registros...................................................................................................... 95 6.7 Modificar Registros ...................................................................................................... 96 6.8 Consultar Chave Estrangeira ........................................................................................ 97 6.9 Salvar Informações ....................................................................................................... 98 Conclusão e Trabalhos Futuros ................................................................................................ 99 Referências Bibliográficas...................................................................................................... 101 INTRODUÇÃO Projetar software orientado a objetos é difícil, mas projetar software reutilizável orientado a objetos é mais difícil ainda. É necessário achar objetos pertinentes, fatorá-los em classes no nível correto de granularidade, definir as interfaces das classes e as hierarquias de herança e estabelecer as relações chave entre eles. O projeto deve ser específico para o problema a resolver, mas também genérico o suficiente para atender futuros problemas e requisitos. Também deve evitar o reprojeto, ou pelo menos minimizá-lo (GAMMA, 2000, p. 17). Frameworks estão se tornando cada vez mais comuns e importantes. Eles representam a maneira pela qual sistemas orientados a objetos conseguem um maior grau de reutilização. Aplicações, de grande porte, orientadas a objetos terminarão por constituir-se de camadas de frameworks que cooperam uns com os outros para atender as necessidades do domínio da aplicação (GAMMA, 2000, p. 43). Embora frameworks possuam classes concretas que podem ser utilizadas, a tecnologia de frameworks orientado a objetos enfatizam a reutilização, em maior escala de projeto de software, o qual exige muito mais criatividade por parte do desenvolvedor, quando comparado com a tarefa de implementar aplicações (GAMMA, 2000, p. 42; JOHNSON, 1988, p. 1; FAYAD, 1997, p. 1; JOHNSON, 1997, p. 40). Um framework pode ser definido como “um projeto reutilizável de uma parte ou de todo um sistema, que é representado por um conjunto de classes abstratas e pelo modo que elas interagem”, ou “um esqueleto de uma aplicação que pode ser customizado para gerar novas aplicações” (JOHNSON, 1997, p. 39). Para desenvolver software reutilizável e flexível, não basta projetá-lo orientado a objetos, diversas técnicas, heurísticas e princípios de bom projeto devem ser aplicados durante o desenvolvimento (GERBER, 1999, p. 11). Segundo Gamma, um projeto reutilizável e flexível é difícil de obter corretamente da primeira vez, por isso, antes que ele seja concluído é reutilizado várias vezes, sendo modificado a cada vez (GAMMA, 2000, p. 17). 15 Lee (2001, p. 23) diz que software confiável, flexível e de fácil manutenção é difícil de ser criado, pois os sistemas de software são complexos e essa complexidade faz parte da essência do sistema. Isto também é citado por Bezzera (2002, p. 2) que diz que a complexidade é uma característica intrínseca de sistemas de software e que essa complexidade cresce, à medida que o sistema cresce. A capacidade de processamento e a largura de banda das redes aumentaram muito na última década. Porém o projeto e implementação de software permaneceram complexos, caros e sujeitos a erros. Muito do custo deve-se ao fato da indústria de software, re-descobrir e reinventar continuamente conceitos e componentes já utilizados em outros projetos. (FAYAD, 1997, p. 1; FAYAD, 1999, p. 3). Este fato acaba diminuindo a produtividade e a qualidade final do produto, porque problemas que já tinham sido solucionados podem voltar a ocorrer. E isto tudo aumentará o custo total do projeto. Acredita-se que uma das características mais importantes da orientação a objetos é a de promover e aumentar a reusabilidade de software em geral. Reutilização é um fator indispensável para aumentar a produtividade, sendo também um dos critérios na avaliação de qualidade de software (PREE, apud GERBER, 1999, p. 11). Frameworks e padrões estão sendo considerados tecnologias importantes de reutilização, em desenvolvimento de software, pois permitem que uma família de produtos de software possa ser gerada a partir de uma única matriz, o que garante um desenvolvimento mais rápido e com melhor qualidade, reduzindo o custo de implementação (CRESPO, 2000, p. 21; FAYAD, 1997, p. 1). Muitas das dificuldades encontradas durante o processo de desenvolvimento de software são repetitivas e poderiam ser resolvidas de uma mesma maneira se o problema fosse isolado e tratado individualmente. Porém, o que é muito comum de acontecer é cada desenvolvedor resolver de uma maneira diferente, dentro de sua capacidade de entendimento e com níveis de qualidade diferentes, sem que isto fique documentado e que possa ser consultado por outros desenvolvedores. Em um ambiente de desenvolvimento, em grupo, onde cada pessoa desenvolve de sua maneira, passando pelas mesmas dificuldades já enfrentadas e resolvidas por outras pessoas da mesma equipe, a produtividade diminui e dificulta manutenções futuras, uma vez que, a pessoa que for realizar a manutenção terá antes que entender a lógica implementada, para aí sim efetuar a alteração solicitada. 16 Pensando em resolver estes problemas e outros enfrentados no dia-a-dia na tarefa de coordenar o desenvolvimento de software em grupo, surgiu a idéia de estudar, detalhar e documentar os requisitos e funcionalidades desejáveis para a construção de um framework, que sirva como arquitetura para o desenvolvimento de aplicações para a indústria calçadista. Porém é importante ressaltar que para o desenvolvimento de um sistema completo de gestão, para uma indústria calçadista, outras funcionalidades seriam necessárias, porém este trabalho estará focado apenas em uma das funcionalidades, que é a persistência dos dados. O projeto visa não só facilitar o desenvolvimento de aplicações, como também propiciar ao usuário da aplicação final, funcionalidades que facilitem sua interação com o sistema, agilizando o processo de entrada, consulta e atualização das informações. A implementação e adoção de um framework para persistência de dados trará inúmeros benefícios, que dentre os quais pode-se citar: • Documentação de todas as funcionalidades existentes no sistema; • Facilidade para implementação e manutenção de novas funcionalidades no sistema; • Padronização para entrada e manutenção das informações; • Reutilização de código em outros projetos; • Aumento da produtividade; • Maior qualidade do produto final; • Maior credibilidade com os usuários da aplicação; • Melhor valorização do produto no mercado. O objetivo principal deste trabalho é pesquisar, documentar, modelar e implementar um protótipo de um framework para persistência de dados, que servirá como arquitetura para o desenvolvimento de aplicações para a indústria calçadista. Outros objetivos que se pretende com este trabalho e que podem ser citados são os seguintes: • Pesquisar e analisar técnicas de desenvolvimento de software orientado a objetos; • Estudar e definir os diagramas UML a serem utilizados; 17 • Construir um protótipo de um framework orientado a objetos para persistência de dados; • Documentar a construção de um framework orientado a objetos para persistência de dados; • Aumentar a produtividade no desenvolvimento de software; • Definir uma interface para a entrada de dados no sistema (inclusão, exclusão, alteração, consulta); • Propiciar ao usuário final, maior facilidade para acessar as informações do sistema. Este trabalho está divido em seis capítulos, estruturados da seguinte forma: O primeiro faz um levantamento dos conceitos sobre o paradigma da orientação a objetos. O capítulo 2 apresenta a UML1, sua origem, os diagramas que a compõe e a definição dos diagramas que serão utilizados neste trabalho. No capítulo 3, são descritos os conceitos de padrões, mostrando rapidamente suas origens e o catálogo de padrões publicado pela GoF (Gang of Four). Os conceitos, características e classificação de frameworks são descritos no capítulo 4, onde também é apresentando algumas vantagens e desvantagem na utilização de frameworks. A análise e a modelagem do protótipo do framework, que é o objetivo principal deste trabalho é apresentado no capítulo 5, que é composto pelos cenários, pelos diagramas UML necessários para o entendimento do projeto e a documentação básica das principais classes que compõe o framework. O capítulo 6 apresenta o protótipo do framework que foi desenvolvido com a linguagem de programação Delphi© Enterprise 6.0 Update Pack 2 e testado com o banco de dados Oracle Personal Release 8.0.4.0.0. Com a implementação do protótipo, busca-se apresentar todas as funcionalidades do framework. 1 Notação para a elaboração da estrutura de projetos de software orientados a objetos 1 CONCEITOS DE ORIENTAÇÃO A OBJETOS Programar um computador não é uma tarefa simples, pois mesmo com a ajuda de muitas ferramentas, um programador deve ter inteligência, lógica, experiência, criatividade e habilidade de localizar e utilizar abstrações para desenvolver software com qualidade. Neste sentido, o paradigma2 da OO (Orientação a Objetos) busca mostrar um nova maneira para descrevermos a nossa visão (modelo) da realidade (LEE, 2001, p. 24). Este capítulo apresenta algumas das propriedades deste paradigma da OO que auxiliam a administrar a complexidade encontrada no desenvolvimento de software. 1.1 Objetos Programas orientados a objetos são feitos de objetos. Um objeto pode ser definido como uma unidade de software que é formado por dados (atributos) e procedimentos (métodos) que operam sobre estes dados. Os procedimentos são chamados de métodos (operações) que são executados através de uma solicitação (mensagem) de um outro objeto. O objeto que envia a mensagem é chamado de cliente e o que recebe de receptor. Os dados dos objetos não podem ser acessados diretamente por outro objeto, a única maneira de mudar os dados internos dos objetos é através dos métodos, por isso diz-se que o estado interno dos objetos está encapsulado e sua representação é invisível do exterior do objeto (GAMMA, 2000, p. 27; LEE, 2001, p.24). Os métodos que um objeto disponibiliza aos outros objetos para acessarem seus dados internos, são chamados serviços públicos, porém um objeto possui outros métodos que são restritos unicamente a outros objetos específicos e são chamados de serviços protegidos e serviços privados (LEE, 2001, p. 25). 19 Todos os objetos tem uma identidade única e são distinguíveis. O termo identidade significa que um objeto é identificado pela sua própria existência, embora dois objetos da mesma classe podem conter dados iguais, eles são dois objetos distintos. Os dados de um objeto representam o estado atual do objeto. (RUMBAUGH, 1994, p. 32). Todos os objetos são criados a partir da instância de uma classe, portanto a definição dos métodos e atributos de um objeto pertencem a classe a qual ele instancia. Diz-se que um objeto é uma instância da classe. As instâncias podem ser criadas (geradas) ou destruídas (eliminadas) em tempo de execução (LEE, 2001, p. 28). 1.2 Classes Uma classe descreve um grupo de objetos com atributos idênticos, mesma semântica e com comportamento e relacionamentos comuns. Cada objeto em um classe terá os mesmos atributos e padrões de comportamento (LEE, 2001, p. 179; RUMBAUGH, 1994, p. 32). Uma classe define o estado interno do objeto e a sua representação define as operações ou métodos que o objeto pode executar (GAMMA, 2000, p. 30). As classes podem ser abstratas ou concretas. A principal finalidade de uma classe abstrata é definir uma interface comum para suas subclasses. Uma classe abstrata não poderá ser instanciada porque parte de, ou toda, sua implementação é postergada para operações definidas em suas subclasses. As operações que ela declara, mas não implementa, são chamadas operações abstratas. As classes que não são abstratas são chamadas de classes concretas e podem ser instanciadas (Ibidem, p. 31). Novas classes podem ser criadas a partir de classes existentes, utilizando-se o mecanismo de herança de classes. As subclasses criadas a partir de uma classe-mãe, herda todos os dados e operações que ela define. Os objetos que são instâncias das subclasses podem executar todas as operações definidas na subclasse e as operações definidas nas suas classes-mãe. As subclasses podem redefinir operações que foram definidas em sua classemãe, isto propicia a subclasse tratar as solicitações recebidas pela classe-mãe de forma diferente (Ibidem, p. 30). 2 Paradigma é definido como um “conjunto de teorias, padrões e métodos que juntos representam um modo de organizar conhecimento” (LEE, 2001, p. 24) 20 1.3 Herança versus Composição As duas técnicas mais comuns para a reutilização de código em sistemas orientados a objetos são a herança de classes e a composição de objetos. Através da herança de classes é possível reutilizar todo o código implementado em uma classe já existente para criar uma nova classe. Esta técnica permite que seja criado uma estrutura hierárquica de classes, onde as classes localizadas mais ao topo da hierarquia, normalmente são classes abstratas, que serão estendidas para obtenção de novas classes com funcionalidades específicas. A reutilização através de herança é freqüentemente chamada de reutilização de caixa branca, porque utilizando herança, o interior da superclasse fica visível para a subclasse (GAMMA, 2000, p. 34). A composição de objetos é uma alternativa à herança de classes. Através desta técnica, a nova funcionalidade é obtida pela montagem e/ou composição de objetos, para obter funcionalidades mais complexas. Este técnica de reutilização é chamada de reutilização de caixa preta, pois os detalhes internos do objetos não ficam visíveis para as outras classes (Ibidem). A herança e a composição têm, cada uma, vantagens e desvantagens. A herança de classes é mais simples de usar uma vez que é suportada diretamente pelas linguagens de programação, o que torna mais fácil modificar a implementação que está sendo reutilizada. A modificação do comportamento de uma classe é obtida através da redefinição das operações implementadas pela classe-mãe, que é chamado de overridden. Porém a herança de classes tem a desvantagem de que as alterações que forem realizadas na classe-mãe afetam todas as suas subclasses, desta forma as subclasses ficam amarradas as suas classes-mãe. Esta dependência limita a flexibilidade e, em última instância, a reutilizabilidade. Uma solução para este problema é herdar somente de classes abstratas, uma vez que possuem pouca ou nenhuma implementação (Ibidem). A composição de objetos mantém as classes independentes umas das outras, o que a mantém focalizada em uma única tarefa e sua hierarquia se manterá pequena e com menor probabilidade de crescer em relação a herança de classes. A composição de objetos requer que os objetos respeitem as interfaces uns dos outros, o que por sua vez, exige que as interfaces sejam cuidadosamente projetadas. Por outro lado, a composição de objetos terá mais objetos (embora menos classes), e o comportamento do sistema dependerá do inter-relacionamento 21 dos objetos ao contrário da herança de classes, onde o comportamento é definido na classe (Ibidem). Utilizando composição de objetos, um sistema deveria ser construído simplesmente montando componentes através da composição, sem necessitar criar novos componentes. Mas isto raramente ocorre, porque o conjunto de componentes disponíveis nunca é rico o suficiente para atender todas as funcionalidades requeridas. A reutilização por herança torna mais fácil criar novos componentes que podem ser obtidos pela composição de componentes existentes. Assim, a herança e a composição de objetos trabalham juntas para satisfazer as funcionalidades requeridas pelo sistema (Ibidem). 1.4 Polimorfismo A palavra polimorfismo vem do grego e significa “várias formas”. Ela pode ser definida como um dispositivo pelo qual o nome de um método pode ser definido sobre mais de uma classe e pode assumir diferentes implementações em cada uma dessas classes (PAGEJONES, 1997, p. 34). Um dos objetivos da OO é a reutilização de código e uma das formas mais efetivas é a herança de classes. Entretanto, em algumas situações existem operações que necessitam ser personalizadas para satisfazer as regras de negócio, quando isso acontece a tecnologia orientada a objeto tem um mecanismo, denominado polimorfismo, que permite a uma subclasse ter uma operação substituída por uma operação específica. Então, quando essa operação for invocada por esta subclasse, será executada a operação implementada nela (LEE, 2001, p. 181). Cada operação declarada por um objeto é definida por um nome, os objetos que ela aceita como parâmetros e o valor que ela irá retornar, a isto chama-se assinatura da operação. O conjunto de todas as operações definidas por um objeto é chamado de interface do objeto. Uma interface é denominada um tipo, portanto, quando diz-se que um objeto tem o tipo “x”, por exemplo, significa que ele aceita todas as operações definidas na interface chamada “x”. Um objeto pode possuir várias operações com mesmo nome, porém com assinaturas diferentes, então quando uma solicitação é enviada a um objeto, a operação que será executada depende da operação e do objeto receptor. A associação de qual operação será executada é feita em tempo de execução e é chamada de ligação dinâmica (GAMMA, 2000, p. 29). 22 A ligação dinâmica permite substituir objetos que tenham interfaces idênticas uns pelos outros e é também conhecida como polimorfismo (Ibidem). 1.5 Bibliotecas de Classes (toolkits) Normalmente no desenvolvimento de uma aplicação será utilizado uma ou mais bibliotecas de classes pré-definidas, chamadas toolkits. Um toolkit é um conjunto de classes relacionadas e reutilizáveis, projetadas para fornecer uma funcionalidade útil e de finalidade geral. Um exemplo de um toolkit é um conjunto de classes de coleções para listas, tabelas associativas, pilhas, etc.. A biblioteca I/O stream de C++ é um outro exemplo. Os toolkits não impõe um projeto específico à sua aplicação, simplesmente fornecem funcionalidades que podem auxiliar sua aplicação a executar o seu trabalho. Eles permitem ao desenvolvedor, evitar a recodificação de funcionalidades comuns. Os toolkits enfatizam a reutilização de código e são o equivalente em orientação a objetos a bibliotecas de sub-rotinas (GAMMA, 2000, p. 41). Em virtude dos toolkits terem que funcionar em muitas aplicações para serem úteis, o projeto de toolkits é consideravelmente mais difícil que o projeto de aplicações. Isto porque o autor do toolkit não está numa posição que lhe permita saber quais serão estas aplicações ou suas necessidades especiais. Isto torna ainda mais importante evitar suposições e dependências que podem limitar a flexibilidade do toolkit e consequentemente sua aplicabilidade e sua efetividade (Ibidem). Visando o desenvolvimento de um framework orientado a objetos os fundamentos da OO serão aplicados no desenvolvimento deste trabalho pois a implementação do framework para persistência de dados utilizará os conceitos de herança, polimorfismo e encapsulamento, o que irá proporcionar a reutilização de código3, um dos objetivos da orientação a objetos. O framework será construído sobre a arquitetura de classes extensíveis, o que representa a utilização de mais um princípio da OO. A seguir, o capítulo 2 versará sobre a UML, que é um padrão para a elaboração da estrutura de projetos de software. Mostrará sua origem, aplicação e apresentará os nove diagramas que ela possui para a modelagem orientada a objetos. 3 A reutilização de código se dará principalmente nas aplicações que usarem o framework, embora na própria construção do framework haverá reutilização de código. 2 UML A UML é um padrão para a elaboração da estrutura de projetos de software. A UML poderá ser empregada para a visualização, a especificação, a construção e a documentação de artefatos que façam uso de sistemas complexos de software. Além disso, é uma tentativa de padronizar a modelagem orientada a objetos de uma forma que qualquer sistema, seja qual for o tipo, possa ser modelado corretamente, com consistência, fácil de se comunicar com outras aplicações, simples de ser atualizado e compreensível (BOOCH, 2000, p. 15). 2.1 Origem As linguagens de modelagem orientada a objetos surgiram entre a metade da década de 1970 e final da década de 1980, incentivados pela complexidade cada vez maior dos sistemas. Diante de um novo gênero de linguagens orientada a objetos, no período de 1989 a 1994, os métodos orientado a objetos aumentaram de um pouco mais de 10 para mais de 50. Os desenvolvedores tiveram enormes dificuldades para escolher um método que atendessem a todas as suas necessidades. Os métodos até então utilizados tinham pontos fortes e fracos. Então os autores das três principais metodologias de modelagem orientada a objetos, Grady Booch4, Ivar Jacobson5 e James Rumbaugh6, resolveram trazer as melhores idéias de cada uma destas metodologias e mostrar como deveria ser a migração de cada uma para a UML (BOOCH, 2000, p. XVI; LARMAN, 2000, p. 38). 4 O método Booch era expressivo principalmente durante as fases de projeto e construção de sistemas. 5 O método OOSE (Object Oriented Software Engineering) fornecia excelente suporte para a análise e projeto em alto nível 6 O método OMT (Object Modeling Technique) era mais útil para análise e sistemas de informações com o uso intensivo de dados. 24 A criação da UML iniciou oficialmente em outubro de 1994, quando Rumbaugh se juntou a Booch na Rational. O foco inicial do projeto era a unificação dos métodos Booch e OMT (Object Modeling Technique). O esboço da versão 0.8 do método unificado foi lançado em outubro de 1995. Mais ou menos na mesma época Jacobson se associou a Rational com a finalidade de incorporar o OOSE (Object Oriented Software Engineering) no escopo inicial da versão 0.8, resultando o lançamento da versão 0.9 da UML em junho de 1996 (BOOCH, 2000, p. XVII; LARMAN, 2000, p. 38). Em resposta a uma solicitação do OMG7 (Object Management Group), para definir uma linguagem e notação de modelagem padronizada, a UML 1.0 foi oferecida para padronização em janeiro de 1997. Eles disponibilizaram inúmeras versões preliminares desta linguagem para a comunidade de desenvolvedores e a resposta incrementou muitas novas idéias que a melhoraram ainda mais. Em 14 de novembro de 1997 uma versão revisada da UML (versão 1.1), foi adotada pelo OMG (BOOCH, 2000, p. XVII; LARMAN, 2000, p. 38). 2.2 Aplicação A UML é uma linguagem padrão para a elaboração da estrutura de projetos de software. A UML poderá ser empregada para a visualização, especificação, construção e documentação de artefatos que façam uso de sistemas complexos de software (BOOCH, 2000, p. 13). Pode-se dividir a visualização em textual e gráfica. A modelagem textual é uma forma mínima e direta para escrever expressões e algoritmos, porém poderá trazer alguns problemas, como erro de comunicação entre as pessoas envolvidas, dificuldade de descrever aspectos complexos de um sistema e a falta de documentação e histórico dos modelos anteriores a algumas mudanças que comumente são necessárias. A UML é mais do que um punhado de símbolos gráficos, por trás de cada símbolo empregado na notação da UML existe uma semântica bem definida. Dessa maneira, um modelo escrito por um desenvolvedor, poderá ser interpretado sem ambigüidades por outro desenvolvedor, ou até mesmo outra ferramenta (BOOCH, 2000, p. 15). O emprego da UML na especificação significa construir modelos precisos, sem ambigüidades e completos. A UML atende a todas as decisões importantes que devem ser 7 Uma entidade que fornece diretrizes para a indústria de software, através de especificações de padrões. 25 tomadas para o desenvolvimento e implantação de sistemas complexos de software, em termos de análise, projeto e implementação. (Ibidem, p. 16). Embora a UML não seja uma linguagem visual de programação, pode ser utilizada para a construção, pois seus modelos podem ser diretamente conectados a várias linguagens de programação. Isso significa que é possível mapear os modelos da UML em linguagens de programação tais como Java, C++, Visual Basic ou até tabelas de bancos de dados relacionais ou o armazenamento de dados persistentes em um banco de dados orientado a objetos. Enquanto as linguagens de programação representam o que é melhor expresso em termos textuais, a UML é utilizada para representar tudo que possa ser melhor expresso em termos gráficos (Ibidem). A UML abrange a documentação da arquitetura do sistema e de todos seus detalhes, como a expressão de requisitos e realização de testes. Portanto pode-se afirmar que a UML é uma linguagem para modelagem das atividades de planejamento do projeto e de gerenciamento de versões (Ibidem, p. 17). 2.3 Diagramas da UML Segundo Booch, quando uma pessoa realiza uma modelagem, ela simplifica a realidade para um melhor entendimento do sistema em desenvolvimento. Em UML os modelos são desenvolvidos a partir de blocos de construção básicos, como classes, interfaces, colaborações, componentes, nós, dependências, generalizações e associações. Os diagramas são meios utilizados para visualização desses blocos de construção (BOOCH, 2000, p. 89). A UML define nove tipos de diagramas, que são classificados em diagramas estruturais e diagramas comportamentais, conforme mostra a tabela 2-1. Diagramas Estruturais Diagramas Comportamentais Diagrama de classes Diagrama de caso de uso Diagrama de objetos Diagrama de seqüência Diagrama de componentes Diagrama de colaboração Diagrama de implantação Diagrama de estados Diagrama de atividade Tabela 2-1 Diagramas da UML (GAMMA, 2000) 26 2.3.1 Diagrama de Classes Um diagrama de classe mostra um conjunto de classes, interfaces, colaborações e seus relacionamentos. Os diagramas de classes são os mais encontrados em sistemas de modelagem orientado a objetos (BOOCH, 2000, p. 94). Uma classe em UML é representada por uma caixa retangular com três compartimentos: o primeiro com o nome da classe, o do meio com a lista de atributos da classe e o último com a lista de operações da classe. As associações representam relacionamentos estruturados entre objetos de diferentes classes, e são representados graficamente através de uma linha conectando as classes. Uma associação pode ter um nome, e as extremidades da linha que representa uma associação pode ter nome de papéis mostrando como a classe é vista pelas outras classes na associação, conforme mostra a figura 2-1 (BEZERRA, 2002, p. 97). Figura 2-1 Diagrama de classes 2.3.2 Diagrama de Objetos Um diagrama de objetos mostra um conjunto de objetos e seus relacionamentos em determinado ponto no tempo. Esses diagramas ilustram as estruturas de dados, registros estáticos de instâncias dos itens encontrados nos diagramas de classes. Os diagramas de objetos apresentam a visão estática do processo de um sistema, tal qual os diagramas de classes, mas considerando casos reais ou prototípicos (BOOCH, 2000, p.192). 27 Estes diagramas são importantes para a visualização, especificação e documentação de modelos estruturais e também para a construção de aspectos estáticos do sistema (Ibidem). Em um diagrama de objetos, cada objeto é representado por um retângulo com dois compartimentos. No compartimento superior é exibido o nome do objeto e no compartimento inferior (cuja utilização é opcional), aparecem valores para os atributos definidos na classe do objeto, conforme mostra a figura 2-2 (BEZERRA, 2002, p. 128). Figura 2-2 Diagrama de objetos 2.3.3 Diagrama de Componentes Um diagrama de componentes mostra um conjunto de componentes e seus relacionamentos, conforme mostra a figura 2-3. Os diagramas de componentes estão relacionados aos diagramas de classes, pois tipicamente um componente mapeia uma ou mais classes, interfaces ou colaborações (BOOCH, 2000, p.26). Os diagramas de componentes são utilizados para a modelagem da visão estática da implementação de um sistema. Isto envolve a modelagem de itens físicos que residem em um nó, como executáveis, bibliotecas, tabelas, arquivos e documentos. (Ibidem, p.387). 28 Figura 2-3 Diagrama de componentes 2.3.4 Diagrama de Implantação Os diagramas de implantação mostram a configuração de nós de processamento em tempo de execução e os componentes existentes nele, conforme mostra a figura 2-4. Os diagramas de implantação são essencialmente diagramas de classes que focalizam os nós do sistema e são utilizados para a modelagem da visão estática de implantação. Essa visão focaliza primeiramente a distribuição, entrega e instalação das partes que formam o sistema físico, embora na maioria das vezes, isso envolve a modelagem da topologia do hardware em que o sistema é executado. Eles são importantes para visualizar, especificar e documentar sistemas embutidos, cliente/servidor e distribuídos. (BOOCH, 2000, p. 402). Figura 2-4 Diagrama de implantação 29 2.3.5 Diagrama de Caso de Uso Um diagrama de caso de uso mostra um conjunto de caso de uso e atores e seus relacionamentos. Os diagramas de caso de uso são importantes principalmente para a organização e modelagem dos comportamentos de um sistema (BOOCH, 2000, p. 26). Os casos de uso geralmente são o ponto de partida da análise orientada a objetos utilizando a UML. Os atores representam usuários e outros sistemas que interagem com sistema modelado. Eles são representados graficamente pela figura de um boneco. Os casos de uso mostram o comportamento do sistema, cenários que o sistema percorre em resposta ao estímulo de um ator. O caso de uso é representado por uma elipse e o nome do caso de uso pode aparecer dentro ou abaixo da elipse, conforme mostra a figura 2-5 (LEE, 2001, p. 51). Figura 2-5 Diagrama de caso de uso 2.3.6 Diagrama de Seqüência Um diagrama de seqüência mostra a ordem temporal em que as mensagens são trocadas entre o ator e o sistema. Um diagrama de seqüência mostra um conjunto de objetos e as mensagens enviadas e recebidas por esses objetos. Tipicamente os objetos são instâncias nomeadas ou anônimas de classes, mas também podem representar instâncias de outros itens, como colaborações, componentes e nós (BOOCH, 2000, p. 241). Conforme mostra a figura 2-6, os objetos são representados por linhas tracejadas verticais, e a troca de mensagens entre dois objetos é representada por vetores horizontais identificados pela mensagem que está sendo passada. As mensagens são desenhadas em ordem cronológica do topo à base do diagrama (LEE, 2001, p. 52). 30 Figura 2-6 Diagrama de seqüência 2.3.7 Diagrama de Colaboração Um diagrama de colaboração dá ênfase a organização estrutural dos objetos que enviam e recebem mensagens. Um diagrama de colaboração mostra um conjunto de objetos, as conexões existentes entre estes objetos e as mensagens enviadas e recebidas pêlos objetos, conforme mostra a figura 2-7. Tipicamente os objetos são instâncias nomeadas ou anônimas de classes, mas também podem representar instâncias de outros itens, como colaborações, componentes e nós (BOOCH, 2000, p. 246). Figura 2-7 Diagrama de colaboração 31 2.3.8 Diagrama de Estados Um diagrama de gráfico de estados mostra uma máquina de estados, que consiste de estados, transições, eventos e atividades, conforme pode-se observar na figura 2-8. Esses diagramas são importantes principalmente para se fazer a modelagem do comportamento de uma interface, classe ou colaboração. (BOOCH, 2000, p. 332). O estado é uma situação na vida de um objeto durante a qual ele satisfaz alguma condição ou realiza alguma atividade. Um evento é a ocorrência de um estímulo capaz de ativar uma transação de estado. Uma transição é um relacionamento entre dois estados e indica que se ocorrer um determinado evento e as condições forem satisfeitas, o objeto realizará certas ações e passará de um estado para outro (Ibidem). Figura 2-8 Diagrama de estados 2.3.9 Diagrama de Atividade Um diagrama de atividade mostra um conjunto de atividades, o fluxo seqüencial ou ramificado de uma atividade para outra e, os objetos que realizam ou sofrem ações, conforme apresenta a figura 2-9. Esses diagramas são importantes principalmente para se fazer a modelagem da função de um sistema. Os diagramas de atividades dão ênfase ao fluxo de controle entre atividades (BOOCH, 2000, p. 255). 32 O diagrama de atividade é um tipo especial de diagrama de estados, onde são representados os estados de uma atividade, ao invés de um objeto. Ao contrário do diagrama de estados que são orientados a eventos, os diagramas de atividade são orientados a fluxo de controle. Semelhante a um fluxograma, mas com notação ligeiramente diferente, o diagrama de atividade pode ser visto como uma extensão do fluxograma e possui notação para representar ações concorrentes (paralelas), juntamente com sua sincronização (BEZERRA, 2002, p. 228). Figura 2-9 Diagrama de atividade 2.4 Diagramas e Ferramentas Utilizadas A UML é uma notação suficientemente expressiva, abrangendo todas as visões necessárias ao desenvolvimento e implantação de sistemas, cuja abrangência poderá incluir sistemas de informações corporativas a aplicações baseadas em Web e até sistemas complexos de tempo real. Apesar de sua expressividade, não é difícil compreender e usar a UML (BOOCH, 2000, p. 13). Para a implementação do framework, a modelagem e a documentação do projeto foi feita utilizando a UML, pois pode-se dizer que a UML é uma parte fundamental de qualquer projeto orientado a objetos. 33 A UML apresenta nove diagramas diferentes que podem ser utilizados para representar a modelagem de um sistema. No entanto, neste trabalho serão utilizados apenas os diagramas necessários para modelar o domínio do problema de forma consistente e que facilite a sua compreensão, implementação e manutenção. Os diagramas utilizados foram os seguintes: Diagrama de Caso de Uso, Diagrama de Classes, Diagrama de Estados e Diagrama de Seqüência. É importante observar que estes diagramas são parte importante da documentação do protótipo de framework que foi implementado. Para realizar a modelagem foi estudado a viabilidade de uma dentre três ferramentas encontradas no mercado. As ferramentas pesquisadas foram as seguintes: • Poseidon for UML© 1.6.1, disponível em www.gentleware.com • Rational Rose Enterprise Editon©, disponível em www.rational.com • ModelMaker© 6.2, disponível em www.modelmakertools.com Optou-se por utilizar a ferramenta ModelMaker©, por ser integrada com o ambiente de desenvolvimento Delphi© da Borland, com o qual foi implementado o protótipo para o framework. Convém ressaltar que a Rational Rose Enterprise Edition©, é uma ferramenta mais completa, porém é paga e sua utilização é permitida apenas por 30 dias. O Poseidon for UML© é uma ferramenta freeware mais não foi adotada por deficiências da ferramenta em disponibilizar um formato de arquivo que não utiliza-se muita memória para exportar os diagramas e não possuir uma opção para gerar a documentação das classes no formato do Microsoft© Word. O próximo capítulo versará sobre padrões de projeto, definirá como descrever um padrão de projeto, apresentará o catálogo de padrões segundo Gamma e versará também sobre metapadrões, que constituem uma abordagem complementar ao padrões de projeto propostos por Gamma (GAMMA, 2000). 3 PADRÕES A origem dos padrões de projeto deu-se com o trabalho feito pelo arquiteto Christopher Alexander no final dos anos 70, que além de exemplificarem, descrevem seu método para documentação de padrões. O trabalho de Alexander, apesar de ser voltado para a arquitetura, possui uma fundamentação básica que pode ser abstraída para a área de software (GERBER, 1999, p. 24). Os conceitos de padrões começaram a ser introduzidos na comunidade de software no fim dos anos 80 e no início dos anos 90, entretanto foram realmente conhecidos e popularizados através da publicação dos Design Patterns (Padrões de Projeto), da chamada Gang of Four. Este livro apresenta um catálogo de padrões para o projeto de software orientado a objetos, que documenta as suas experiências na resolução de problemas de projeto independente de domínio de aplicação. O catálogo registra diversas soluções satisfatórias que eles encontraram durante o desenvolvimento de frameworks, relacionados principalmente por problemas de reusabilidade, flexibilidade, modularidade, etc. (Ibidem). A reutilização de projetos e arquiteturas bem sucedidas se tornam mais fáceis quando são utilizados padrões de projeto, pois expressar técnicas testadas e aprovadas facilitam o entendimento e aceitação dos desenvolvedores de novos sistemas. Os padrões de projeto podem melhorar a documentação e facilitar a manutenção de sistemas pois fornecem uma especificação explícita de interações de classes e objetos e o seu objetivo subjacente. Em resumo, ajudam o projetista a obter um projeto “certo” mais rápido (GAMMA, 2000, p. 18). 3.1 Descrevendo Padrões de Projeto Existem várias formas de documentar um padrão, ou seja, alguns autores os descrevem através de um conjunto de elementos, muitas vezes diferente dos elementos adotados por outros autores. Ainda não se chegou a um acordo entre os autores para que os 35 mesmos utilizem uma forma única de documentação de padrões. Os elementos utilizados para descrever um padrão são muito importantes uma vez que eles contêm todas as informações que se precisa para poder entendê-los e utilizá-los de forma apropriada em projetos. Os padrões de projeto catalogados conforme Gamma, possui um formato bastante estruturado, conhecido como GoF format, o qual é dividido em 13 seções, os quais representam os elementos essenciais que devem existir na descrição de padrões (GAMMA, 2000). Segundo Gamma (2000, p. 22) e Vlissides (1995, p. 2), os elementos que descrevem um padrão de projeto são: O primeiro elemento, denominado Nome e classificação do padrão, determina que todo padrão precisa ter um nome pelo qual ele será conhecido entre a comunidade. Este nome deve ser composto por uma palavra significativa e deve ser o mais curto possível. É através dele que as pessoas irão se referenciar ao padrão. Muitas vezes a literatura apresenta o mesmo padrão com outros nomes, ou então a comunidade poderá conhecê-lo por um nome diferente. Estes nomes devem ser documentados na seção “Também conhecido como”. O segundo elemento, denominado Intenção e objetivo, determina que ele deve conter um pequeno parágrafo que explique qual é o propósito deste padrão e mostre claramente qual o problema de projeto que ele se propõe a resolver. Alguns autores dão o nome a este elemento de “problema”, já que ele deve descrever o problema que se propõe a resolver. O terceiro elemento, denominado também conhecido como, descreve todos aqueles nomes pelo qual o padrão também é conhecido. Muitas vezes um padrão possui vários nomes, sendo necessário documentar todos eles. Por exemplo o Design Pattern Command é também conhecido como Action e Transaction. Caso um padrão seja conhecido somente por um nome como é o caso de Singleton, então esta seção simplesmente não aparecerá na descrição do padrão. O quarto elemento, denominado motivação, descreve um cenário no qual aparece um problema de projeto e mostra como os objetos e outras estruturas do padrão irão resolver este problema. O quinto elemento, denominado aplicabilidade, mostrará quais são as situações onde o padrão poderá ser aplicado. Que exemplos de mau projeto ele pode tratar e como pode-se reconhecer estas situações. 36 O sexto elemento, denominado estrutura, mostra uma representação gráfica das classes envolvidas no padrão. Esta seção é muito importante, pois as representações gráficas do padrão ajudam muito para o seu entendimento. Esta representação gráfica é baseada na notação da OMT. Também são usados, em alguns casos, diagramas de interação para mostrar a relação entre os objetos. O sétimo elemento, denominado participantes, apresenta todas as classes e/ou objetos que fazem parte do padrão de projeto e ao mesmo tempo as responsabilidades de cada uma. O oitavo elemento, denominado colaboração, apresenta como os componentes do padrão, colaboram para executar suas responsabilidades. O nono elemento, denominado conseqüências, apresenta as possíveis conseqüências da adoção deste padrão. Muitas vezes a utilização de um padrão pode ter algumas conseqüências para o software que precisam ser analisadas antes de implementá-lo. É mostrado, também, como o padrão lida com estas conseqüências. O décimo elemento, denominado implementação, descreve sobre a implementação do padrão, que cuidados deve-se tomar ao implementar. Dará dicas de implementação e mostrará se alguma coisa do padrão é específico da linguagem. O décimo primeiro elemento, denominado exemplo de código, apresenta um ou mais exemplos da aplicação deste padrão, isto facilita o entendimento e utilização do mesmo. Normalmente estes exemplos de código são apresentados em C++ ou Smalltalk. O décimo segundo elemento, denominado usos conhecidos, apresenta exemplos da utilização deste padrão em sistemas reais, incluído pelo menos dois, de domínios diferentes. Estes exemplos devem mostrar como o problema pode ser resolvido. O décimo terceiro elemento, denominado padrões relacionados, mostra aqueles padrões que possuem alguma relação com este que está sendo apresentado. Normalmente aqueles que se relacionam compartilham recursos. Estes elementos apresentados acima devem, segundo o livro da Gang Of Four, estar presentes na descrição de um padrão de projeto. Uma descrição completa de um padrão é muito importante para que o mesmo possa ser utilizado. 37 Figura 3-1 Elementos de padrões segundo GoF 3.2 O Catálogo de Padrões de Projeto Gamma (2000, p. 24) descreve um grupo de 23 padrões de projeto, organizados em um catálogo, que descrevem boas soluções de software de uso geral, ou seja, independente de domínio de aplicação e que podem ser aplicadas em qualquer projeto orientado a objetos. A tabela 3-1 descreve estes 23 padrões de projeto catalogados por Gamma. Padrão Intenção Abstract Fornece uma interface para a criação de famílias de objetos relacionados Factory ou dependentes sem especificar suas classes concretas. Adapter Converte a interface de uma classe em outra interface esperada pelos clientes. O adapter permite que certas classes trabalhem e, conjunto, pois de outra forma seria impossível por causa de suas interfaces incompatíveis. Bridge Separa uma abstração da sua implementação, de modo que as duas possam variar independentemente. 38 Padrão Intenção Builder Separa a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção possa criar diferentes representações. Chain of Evita o acoplamento do remetente de uma solicitação ao seu destinatário, Responsibility dando a mais de um objeto a chance de tratar a solicitação. Encadeia os objetos receptores e passa a solicitação ao longo da cadeia até que um objeto trate. Command Encapsula uma solicitação como um objeto, desta forma permitindo que se parametrize clientes com diferentes solicitações, enfileire ou registre (log) solicitações e suporte operações que podem ser desfeitas. Composite Compõe objetos em estruturas de árvore para representar hierarquias do tipo partes-todo. O composite permite que os clientes tratem objetos individuais e composições de maneira uniforme. Decorator Atribui responsabilidades adicionais a um objeto dinamicamente. O decorator fornece uma alternativa flexível a subclasses para extensão da funcionalidade. Façade Fornece uma interface unificada para um conjunto de interfaces em um subsistema. O façade define um interface de nível mais alto que torna o subsistema mais fácil de usar. Factory Method Define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe a ser instanciada. O factory method permite a uma classe postergar a instanciação às subclasses. Flyweight Usa compartilhamento para suportar grandes quantidades de objetos, de granularidade fina, de maneira eficiente. Interpreter Dada uma linguagem, define uma representação para sua gramática juntamente com um interpretador que usa a representação para interpretar sentenças nesta linguagem. Iterator Fornece uma maneira de acessar seqüencialmente os elementos de um objeto agregado sem expor sua representação subjacente. 39 Padrão Intenção Mediator Define um objeto que encapsula como um conjunto de objetos interage. O mediator promove o acoplamento fraco ao evitar que os objetos se refiram explicitamente uns aos outros, permitindo que se varie suas interações independentemente. Memento Sem violar a encapsulação, captura e externaliza um estado interno de um objeto, de modo que o mesmo possa posteriormente ser restaurado para este estado. Observer Define uma dependência um-para-muitos entre objetos, de modo que, Quando um objeto muda de estado, todos os seus dependentes são automaticamente notificados e atualizados. Prototype Especifica os tipos de objetos a serem criados usando uma instância prototípica e ciar novos objetos copiando este protótipo. Proxy Fornece um objeto representante, ou um marcador de outro objeto, para controlar o acesso ao mesmo. Sigleton Garante que uma classe tenha somente uma instância e fornece um ponto global de acesso para ela. State Permite que um objeto altere seu comportamento Quando seu estado interno muda. O objeto parecerá ter mudado sua classe. Strategy Define uma família de algoritmos, encapsula cada um deles e os faz intercambiáveis. O strategy permite que o algoritmo varie independentemente dos clientes que o utilizam. Template Define o esqueleto de um algoritmo em uma operação, postergando a Method definição de alguns passos para subclasses. O template method permite que as subclasses redefinam certos passos de um algoritmo sem mudar sua estrutura. Visitor Representa uma operação a ser executada sobre os elementos da estrutura de um objeto. O visitor permite que se defina uma nova operação sem mudar as classes dos elementos sobre os quais opera. Tabela 3-1 Catálogo de padrões de projeto (GAMMA, 2000) 40 3.3 Organização do Catálogo Os padrões de projeto da GoF são organizados no catálogo de acordo com dois critérios principais, que são o propósito e escopo, conforme mostra a tabela 3-2. O primeiro critério, chamado propósito, reflete o que o padrão faz, e pode ser criacional, estrutural ou comportamental. Padrões criacionais preocupam-se com o processo de instanciação de objetos, estruturais tratam de problemas de composição de classes e objetos, comportamentais definem o modo em que classes e objetos interagem e distribuem responsabilidades (GAMMA, 2000, p. 25). O critério escopo especifica se o foco do padrão é dado sobre classes ou objetos, que podem ser class (classe) ou object (objeto). Em resumo, padrões com escopo classe trabalham com relacionamentos entre classes e subclasses, através do mecanismo de herança, e padrões com escopo objeto trabalham com relacionamentos entre objetos, obtidos através do mecanismo de composição de objetos (Ibidem, p. 26). Tabela 3-2 Organização do catálogo de padrões (MALDONADO, 2001, p. 12) 3.4 Metapadrões Metapatterns (metapadrões) constituem uma abordagem complementar à abordagem de padrões de projeto proposta por Gamma (GAMMA, 2000). Os metapadrões se originaram da observação de aspectos comuns dos padrões de projeto. Pree observou e classificou alguns arranjos de funcionalidades sobre métodos, que se repetem em diferentes padrões de projeto – o que denominou padrões (PREE, apud SILVA, 2000, p. 56). Os padrões de projeto de Gamma tratam da combinação de um conjunto de classes com divisão de responsabilidades, para a solução de um problema de projeto específico, como 41 por exemplo, a questão do estado de um objeto ser alterado em função da mudança de estado de outro objeto, tratada pelo padrão de projeto Observer. Os metapadrões trabalham em um nível de abstração superior, em relação aos padrões de projeto. Definem como manter a flexibilidade das classes, encapsulando a funcionalidade sujeita a alteração em métodos hook, chamados por métodos template8 (Ibidem). Segundo Pree, os metapadrões se prestam principalmente a produzir a documentação de projeto de um framework cuja estrutura já esteja estável9. Neste caso, os metapadrões presentes no framework são destacados na documentação de projeto, ressaltando o que se decidiu manter flexível e de que modo, e o que se decidiu manter inflexível. A noção básica é que a inclusão de um método template define uma estrutura de algoritmo que se deseja manter estável. A flexibilidade permitida pelo projetista é concentrada na funcionalidade acessada através da chamada de métodos hook (pelo método template). A documentação de projeto destacando as características de flexibilidade usando metapadrões registra decisões de projeto (Ibidem, p. 57). A utilização de metapadrões em desenvolvimento de projeto, segundo propõe Pree, está intimamente ligada a abordagem de projeto hot-spots-driven design. Nesta abordagem são identificadas as partes de projeto que se deve manter flexíveis, que constituem os hotspots. Em contraste, as partes estáveis constituem os frozen-spots. Frozen-spots podem dar origem a métodos templates – que tem comportamento flexível em função do uso de métodos hook. A identificação de estruturas de algoritmos estáveis (frozen-spots) que podem ter partes variáveis (hot-spots), define a necessidade de um metapadrão. A escolha do metapadrão depende da flexibilidade requerida (por exemplo se há necessidade de alteração de comportamento em tempo de execução), e de características específicas do projeto tratado (Ibidem). Os metapadrões constituem uma proposta de padrão de solução para problemas de projeto distinta da proposta de Gamma (GAMMA, 2000). Metapadrões estabelecem como manter a flexibilidade de um procedimento, implementando-o através de métodos template e 8 Um método template é um método que ao ser executado invoca pelo menos um outro método – um método hook. O método template comporta a parte imutável de um procedimento. A flexibilização de um procedimento ocorre através da troca do(s) método(s) hook invocado(s) (SILVA, 2000). 9 Esta noção de estabilidade se refere ao fato de que um framework que foi utilizado para gerar poucas aplicações, possivelmente precisará ser alterado (a medida em que novas informações de domínio são obtidas, a partir do desenvolvimento de novas aplicações). Apenas um framework usado para gerar muitas aplicações de um domínio, chega a uma estrutura menos sujeita a alterações (GAMMA, 2000). 42 hook. O método template encapsula a parte estável do procedimento (a generalidade), enquanto que através do uso de diferentes métodos hook, podem-se estabelecer diferentes variações de comportamento para o procedimento (Ibidem). 3.5 Padrões de Projeto e Frameworks Padrões de projeto e frameworks seguidamente são confundidos e até apresentados como sendo uma mesma técnica. Aparentemente são coisas semelhantes, mas na verdade possuem uma diferença bem clara. Cada um se ocupa com coisas diferentes e fundamentais para o desenvolvimento de software. Talvez o motivo maior da confusão entre estes dois conceitos seja em função de ambos darem ênfase a um fator muito importante, o reuso. Segundo Gamma as três principais diferenças entre framework e padrões de projeto, são: Padrões de projeto são mais abstratos que frameworks. Frameworks podem ser utilizados diretamente no código, mas somente exemplos de padrões podem ser utilizados no código. A vantagem dos frameworks é que eles podem ser escritos com linguagens de programação e não somente estudados mas executados e reutilizados diretamente. Ao contrário os padrões de projeto descritos devem ser implementados cada vez que irão ser utilizados. Padrões de projeto também explicam o objetivo, custo e benefício, e as conseqüências de um projeto; padrões de projeto são elementos de arquitetura menores do que frameworks. Um típico framework contém diversos padrões de projeto, mas a recíproca nunca é verdadeira; padrões de projeto são menos especializados que frameworks. Frameworks sempre tem um domínio particular de aplicação. Um framework para um editor gráfico poderia ser usado na simulação de uma fábrica, mas ele não seria confundido com um framework para simulação. Em contraste, os padrões de projeto, podem ser usados em quase qualquer tipo de aplicação (GAMMA, 2000, p. 43). Frameworks estão se tornando cada vez mais comuns e importantes. Eles são a maneira pela qual sistemas orientado a objetos conseguem um maior grau de reutilização. Aplicações maiores orientada a objetos terminarão por constituir-se de camadas de frameworks que cooperam uns com os outros. A maior parte do projeto e do código da aplicação virá dos, ou será influenciada pelos frameworks que utiliza (Ibidem). Os padrões de projeto constituem uma parte importante da construção do framework para persistência de dados, pois a sua utilização proporcionará uma melhor organização da estrutura das classes do framework. A origem dos padrões de projeto e metapadrões está na busca de estruturas de projeto flexíveis, que são obtidas através da distribuição de 43 responsabilidades entre um conjunto de classes (ao invés de concentrar sobre uma classe) procurando mantê-las o mais desacopladas possível. A flexibilidade proporcionada pela utilização de padrões de projeto e metapadrões na construção do framework para persistência de dados é outro benefício que será obtido com a utilização do framework para o desenvolvimento de aplicações. A seguir, o capítulo 4 apresentará alguns conceitos e características de frameworks, segundo vários autores, e algumas vantagens e desvantagens em se utilizar esta tecnologia. Será apresentado também os indivíduos envolvidos com o uso e construção de frameworks. 4 FRAMEWORKS Diversas definições são encontradas para o termo framework orientado a objetos. Um framework pode ser considerado como “um projeto reutilizável de uma parte ou de todo um sistema, que é representado por um conjunto de classes abstratas e pelo modo que elas interagem” ou “um esqueleto de uma aplicação que pode ser customizado para desenvolver outras aplicações” (JOHNSON, 1997, p. 39). Segundo Fayad (1997, p. 1) um framework pode ser definido como “uma aplicação reutilizável, semi-completa, que pode ser especializada para produzir aplicações específicas”. Segundo Gamma (2000, p. 41) um framework é um conjunto de classes cooperantes que constróem um projeto reutilizável para uma família específica de software. Um framework fornece uma orientação arquitetural através da divisão do projeto em classes abstratas e definindo as suas responsabilidades e colaborações. Um desenvolvedor irá customizar um framework para uma aplicação particular através de subclasses e compor instâncias de classes do framework (GAMMA, 2000, p. 41). Ainda de acordo com a Gang Of Four '', o framework dita a arquitetura da aplicação. Ele irá definir toda a estrutura, sua divisão em classes e objetos, as responsabilidades do framework, como as classes e objetos colaboram, e o fluxo de controle. Um framework predefine estes parâmetros de projeto, então o projetista/implementador da aplicação, pode se concentrar nas especificidades da aplicação. Um framework captura as decisões que são comuns ao domínio da aplicação. Frameworks então enfatizam o reuso de projeto mais do que o reuso de código, ainda que um framework possa normalmente incluir subclasses concretas que podem ser utilizadas imediatamente (Ibidem, p. 42). Frameworks diferem de bibliotecas de classes porque apresentam uma inversão do fluxo de controle, entre os frameworks e os desenvolvedores usuários dos frameworks. Projetos baseados em bibliotecas de classes tradicionalmente forçam o desenvolvedor a 45 reescrever todo o fluxo da aplicação. Ao contrário, projetos baseados em frameworks colocam o framework no controle do fluxo, onde o desenvolvedor reescreve apenas métodos especiais que adaptam a funcionalidades do framework, os quais são chamados pelo próprio framework (GAMMA, 2000, p. 42; LARMAN, 2000, p. 439; JOHNSON, 1988, p. 4; MALDONADO, 2001, p. 22). A figura 4-1 mostra as principais diferenças entre frameworks e bibliotecas de classes. Figura 4-1 Frameworks x bibliotecas de classes (MALDONADO, 2001, P. 22) 4.1 Classificação dos Frameworks Frameworks são classificados sobre diferentes pontos de vista, segundo alguns autores, caracterizando tipos distintos de frameworks de acordo com os seus propósitos. Fayad classifica frameworks em três grupos: frameworks de infra-estrutura do sistema, frameworks de integração e frameworks de aplicação (FAYAD, 1997, p. 2; FAYAD, 1999, p. 10). Frameworks de infra-estrutura do sistema simplificam o desenvolvimento da infraestrutura de sistemas portáveis e eficientes, como por exemplo os sistemas operacionais, sistemas de comunicação, interfaces com o usuário e ferramentas de processamento de linguagem. Em geral são usados internamente em uma empresa de software e não são vendidos diretamente a clientes. Frameworks de integração são usados, para integrar aplicações e componentes distribuídos. Eles são projetados para aumentar a habilidade de desenvolvedores em modularizar, reutilizar e estender sua infra-estrutura de software para funcionar em um ambiente distribuído. Exemplo dessa classe de framework é o ORB (Object Request Broker). 46 Frameworks de aplicação estão voltados a domínios de aplicações mais amplos e são a base para as atividades de negócios das empresas, como por exemplo sistemas de telecomunicações, aviação, manufatura e engenharia financeira. Estes são geralmente os mais caros de serem desenvolvidos e/ou comprados, porém podem trazer um retorno significativo do investimento, já que permitem o desenvolvimento de aplicações e produtos diretamente. Frameworks deste grupo capturam elementos invariantes de domínio, e deixam em aberto aspectos específicos de cada aplicação. Já os frameworks de infra-estrutura e integração preocupam-se basicamente com problemas internos de desenvolvimento de software. Embora eles sejam importantes para desenvolvimento rápido de software com qualidade, não geram um retorno significativo do investimento. Este tipo de framework é mais vantagem comprá-lo do que construir um (FAYAD, 1997, p. 2). 4.2 Frameworks Caixa Branca X Caixa Preta Para se definir o comportamento específico de um framework de aplicação geralmente novos métodos são adicionados às subclasses de uma ou mais de suas classes e estes novos métodos devem atender as convenções internas da superclasse (JOHNSON, 1988, p. 4). Segundo Johnson (1988, p. 4) dependendo de como o framework for customizado, pode ser classificado como caixa branca ou caixa preta. No framework caixa branca o usuário deve estender as classes que constituem o framework para criar aplicações específicas, ou seja, a reutilização é obtida através da herança. Isso dificulta muito sua utilização, porque ele necessita entender detalhes de como o framework funciona para poder usá-lo e ensinar como funciona é quase o mesmo trabalho de ensinar como criá-lo. Já no framework caixa preta o reuso é obtido através da composição, ou seja, o usuário combina diversas classes concretas existentes no framework para obter a aplicação desejada. Neste caso, ele deve entender apenas a interface para poder usá-lo. Johnson afirma que o ideal é que cada framework caixa branca evolua para um framework caixa preta, por isso os frameworks caixa branca devem ser vistos como uma fase natural na evolução de um sistema, que será algum dia um passo na evolução de uma coleção de métodos em um conjunto de componentes. Um aspecto variável de um domínio de aplicação é chamado de hot-spot (ponto de especialização) (BUSCHMAN, apud MALDONADO, 2001, p. 23). Diferentes aplicações 47 dentro de um mesmo domínio são distinguidas por um ou mais hot-spots. Eles representam as partes do framework de aplicação que são específicas de cada sistema. Os hot-spots são projetados para serem genéricos, mas podem ser adaptados às necessidades de cada aplicação (MALDONADO, 2001, p. 23). Frozen-spots (pontos fixos) definem a arquitetura geral de um sistema de software – seus componentes básicos e os relacionamentos entre eles. Os frozen-spots permanecem fixos em todas as instanciações do framework de aplicação. A figura 4-2 ilustra um framework caixa branca com um único hot-spot R. Para utilização do framework é necessário fornecer a implementação referente a esse hot-spot, que no caso da figura 4-2 é R3 (Ibidem). Figura 4-2 Framework caixa branca (MALDONADO, 2001, p. 23) A figura 4-3 ilustra um framework caixa preta, também com um único hot-spot R. Nesse caso, existem três alternativas (R1, R2 e R3) para implementação da responsabilidade R. O desenvolvedor irá escolher uma delas para obter sua aplicação específica. Note que R1, R2 e R3 fazem parte do framework e são as únicas alternativas possíveis de implementação do hot-spot. Já no caso da figura 4-2 R3 não fazia parte do framework, mas, em compensação, qualquer alternativa de implementação do hot-spot seria possível (Ibidem). Figura 4-3 Framework caixa preta (MALDONADO, 2001, p. 24) Em resumo, um framework caixa branca é mais fácil de projetar, pois não é necessário se prever todas as possíveis alternativas de implementação. Já o framework caixa preta é mais difícil de projetar por haver a necessidade de fazer essa previsão. Por outro lado, 48 o framework caixa preta é mais fácil de usar, pois basta escolher a implementação desejada, enquanto no caixa branca é necessário fazer essas implementações, além de conhecer a estrutura interna do framework (FAYAD, 1997, p. 3; MALDONADO, 2001, p. 24). Frameworks caixa branca podem evoluir para se tornar cada vez mais caixa preta (JOHNSON, 1997, p. 3). Isso pode ser conseguido de forma gradativa, implementando-se várias alternativas que depois podem ser utilizadas na instanciação do framework. Ao mesmo tempo não se fecha totalmente o framework, permitindo ao usuário continuar usando-o como caixa branca e após determinado tempo, que diversas alternativas estejam disponíveis pode-se decidir tornar o framework caixa preta. A medida em que o framework vai se tornando mais caixa preta, diminui o número de objetos criados, embora aumente a complexidade das suas interconexões (MALDONADO, 2001, p. 24). 4.3 Vantagens e Desvantagens Os benefícios primários que pode-se identificar no uso de frameworks, segundo Fayad (1997, p. 1; 1999, p. 8), são: Modularidade: frameworks aumentam a modularidade, pois encapsulam detalhes de implementação sob interfaces bem definidas e estáveis. Esta modularidade auxilia na qualidade do software, localizando os lugares de impactos no projeto e nas mudanças de implementações. Esta localização reduz esforço necessário para entender e manter o software existente. Reutilização: interfaces estáveis presentes nos frameworks aumentam o potencial de reutilização pela definição de componentes abstratos que podem ser redefinidos para criarem novas aplicações. O uso de componentes já definidos e utilizados anteriormente aumentam a produtividade dos desenvolvedores, aumentando, por sua vez, a qualidade, desempenho, confiabilidade e interoperabilidade do software. Extensibilidade: um framework aumenta a extensibilidade na medida em que oferece métodos hook explícitos. Estes permitem que aplicações possam ser estendidas usando-se as interfaces estáveis já presentes. Inversão de controle: A arquitetura de um framework é caracterizada por uma inversão de controle. Esta arquitetura permite a aplicação processar eventos que podem ser personalizados e que são invocados pelo próprio framework. Quando ocorrem eventos, o 49 framework reage, no lugar de cada aplicação, invocando métodos pré definidos que executam processos específicos, em resposta a eventos externos10. Um benefício adicional é obtido quando o framework é documentado com padrões de projeto. Pessoas que conhecem os padrões obtêm rapidamente uma compreensão do framework, pois fazem com que os elementos chaves do framework se tornem mais explícitos (GAMMA, 2000, p. 42). A figura 4-4 ilustra os benefícios obtidos versus os custos de construção de frameworks (TALIGENT, 1993). Figura 4-4 Custo x benefício de framework (TALIGENT, 1993) 4.4 Compreensão e Uso de Frameworks Utilizar um framework consiste em desenvolver aplicações a partir deste framework. A motivação para se utilizar um framework para produzir aplicações é a perspectiva de aumento da produtividade e qualidade do produto final, em função da reutilização promovida. Para produzir uma aplicação a partir de um framework deve se estender sua estrutura, de modo a cumprir os requisitos da aplicação que deve ser desenvolvida (SILVA, 2000, p. 75). Um obstáculo para se desenvolver aplicações a partir de um framework é a dificuldade para aprender como ele funciona internamente. A questão é que se um desenvolvedor de aplicações necessitar empreender um esforço maior para aprender a usar um framework, que para desenvolver uma aplicação do início, a utilidade do framework torna-se questionável (Ibidem). 10 Respostas do usuário a uma solicitação do sistema ou pacotes que chegam em portas de comunicação. 50 Torna-se um imperativo do processo de desenvolvimento de frameworks a produção de subsídios para minimizar o esforço requerido para compreender como usar os frameworks produzidos. Johnson classifica diferentes níveis de compreensão de um framework: saber que tipos de aplicações podem ser desenvolvidas a partir do framework, ser capaz de desenvolver aplicações elementares sob o framework e conhecer em detalhes o projeto do framework. Para capacitar ao desenvolvimento de aplicações elementares recomenda o desenvolvimento de documentação no estilo cookbook11, que não entre em detalhes de projeto (JOHNSON, apud SILVA, 2000, p. 75). A utilização de um framework a partir de instruções passo a passo mostra-se limitada quanto a gama de aplicações que podem ser desenvolvidas: se um requisito de uma aplicação não é tratado no conjunto de instruções, o mecanismo não consegue auxiliar o desenvolvimento. Para suprir essa deficiência, usuários de frameworks, invariavelmente, são forçados a buscar conhecimento acerca do projeto do framework. Assim, é importante que a descrição de um framework fornecida a um usuário o habilite a produzir aplicações com o menor esforço possível, mas que também forneça meios de aprofundar a compreensão do projeto do framework, a fim de a habilitá-lo a produzir aplicações mais complexas, sem que lhe seja exigido um esforço excessivo. O fator de comparação é que o esforço despendido para produzir uma aplicação sob um framework não deve ser superior ao necessário para produzir uma aplicação equivalente, sem o framework (Ibidem). 4.5 Personagens Envolvidos com o Desenvolvimento e Uso de Frameworks O desenvolvimento tradicional de aplicações envolve dois tipos de personagens: 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). Os 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 do usuário) e entregá-la aos usuários. Os usuários interagem com uma aplicação apenas através de sua interface. A figura 4-5 apresenta os indivíduos envolvidos neste caso (Ibidem). 11 Documentação onde mostra exemplos passo a passo de como utilizar o framework. 51 Figura 4-5 Elementos do desenvolvimento tradicional de aplicações O desenvolvimento de frameworks introduz outro personagem, além de desenvolvedor e usuário de aplicação: o desenvolvedor de framework. No contexto dos frameworks, o papel do usuário de aplicação não muda. 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 é um usuário de um framework, que deve estender e adaptar a estrutura deste framework 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 o desenvolvedor de aplicações a necessidade de produzir código) e entregá-la ao usuário. O novo personagem 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, de forma mais produtiva do que sem a utilização do framework. A figura 4-6 apresenta os indivíduos envolvidos neste último caso (Ibidem, p. 76). Figura 4-6 Elementos do desenvolvimento de aplicações baseadas em frameworks 52 4.6 Etapas da Construção de Frameworks Para a construção de um framework diversas atividades não seqüenciais se repetem, até se obter uma estrutura de classes que satisfaça os requisitos de generalidade, flexibilidade e extensibilidade. Para melhor entendimento, pode-se organizar estas atividades que constituem o processo de desenvolvimento da estrutura de classes de um framework nas seguintes etapas: etapa de generalização; etapa de flexibilização; etapa de aplicação de metapadrões; etapa de aplicação de padrões de projeto; etapa de aplicação de princípios práticos de orientação a objetos (Ibidem, p. 58). A etapa de generalização consiste no processo de identificar estruturas idênticas nas aplicações analisadas, e na fatoração de estruturas em que se identificam semelhanças, de modo a obter uma estrutura de classes que generalize o domínio tratado. O primeiro aspecto na busca de generalidade da estrutura do framework, é a identificação das classes que representam elementos e conceitos do domínio tratado. Isto é obtido a partir da confrontação de estruturas de classe de diferentes aplicações. Nesta etapa também são buscados elementos prontos que podem ser reutilizados, como outros frameworks e componentes (Ibidem, p. 59). Na etapa de flexibilização o objetivo é identificar o que deve ser mantido flexível na estrutura de classes que generaliza o domínio, de modo que a estrutura possa ser especializada posteriormente, gerando diferentes aplicações. É um processo de localização de hot-spots na estrutura de classes e de escolha de soluções de projetos para modelá-los. A identificação de hot-spots ocorre quando se terminam situações de processamento comuns às aplicações do domínio (frozen-spots), porém, com variações de uma aplicação específica para outra (Ibidem). Uma vez identificado um hot-spot, deve-se comparar o requisito de flexibilização por ele imposto com os casos tratados por padrões existentes. Se um padrão é julgado adequado para a solução do problema, ele pode ser incorporado a estrutura de classes do framework. No caso específico dos metapadrões, o seu uso consiste em transformar um procedimento geral e em um método template, cujo comportamento é flexibilizado através da dependência de métodos hook, que podem ter diferentes implementações (Ibidem). A incorporação de padrões de projeto consiste em incluir as classes de um padrão selecionado na estrutura de classes do framework (ou fazer com que classes já existentes assumam as responsabilidades correspondentes às classes do padrão de projeto) (Ibidem). 53 Segundo Johnson (apud SILVA, 2000, p. 63) para se obter um framework com uma estrutura de classes flexível é necessário seguir princípios de projeto orientado a objetos, como o uso de herança para a reutilização de interfaces, ao invés do uso de herança para a reutilização código (a delegação é mais adequada que o uso indevido de herança); reutilização de código através de composição de objetos; preocupação em promover polimorfismo na definição de classes e métodos, de modo a possibilitar acoplamento dinâmico, etc. 4.7 Aprendendo como usar Frameworks Aprender a utilizar um framework vai além de adquirir a capacidade de produzir aplicações. Também implica em conhecer os recursos que são disponibilizados, para evitar esforços desnecessários de desenvolvimento. Um usuário que utiliza um framework sem conhecê-lo razoavelmente, pode despender esforço desenvolvendo o que poderia ser reutilizado, o que reduz sua produtividade e pode estar sujeito a erros. Assim, aprender a usar um framework corresponde a buscar informações na documentação e/ou código fonte (SILVA, 2000, p. 77). Uma das formas de aprender a usar frameworks é a partir da sua documentação. A documentação direcionada a ensinar como usar um framework normalmente descreve os passos a serem seguidos por um usuário para gerar aplicações. Este tipo de documentação da pouca ênfase a aspectos de projeto, seu principal objetivo é descrever de forma mais breve possível, como produzir aplicações. Em geral, apresentam formato textual e incluem alguma outra forma de descrição, como exemplos utilizando código fonte (Ibidem, p. 79). Outra forma, é a partir da disponibilização de código fonte, que é a forma mais elementar de auxílio ao desenvolvimento de aplicações baseadas em frameworks. Isto pode incluir o código do framework tratado (de todo o framework ou parte dele) e o código de aplicações desenvolvidas sob o framework. Entender o projeto de um framework dispondo apenas de código é o único modo possível quando não existe documentação disponível. É uma atividade de baixo nível, e de um modo geral, é a maneira mais árdua de aprender a utilizar um framework (Ibidem, p. 80). 5 ANÁLISE E MODELAGEM DO FRAMEWORK Este capítulo falará sobre as funções desempenhadas pelo sistema para os usuários que utilizarão o framework. Apresentará também a modelagem realizada para a construção e documentação do framework, que é composta por: cenários, diagrama de casos de uso, diagrama de classes, diagrama de seqüências e diagrama de estados. 5.1 Requisitos do Sistema O framework visa atender requisitos de dois usuários diferentes: o desenvolvedor de aplicações, que utilizará o framework como arquitetura para o desenvolvimento de suas aplicações e o usuário final, que utilizará a aplicação desenvolvida sobre a arquitetura do framework. Os requisitos que devem ser atendidos ao desenvolvedor de aplicações, que utilizará o framework como arquitetura para o desenvolvimento de suas aplicações, são os seguintes: • Liberar o desenvolvimento da tarefa de criar consultas específicas em cada tabela do sistema, para atender as necessidades individuais de cada usuário; • Ter um evento para validar os valores informados pelo usuário, onde o desenvolvedor possa implementar as regras de negócio da aplicação que está sendo desenvolvida. Esta validação deverá ser realizada no momento da digitação, se for pressionada a tecla enter, e quando o usuário terminar a inclusão do registro deverá validar os valores novamente, para garantir a integridade das informações que estão sendo salvas. Isto irá determinar um padrão para o desenvolvimento implementar as regras de negócio da aplicação que está sendo desenvolvida; 55 • Validar automaticamente valores informados em um campo que possua uma chave estrangeira; • Possibilitar ao desenvolvedor informar uma cláusula restritiva adicional, para validar um registro que seja chave estrangeira; • A consulta de registros em tabelas referenciadas seja padrão para todas as tabelas, sem ter que codificar cada consulta; • Que a implementação das funcionalidades acima seja realizada de forma visual (sem ter que escrever código fonte). Outro usuário que será beneficiado com a adoção do framework, será o usuário que utilizará a aplicação desenvolvida sobre a arquitetura deste framework. Para isto, alguns requisitos devem ser atendidos, visando facilitar a interação do usuário com a aplicação. Dentre os requisitos, pode-se citar os seguintes: • Possibilitar ao usuário realizar a cópia de um registro que exista no sistema, alterando a chave primária e, se desejar, outros valores do registro; • Possibilitar ao usuário realizar uma consulta, restringindo o resultado por qualquer campo da tabela que está sendo consultada; • Possibilitar ao usuário realizar a manutenção das informações, no resultado da consulta realizada; • Validar, no momento da digitação, o valor informado em um campo que possua uma chave estrangeira; • Consultar os valores disponíveis para os campos que fazem referência a chaves estrangeiras, sem a necessidade de sair do formulário atual; • Possibilitar ao usuário incluir um registro em uma tabela referenciada, sem perder as informações do registro atual que está sendo incluído/alterado; • Ter um formulário padrão para a manutenção das informações, facilitando o entendimento das funcionalidades do sistema; 56 5.2 Cenários Um cenário é uma pequena história que descreve uma seqüência esperada de ações e respostas entre um usuário e o sistema. Ele é utilizado para apresentar como um usuário emprega o sistema para atingir seu objetivo (LEE, 2001, p. 44). Nos cenários abaixo, os passos serão descritos sempre através de uma opção. Cada opção terá um botão e um item de menu correspondente no formulário, que poderá ser acessado através do mouse ou pelo teclado através de uma tecla de atalho, que poderá ser vista, posicionando-se o mouse sobre o botão. 5.2.1 Acessar Formulário Para acessar um formulário, a aplicação que for desenvolvida utilizando a arquitetura do framework deverá possuir um menu para disponibilizar acesso as tabelas que formam o sistema. A partir da opção de menu selecionada pelo usuário, a aplicação irá instanciar o formulário correspondente a opção selecionada, através do método ChamaForm. O formulário será exibido ao usuário, em modo normal, com as opções de incluir, consultar, browse e sair, disponíveis para seleção. As opções de copiar, excluir, salvar, cancelar, executar e navegar, neste momento estarão desabilitadas. O sistema irá controlar as opções que ficarão disponíveis ao usuário, dependendo do cenário que ele estiver no momento. A partir deste cenário, serão chamados os outros cenários. Objetivo: Acessar um formulário do sistema. Atores: usuário, método ChamaForm. 5.2.2 Realizar Consulta Para realizar uma consulta, o usuário deverá acessar a opção de menu que disponibiliza o acesso a tabela que ele deseja consultar. O método ChamaForm irá instanciar um formulário que apresentará todos os campos disponíveis na tabela, para serem preenchidos. O usuário irá entrar em modo de consulta, através da opção consultar. A partir deste momento o usuário estará em modo de consulta (somente as opções cancelar, executar e sair ficarão habilitados) e irá especificar as características do(s) registro(s) que procura, através do preenchimento dos campos. Todos os campos utilizados para a inclusão do(s) registro(s) estarão disponíveis para realizar a consulta, porém somente os campos que forem preenchidos farão parte da restrição que será enviada ao banco de dados 57 para encontrar o(s) registro(s). Nesta operação não haverá validação dos valores informados como características. Quando o usuário informar a(s) característica(s) do(s) registro(s) que procura, irá executar a consulta através da opção executar. A última consulta executada é mantida em memória e pode ser executada novamente através do menu Opções / Última Consulta ou da tecla de atalho F12. O sistema irá então montar a consulta através do método ExecutarConsulta da classe Area, que enviará para o banco de dados e retornará para o usuário o primeiro registro encontrado e o formulário voltará ao modo normal. O usuário poderá navegar no resultado da consulta até o último registro encontrado, através dos botões de navegação, ou visualizar todo o resultado da consulta em um DbGrid através da opção browse. Caso o usuário queira cancelar a consulta e voltar ao modo de edição, fará através da opção cancelar. Objetivo: buscar informações sobre os registros de uma tabela Atores: usuário, método ChamaForm, SetModoConsulta, ExecutarConsulta, SetModoNormal 5.2.3 Incluir Registros Para incluir registros, o usuário deverá acessar a opção de menu que disponibiliza o acesso a tabela que ele deseja incluir novos registros. O método ChamaForm irá instanciar um formulário, em modo normal, que apresentará todos os campos disponíveis na tabela, para serem preenchidos. O usuário irá incluir um registro através da opção incluir. O registro virá preenchido com os valores default de cada campo, que foram definidos no banco de dados. A medida em que os campos forem preenchidos e o usuário teclar enter, será disparado o evento onValida que irá validar se o valor informado satisfaz as regras de negócio que foram implementadas, se atende a integridade referencial do banco de dados e se o campo é de preenchimento obrigatório. Se alguma inconsistência for encontrada, ela será apresentada ao usuário e o cursor permanecerá no campo. Para sair do campo sem executar as validações deve ser utilizado a tecla tab. Caso o usuário não conheça o valor a ser informado em um campo, que possua uma chave estrangeira, poderá realizar uma consulta aos valores existentes na tabela referenciada, através do botão BuscaFk. O botão BuscaFk está posicionado ao lado do campo, ou da tecla 58 de atalho F9. Uma vez encontrado o registro o usuário pode selecioná-lo e retornar para o formulário de inclusão, concluindo a inclusão do registro. Após ter sido informado os valores para o registro, o usuário poderá incluir novos registros através da opção incluir, que chamará o método Append da classe TArea, que é responsável por criar um novo registro e atribuir os valores default de cada campo. Quando o usuário informar todos os valores, irá salvar o(s) registro(s) através da opção salvar, que irá executar o método ApplyUpdates da classe ClDataSet. O método ApplyUpdates é o responsável por inserir os registros no banco de dados. Caso ocorra algum problema na inclusão do registro, as mensagens de erro serão apresentadas ao usuário e nenhuma inclusão será realizada. Através da opção cancelar o usuário pode cancelar a inclusão do(s) registro(s). Objetivo: adicionar novos registro ao sistema Atores: usuário, método ChamaForm, onValida, Append, AtribuirDefault, ApplyUpdates 5.2.4 Copiar Registros Para copiar um registro, o usuário irá efetuar os passos descritos no cenário 5.2.2 Realizar consulta. Após ter selecionado o registro que deseja copiar, irá realizar a cópia do registro através da opção copiar. Nesta operação os valores de todos os campos serão copiados, exceto a chave primária do registro, que deverá ser informada pelo usuário. O usuário poderá alterar o valor de qualquer campo antes de salvar o registro. A medida em que os campos forem preenchidos e o usuário teclar enter, será disparado o evento onValida que irá validar se o valor informado satisfaz as regras de negócio que foram implementadas, se atende a integridade referencial do banco de dados e se o campo é de preenchimento obrigatório. Se alguma inconsistência for encontrada, ela será apresentada ao usuário e o cursor permanecerá no campo. Para sair do campo sem executar as validações deve ser utilizado a tecla tab. Caso o usuário não conheça o valor a ser informado em um campo, que possua uma chave estrangeira, poderá realizar uma consulta aos valores existentes na tabela referenciada, através do botão BuscaFk. O botão BuscaFk está posicionado ao lado do campo, ou da tecla 59 de atalho F9. Uma vez encontrado o registro o usuário pode selecioná-lo e retornar para o formulário de inclusão, concluindo a inclusão do registro. Quando o usuário informar todos os valores, irá salvar o(s) registro(s) através da opção salvar, que irá executar o método ApplyUpdates da classe ClDataSet. O método ApplyUpdates é o responsável por inserir os registros no banco de dados. Caso ocorra algum problema na inclusão do registro, as mensagens de erro serão apresentadas ao usuário e nenhuma inclusão será realizada. Através da opção cancelar o usuário pode cancelar a inclusão ou cópia do(s) registro(s). Objetivo: inserir novos registros no sistema através de outros registros existentes Atores: usuário, método ChamaForm, SetModoConsulta, ExecutarConsulta, SetModoNormal, Copy, onValida, ApplyUpdates 5.2.5 Modificar Registros Para modificar um registro, o usuário irá efetuar os passos descritos no cenário 5.2.2 Realizar consulta. Após ter selecionado o registro que deseja alterar, entrará com os novos valores. Não é permitido alterar a chave primária do registro. A medida em que os campos forem preenchidos e o usuário teclar enter, será disparado o evento onValida que irá validar se o valor informado satisfaz as regras de negócio que foram implementadas, se atende a integridade referencial do banco de dados e se o campo é de preenchimento obrigatório. Se alguma inconsistência for encontrada, ela será apresentada ao usuário e o cursor permanecerá no campo. Para sair do campo sem executar as validações deve ser utilizado a tecla tab. Caso o usuário não conheça o valor a ser informado em um campo, que possua uma chave estrangeira, poderá realizar uma consulta aos valores existentes na tabela referenciada, através do botão BuscaFk. O botão BuscaFk está posicionado ao lado do campo, ou da tecla de atalho F9. Uma vez encontrado o registro o usuário pode selecioná-lo e retornar para o formulário de inclusão, concluindo a inclusão do registro. Quando o usuário informar todos os valores, irá salvar o(s) registro(s) através da opção salvar, que irá executar o método ApplyUpdates da classe ClDataSet. O método ApplyUpdates é o responsável por alterar os registros no banco de dados. Caso ocorra algum 60 problema na alteração do registro, as mensagens de erro serão apresentadas ao usuário e nenhuma alteração será realizada. O usuário deve acessar a opção cancelar, caso queira descartar as alterações realizadas. Objetivo: efetuar a manutenção dos registros inseridos no sistema Atores: usuário, método ChamaForm, SetModoConsulta, ExecutarConsulta, SetModoNormal, onValida, ApplyUpdates 5.2.6 Excluir Registros Para excluir um registro, o usuário irá efetuar os passos descritos no cenário 5.2.2 Realizar consulta. Após ter selecionado o registro que deseja excluir, irá realizar a exclusão do registro através da opção excluir. Nesta operação será executado o método ExecutaExcluir que irá definir se é permitido excluir o registro, com base nas regras de negócio implementadas pelo desenvolvedor da aplicação. Se for permitido excluir o registro, este será marcado para exclusão e não ficará disponível para visualização do usuário. Caso não seja permitido a exclusão, será apresentado uma mensagem ao usuário informando o motivo. Quando o usuário marcar todos os registros que deseja excluir, irá efetivar a exclusão no banco de dados através da opção salvar, que irá executar o método ApplyUpdates da classe ClDataSet. O método ApplyUpdates é o responsável por excluir os registros no banco de dados. Caso ocorra algum problema na exclusão do registro, as mensagens de erro serão apresentadas ao usuário e nenhuma exclusão será realizada. Através da opção cancelar o usuário pode cancelar a exclusão. Objetivo: efetuar a exclusão de registros inseridos no sistema Atores: usuário, método ChamaForm, SetModoConsulta, ExecutarConsulta, SetModoNormal, Delete, ApplyUpdates 5.2.7 Consultar Chave Estrangeira A inclusão de novos registros, a modificação ou a cópia de registros que possuam chaves estrangeiras possibilitam ao usuário instanciar a classe TFrmConsulta através da classe TBuscaFk ou da tecla de atalho F9. Esta instância apresenta ao usuário todos os campos da 61 tabela que está sendo consultada, porém só é permitido restringir a consulta por um dos campos. Após o usuário realizar a consulta é possível aplicar mais um filtro no resultado da consulta para torná-la mais seletiva e/ou ainda classificar o resultado em ordem ascendente ou descendente por qualquer campo da tabela que esteja sendo visualizado pelo usuário. Para classificar basta clicar sobre o título de uma das colunas do browse. Caso o registro procurado não exista no banco de dados é possível acessar o formulário responsável pela entrada de dados nesta tabela e efetuar a inclusão deste registro. Quando o formulário de inclusão for fechado, o usuário voltará para o formulário de consulta, onde poderá realizar novamente a consulta. Quando o registro for encontrado, o usuário irá clicar em OK e o código do registro selecionado retornará para o formulário principal onde o usuário estava realizando a manutenção das informações. Objetivo: realizar consultas em tabelas referenciadas por chave estrangeira. Atores: usuário, BuscaFk, ChamaForm 5.3 Casos de Uso Os casos de uso geralmente são o ponto de partida da análise orientada a objetos utilizando a UML. Os atores representam usuários e outros sistemas que interagem com sistema modelado. Eles são representados graficamente pela figura de um boneco. Os casos de uso mostram o comportamento do sistema, cenários que o sistema percorre em resposta ao estímulo de um ator (LEE, 2001, p. 51). Esta seção apresentará os casos de uso que descrevem as interações do usuário com sistema, que busca através dos diagramas facilitar o entendimento de como funcionará o framework. 62 5.3.1 Acessar Formulário Figura 5-1 Caso de uso acessar formulário Caso de uso : Atores: Acessar Formulário Usuário (iniciador), Sistema Finalidade: Acessar um formulário de cadastro do sistema. Visão geral: O usuário acessa uma opção de cadastro do sistema. O sistema exibe um formulário em modo de inclusão com todos os campos para serem preenchidos. Cenários: Acessar Formulário. Seqüência típica de eventos Ação do ator Resposta do sistema 1. Este caso de uso começa quando o usuário acessa um formulário de cadastro do sistema para realizar manutenção nas informações ou realizar uma consulta. 2. Exibe o formulário em modo normal, 63 com opção para incluir, consultar, browse e sair. 3. Usuário define opção que deseja realizar a. Se consultar, iniciar Realizar Consulta b. Se incluir, iniciar Incluir Registros c. Se copiar, iniciar Copiar Registros d. Se excluir, iniciar Excluir Registros e. Se modificar, iniciar Modificar Registros 4. Executa a opção selecionada pelo usuário. 5. Sair do formulário. 6. Fecha o formulário atual. Seqüência alternativa Linha 3: Cancelar a criação do registro e executar linha 5. Casos de uso relacionados Realizar Consulta Incluir Registros Copiar Registros Excluir Registros Modificar Registros 64 5.3.2 Realizar Consulta Figura 5-2 Caso de uso realizar uma consulta Caso de uso: Atores: Realizar Consulta Usuário (iniciador), Sistema Finalidade: Executar uma consulta ao banco de dados Visão geral: O usuário acessa uma opção de cadastro do sistema, que deseja localizar um registro, entra em modo consulta, informa as caraterísticas do registro que procura e executa a consulta. O sistema retorna os registros que satisfazem as condições especificadas pelo usuário. Cenários: Realizar Consulta. Seqüência típica de eventos Ação do ator 1. Este caso de uso começa quando o usuário deseja localizar um registro em uma determinada tabela do sistema. O usuário acessa o formulário responsável pela manutenção das informações desta tabela. Resposta do sistema 65 2. Exibe o formulário em modo normal, com opção para incluir, consultar, browse e sair. 3. Entra em modo de consulta. 4. Muda o status do formulário para consulta e libera os campos para digitação, sem validar os valores informados. 5. Informa as características do(s) registro(s) que procura. 6. Armazena em memória as características informadas. 7. Executa a consulta. 8. Executa a consulta e armazena em memória os registros que satisfazem as condições definidas pelo usuário. Exibe as informações do primeiro registro selecionado. 9. Navega nos registros selecionados pela consulta. 10. Exibe as informações do registro selecionado. Seqüência alternativa Linha 5: Seleciona a última consulta realizada. Linha 7: Cancela a consulta e volta para o status de normal. Linha 8: Nenhum registro satisfaz as restrições do usuário, executar linha 5. Linha 9: Visualiza todos os registros selecionados, em um browse. 66 5.3.3 Incluir Registros Figura 5-3 Caso de uso incluir registros Caso de uso: Atores: Incluir Registros Usuário (iniciador), Sistema Finalidade: Incluir novos registros no banco de dados. Visão geral: O usuário acessa uma opção de cadastro do sistema, que deseja incluir novos registros. Preenche os campos disponíveis no formulário e salva as informações. O sistema armazena as informações no banco de dados. Cenários: Incluir Registros Seqüência típica de eventos Resposta do sistema Ação do ator 1. Este caso de uso começa quando o usuário deseja incluir um novo registro no sistema. O usuário acessa o formulário responsável pela manutenção das informações desta tabela. 2. Exibe o formulário em modo normal, com opção para incluir, consultar, browse e sair. 67 3. Selecionar incluir. 4. Cria um novo registro com os valores default informados no banco de dados. 5. Preenche os campos disponíveis na tela. 6. Valida as informações digitadas e armazena em memória. 7. Salva as informações. 8. Iniciar “Salvar”. Seqüência alternativa Linha 5: Iniciar “Consultar Chave Estrangeira”. Linha 6: Informações inválidas. Executar linha 5. Linha 7: Cancela a inclusão do registro e volta ao status de normal. Casos de uso relacionados Consultar Chave Estrangeira Salvar 5.3.4 Copiar Registros Figura 5-4 Caso de uso copiar registros 68 Caso de uso: Atores: Finalidade: Copiar Registros Usuário (iniciador), Sistema Incluir novos registros no banco de dados a partir de registros existentes. Visão geral: O usuário acessa uma opção de cadastro do sistema, que deseja incluir novos registros. Ele realiza uma consulta e localiza o registro que deseja copiar, seleciona a opção copiar, informa um código para o novo registro e salva as informações. O sistema valida e armazena as informações no banco de dados. Cenários: Copiar Registros Seqüência típica de eventos Ação do ator Resposta do sistema 1. Este caso de uso começa quando o usuário deseja incluir um novo registro no sistema e sabe que já existe um registro com muitas características iguais ao que deve ser incluído. O usuário acessa o formulário responsável pela manutenção das informações desta tabela. 2. Iniciar “Realizar Consulta” 3. Copiar registro. 4. Cria um novo registro em memória e copia as informações do registro anterior para o atual, exceto a chave primária. 5. Informa a chave primária para o novo registro e, se necessário, altera outras informações. 6. Valida as informações digitadas e armazena em memória. 7. Salva as informações. 8. Iniciar “Salvar”. 69 Seqüência alternativa Linha 5: Iniciar “Consultar Chave Estrangeira” Linha 6: Informações inválidas. Executar linha 5. Linha 7: Cancela a inclusão do registro e volta ao status de normal. Casos de uso relacionados Realizar Consulta Consultar Chave Estrangeira Salvar 5.3.5 Modificar Registros Figura 5-5 Caso de uso modificar registros Caso de uso : Atores: Modificar Registros Usuário (iniciador), Sistema Finalidade: Alterar informações existentes no sistema. Visão geral: O usuário acessa uma opção de cadastro do sistema, que deseja modificar registros. Ele efetua uma consulta e localiza o registro que deseja modificar, altera os valores e salva as informações. O sistema valida e armazena as informações no banco de dados. Cenários: Modificar Registros 70 Seqüência típica de eventos Resposta do sistema Ação do ator 1. Este caso de uso começa quando o usuário deseja modificar um registro no sistema. O usuário acessa o formulário responsável pela manutenção das informações desta tabela. 2. Iniciar “Realizar Consulta” 3. Informa os novos valores para o registro, exceto a chave primária. 4. Valida as informações digitadas e armazena em memória. 5. Salva as informações. 6. Iniciar “Salvar”. Seqüência alternativa Linha 3: Iniciar “Consultar Chave Estrangeira” Linha 4: Informações inválidas. Executar linha 3. Linha 5: Cancela as alterações do registro e volta ao status de normal. Casos de uso relacionados Realizar Consulta Consultar Chave Estrangeira Salvar 71 5.3.6 Excluir Registros Figura 5-6 Caso de uso excluir registros Caso de uso: Atores: Excluir Registros Usuário (iniciador), Sistema Finalidade: Excluir informações existentes no sistema. Visão geral: O usuário acessa uma opção de cadastro do sistema, que deseja excluir registros. Ele efetua uma consulta e localiza o registro que deseja excluir, marca o registro para exclusão e salva as informações. O sistema valida a exclusão e exclui fisicamente as informações do banco de dados. Cenários: Excluir Registros Seqüência típica de eventos Ação do ator Resposta do sistema 1. Este caso de uso começa quando o usuário deseja excluir um registro do sistema. O usuário acessa o formulário responsável pela manutenção das informações desta tabela. 2. Iniciar “Realizar Consulta” 72 3. Marca o registro para exclusão. 4. Valida permissão para excluir o registro, oculta o registro do usuário e marca o registro como excluído. 5. Salva as exclusões. 6. Iniciar “Salvar”. Seqüência alternativa Linha 4: Pelas regras de negócio, não é permitido excluir o registro e o registro não é excluído. Linha 5: Cancela as exclusões (os registros permanecem no banco de dados) e volta ao modo normal. Casos de uso relacionados Realizar Consulta Salvar 5.3.7 Consultar Chave Estrangeira Figura 5-7 Caso de uso consultar chave estrangeira 73 Caso de uso: Atores: Finalidade: Consultar Chave Estrangeira Usuário (iniciador), Sistema Realizar consultas em tabelas que são referenciadas por chaves estrangeiras. Visão geral: O usuário tem que informar o valor para um campo, que possui uma chave estrangeira, e não sabe quais valores são válidos. Através da tecla F9 ou do botão BuscaFk é exibido uma consulta com todos os registros existentes no sistema que atendem a restrição da chave estrangeira. O usuário pode selecionar o valor e concluir seu trabalho sem sair do formulário que estava efetuando manutenção. Cenários: Consultar Chave Estrangeira Seqüência típica de eventos Resposta do sistema Ação do ator 1. Este caso de uso começa quando o usuário está incluindo, copiando ou modificando um registro e o campo que está sendo preenchido possui uma chave estrangeira, mas o usuário não sabe os valores que atendem a chave estrangeira. Através do botão BuscaFk ou da tecla de atalho F9, o usuário acessa a consulta de chaves estrangeiras. 2. Exibe um formulário para realizar uma consulta na tabela referenciada pela chave estrangeira. 3. Seleciona um campo da tabela para realizar a consulta, informa qual operador relacional será utilizado (>=, <=, =, <>, LIKE) e o valor para consulta. Realiza a consulta. 4. Exibe, em um browse, todos os registros que satisfazem a restrição imposta pelo usuário. 74 5. Classifica o resultado da consulta por um dos campos apresentados no browse. 6. Ordena o resultado da consulta, em ordem ascendente, pelo campo definido pelo usuário. 7. Aplica um filtro sobre o resultado da consulta para torná-la mais seletiva. 8. Restringe o resultado da consulta, exibindo somente os registros que satisfazem o filtro definido pelo usuário. 9. Seleciona o registro desejado 10. Fecha o formulário de consulta e atribui o código do registro selecionado ao formulário que estava fazendo manutenção. Seqüência alternativa Linha 3: Fecha o formulário de consulta e volta ao formulário que estava fazendo manutenção. Linha 5: Passa diretamente para linha 7 ou 9. Linha 6: Ordena em ordem descendente, se o usuário clicar duas vezes sobre o título da coluna no browse. Linha 7: Passa diretamente para a linha 9. Linha 9: a. O registro procurado não foi encontrado, Iniciar “Incluir registros”. b. Fecha o formulário de consulta e volta ao formulário que estava fazendo manutenção. 75 5.3.8 Salvar Figura 5-8 Caso de uso salvar Caso de uso: Atores: Finalidade: Salvar Usuário (iniciador), Sistema Efetivar no banco de dados as alterações realizadas em memória, pelo usuário. Visão geral: O usuário está efetuando alterações em uma tabela do sistema e solicita que sejam salvas no banco de dados suas alterações. O sistema valida as alterações e efetiva fisicamente no banco de dados as alterações. Seqüência típica de eventos Ação do ator Resposta do sistema 1. Este caso de uso começa quando o usuário solicita ao sistema que efetive fisicamente no banco de dados, as alterações realizadas em uma tabela do sistema. 76 2. Valida as informações, segundo as regras de negócio implementas no formulário. Inicia uma transação no banco de dados e envia os comandos SQL para o banco. Finaliza a transação com um Commit, se nenhuma mensagem de erro retornar do banco, ou com Rollback se ocorrer algum erro. Libera o formulário para o usuário. Seqüência alternativa Linha 2: Se finalizar a transação com Rollback, exibe ao usuário, um formulário com a mensagem de erro para que o usuário corrija e salve novamente. 5.4 Diagramas de Classes Segundo Johnson, um framework pode ser definido como “um projeto reutilizável de uma parte ou de todo um sistema, que é representado por um conjunto de classes abstratas e pelo modo que elas interagem” (JOHNSON, 1997, p. 39). Então nesta seção, serão apresentadas as principais classes que compõem o framework. Para uma melhor apresentação, elas foram dividas em duas categorias, segundo suas funcionalidades dentro do framework. A primeira categoria representa os formulários que serão exibidos ao usuário durante sua interação com o sistema, e a segunda são as classes responsáveis pela edição e manipulação dos dados. Será descrito brevemente a função das classes dentro framework, uma documentação mais detalhada é apresentada na documentação eletrônica12. 5.4.1 Formulários Para a construção do protótipo do framework foram implementadas várias classes, e algumas delas são apresentadas pela figura 5-10. Estas classes representam os formulários que serão herdados para a composição de um sistema que venha a ser desenvolvido utilizando a arquitetura deste framework. Todas as classes herdam de TForm que é uma classe que acompanha o Delphi© e que implementa um formulário. 12 Documentação eletrônica disponibilizada em CD, composta por: documentação das classes, script de criação do banco de dados, executável e arquivos necessários para rodar a aplicação teste. 77 A classe TFrmBase, apresentada pela figura 5-11, é a classe mais genérica que foi implementada, ou seja, é que está mais acima na hierarquia de classes e ela implementa um método chamado Validar, que percorre o formulário procurando por objetos de edição de dados, que são apresentados na figura 5-16, e executa o método onValida de cada objeto, retornando se existe alguma inconsistência ou não nos objetos do formulário. Está é uma das principais classes do framework porque todos os formulários deverão herdar dela, sendo assim, se for necessário implementar novas funcionalidades no framework e que precisem ser disponibilizadas em todos os formulários, esta será a classe que sofrerá as alterações. Outra classe também muito importante é a TFrmCadastro, que é apresentada pela figura 5-15 e herda de TFrmBase. As funções de inclusão, alteração, consulta e exclusão de registros foram implementadas nesta classe, portanto os formulários de cadastro deverão herdar desta classe. A figura 5-12 apresenta a classe TFrmBrowse, que é instanciada pela classe TFrmCadastro para visualizar o resultado de uma consulta ao banco de dados através de um browse, onde todos os registros podem ser vistos ao mesmo tempo. Esta classe herda de TFrmBase apenas para manter as mesmas propriedades visuais. Quando o usuário estiver realizando uma inclusão, cópia ou alterando um registro, poderá acessar a consulta de chaves estrangeiras através da tecla F9, então será exibido um formulário semelhante ao apresentado pela figura 5-13, onde ele poderá realizar uma consulta ao banco de dados para descobrir os valores válidos para o campo que estiver preenchendo. Esta consulta só estará disponível se o campo possuir uma chave estrangeira no banco de dados. Após realizar as alterações o usuário irá salvar no banco de dados estas informações, neste momento se algum valor não satisfazer as regras de negócio implementadas, será apresentado um formulário com as mensagens de inconsistências encontradas, como pode ser visto na figura 5-14. Enquanto ocorrerem inconsistências as informações não serão salvas no banco de dados. A classe TFrmSobre exibe um formulário com o nome do formulário que o usuário está no momento, conforme apresenta a figura 5-15. Este formulário pode ser utilizado para apresentar a versão do produto e o nome da empresa responsável pelo sistema. 78 Figura 5-9 Diagrama de classes dos formulários 79 Figura 5-10 Objeto do tipo TFrmBase Figura 5-11 Objeto do tipo TFrmCadastro Figura 5-12 Objeto do tipo TFrmBrowse 80 Figura 5-13 Objeto do tipo TFrmConsulta Figura 5-14 Objeto do tipo TFrmErros Figura 5-15 Objeto do tipo TFrmSobre 5.4.2 Componentes de Edição O componentes de edição são as classes responsáveis por capturar do teclado os valores informados pelo usuário para os campos das tabelas que estiver realizando a manutenção das informações. Estas classes também herdam métodos e atributos de uma classe existente do Delphi©, chamada TCustomMaskEdit. A figura 5-16 apresenta as principais classes que foram implementadas para a construção do framework. A classe principal é a TCl, que é uma classe abstrata onde foi implementado todos os métodos e 81 atributos necessários para satisfazer os requisitos do framework. As demais classes todas herdam estes métodos e atributos através do mecanismo de herança da orientação a objetos. As três principais classes são TClDbData, TClDbValor e TClDbEdit, todas classes que armazenam em memória, através da classe TClDataSet, os valores informados pelo usuário para depois serem salvos no banco de dados. A classe TClEdit possui as mesmas funcionalidades da classe TClDbEdit, porém não tem a capacidade de manter seus valores em um TClDataSet. A classe TClDbData, apresentada pela figura 5-17, é utilizada para receber valores do tipo data e possui um botão de auxílio que pode ser acessado através do mouse, onde é apresentado um calendário ao usuário para facilitar a sua digitação. Da mesma forma, a classe TClDbValor apresenta um botão de auxílio, porém esta exibe uma calculadora, pois esta classe é utilizada para receber valores do tipo numérico (com ou sem decimais). Uma instância desta classe é apresentada pela figura 5-18. A outra classe é a TClDbEdit, que é mais genérica e aceita todos os tipos de valores, porém não possui tratamento de erros para valores do tipo data e número. Esta classe deve ser utilizada para receber valores do tipo caracter. Esta classe possui uma propriedade onde pode ser informado uma máscara para o valor que será exibido, facilitando assim a visualização. As máscaras disponíveis são para formatar: CNPJ, CPF, CEP, CFOP e telefone, porém outras máscaras podem ser adicionadas. A figura 5-19 é um exemplo desta classe com uma máscara para CNPJ. Outras classes para edição dos dados foram implementadas, como a TClDbMemo, TclDbCheck e a TClDbComboBox, e ainda outras classes auxiliares que podem ser vistas na documentação eletrônica deste trabalho13. 13 Documentação eletrônica disponibilizada em CD, composta por: documentação das classes, script de criação do banco de dados, executável e arquivos necessários para rodar a aplicação teste. 82 Figura 5-16 Diagrama de classe dos componentes de edição Figura 5-17 Objeto do tipo TClDbData Figura 5-18 Objeto do tipo TClDbValor Figura 5-19 Objeto do tipo TClDbEdit 83 5.5 Diagramas de Seqüência Um diagrama de seqüência dá ênfase a ordenação temporal de mensagens. Um diagrama de seqüência mostra um conjunto de objetos e as mensagens enviadas e recebidas por esses objetos. Tipicamente os objetos são instâncias nomeadas ou anônimas de classes, mas também podem representar instâncias de outros itens, como colaborações, componentes e nós (BOOCH, 2000, p. 241). Os objetos são representados por linhas tracejadas verticais, e a passagem de mensagens entre dois objetos é representada por vetores horizontais. As mensagens são desenhadas em ordem cronológica do topo à base do diagrama. A seguir será apresentado os diagramas modelados para a implementação do protótipo do framework. 5.5.1 Realizar Consulta Este diagrama descreve a seqüência de eventos que ocorrerá para realizar uma consulta ao banco de dados, através de um formulário de cadastro. Figura 5-20 Seqüência de realizar consulta 84 5.5.2 Incluir Registros Este diagrama descreve a seqüência de eventos que ocorrerá ao ser incluído novos registros no banco de dados, através de um formulário de cadastro. Figura 5-21 Seqüência de incluir registros 85 5.5.3 Copiar Registros Este diagrama descreve a seqüência de eventos que ocorrerá quando o usuário realizar para a cópia de um registro existente, através de um formulário de cadastro. Figura 5-22 Seqüência de copiar registros 86 5.5.4 Modificar Registros Este diagrama descreve a seqüência de eventos que ocorrerá quando for alterado um registro existente no banco de dados, através de um formulário de cadastro Figura 5-23 Seqüência de modificar registros 87 5.5.5 Excluir Registros Este diagrama descreve a seqüência de eventos que ocorrerá quando for excluído um registro do banco de dados, através de um formulário de cadastro. Figura 5-24 Seqüência de excluir registros 88 5.5.6 Consultar Chave Estrangeira Este diagrama descreve a seqüência de eventos que ocorrerá quando o usuário estiver em um formulário de cadastro e realizar uma consulta em uma tabela que possua referência através de uma chave estrangeira. Figura 5-25 Seqüência de consultar chave estrangeira 89 5.6 Diagrama de Estados Um diagrama de gráfico de estados mostra uma máquina de estados, que consiste de estados, transições, eventos e atividades. Esses diagramas são importantes principalmente para se fazer a modelagem do comportamento de uma interface, classe ou colaboração, como pode ser observado na figura 5-37 (BOOCH, 2000, p. 332). Este diagrama apresenta os estados da classe TFrmCadastro, que é a principal classe do framework. A classe TFrmCadastro é a classe que será estendida para desenvolver uma aplicação sobre a arquitetura do framework. Figura 5-26 Diagrama de estado da classe TFrmCadastro O capítulo 6 apresentará um protótipo funcional que foi implementado utilizando-se a arquitetura do framework. Ele é composto de uma pequena aplicação com algumas opções de cadastro que demonstram todas as funcionalidades implementadas no framework. 6 PROTOTIPAÇÃO Este capítulo apresentará o protótipo desenvolvido, utilizando a arquitetura do framework projetado neste trabalho, e descreverá suas principais funcionalidades, que buscam otimizar o tempo de desenvolvimento das aplicações e também propiciar ao usuário final da aplicação, funcionalidades que facilitem sua interação com o sistema. O protótipo é apresentado em forma de uma pequena aplicação com algumas opções que demonstram todas as funcionalidades implementadas no framework. 6.1 Aplicação Principal A figura 6-1 apresenta uma sugestão de tela inicial para uma aplicação que seja desenvolvida utilizando a arquitetura do framework. Ela é composta basicamente por uma estrutura de menus (a esquerda) que identifica cada tabela do sistema e que conhece a classe responsável pela manutenção das informações nesta tabela. Na parte superior direita possui uma área (não implementado, apenas uma idéia), onde o usuário poderá criar atalhos para as opções que mais utiliza no sistema e na parte inferior o sistema irá registrar as últimas opções acessadas pelo usuário (não implementado, apenas uma idéia). Este modelo de aplicação apresentado utiliza o banco de dados para manter a estrutura de menus, onde é informado qual é a classe responsável pela manutenção das informações de cada tabela do sistema. Esta é apenas uma idéia proposta, existem outras formas que o framework também pode ser utilizado, sem perder suas funcionalidades. Todas as tabelas utilizadas nesta aplicação estão disponíveis junto com a documentação eletrônica14 deste trabalho. 14 Documentação eletrônica disponibilizada em CD, composta por: documentação das classes, script de criação do banco de dados, executável e arquivos necessários para rodar a aplicação teste. 91 Figura 6-1 Formulário inicial da aplicação 6.2 Incluir Registros A figura 6-2 apresenta um formulário em modo de inclusão, onde o usuário irá informar os valores para os campos disponíveis no formulário e ao final salvará o registro no banco de dados através da opção salvar ou poderá cancelar a inclusão do registro através da opção cancelar. O usuário poderá incluir vários registros e salvá-los todos juntos no final. Todos os passos para incluir novos registros foram descritos no capítulo 5 e podem ser vistos no cenário 5.2.3 Incluir Registros. Figura 6-2 Formulário - incluir registros 92 6.3 Copiar Registros O formulário apresentado pela figura 6-3, exibe um registro sendo copiado através da opção copiar, onde todos os valores são automaticamente copiados para um novo registro e apenas a chave primária do novo registro precisa ser informada pelo usuário. Esta funcionalidade é útil quando se precisa incluir um registro muito semelhante a outro já existente no banco de dados. Todos os passos para se copiar um registro foram descritos no capítulo 5 e podem ser vistos no cenário 5.2.4 Copiar Registros. Figura 6-3 Formulário - copiar registros 93 6.4 Excluir Registros Para excluir um registro, o usuário deve selecioná-lo através de uma consulta ao banco de dados. Após deve marcá-lo para exclusão através da opção excluir, conforme é apresentado na figura 6-4. O registro é eliminado definitivamente do banco de dados através da opção salvar. Todos os passos para se excluir um registro do banco de dados foram descritos no capítulo 5 e podem ser vistos no cenário 5.2.6 Excluir Registros. Figura 6-4 Formulário - excluir registros 94 6.5 Consultar Para realizar uma consulta ao banco de dados através de um formulário de cadastro, o usuário deverá entrar em modo de consulta, informar a(s) característica(s) do(s) registro(s) que procura e executar a consulta. A figura 6-5 mostra um formulário em modo de consulta, que procura por clientes com duas características específicas (que o nome seja igual a “Celso” e o representante igual a “1”). Todos os passos para se realizar uma consulta em um formulário de cadastro foram descritos no capítulo 5 e podem ser vistos no cenário 5.2.2 Realizar Consulta. Figura 6-5 Formulário - consultar 95 6.6 Visualizar Registros Após realizar uma consulta ao banco de dados ou enquanto estiver realizando manutenção em vários registros, é possível navegar nos registros um a um através das setas de próximo e anterior. Para ir diretamente a um registro que não seja o anterior ou o próximo ao registro atual, pode-se utilizar a opção browse, que exibe todos os registros em forma de um browse, conforme pode ser visto na figura 6-6. Para visualizar todos os dados do registro no formulário de cadastro, o usuário deve selecioná-lo e clicar no botão OK. Figura 6-6 Formulário - visualizar registros 96 6.7 Modificar Registros Para modificar um registro, o usuário irá selecioná-lo através de uma consulta ao banco de dados, informar os novos valores e efetivar as alterações no banco de dados através da opção salvar. A figura 6-7 apresenta um formulário em modo de edição, com um registro sendo alterado. Todos os passos para se modificar um registro foram descritos no capítulo 5 e podem ser vistos no cenário 5.2.5 Modificar Registros. Figura 6-7 Formulário - modificar registros 97 6.8 Consultar Chave Estrangeira Conforme foi descrito no cenário 5.2.7 Consultar Chave Estrangeira, quando o usuário estiver realizando a inclusão, cópia ou modificação de um registro, poderá executar uma consulta para saber os valores válidos para um campo que possua uma chave estrangeira, conforme pode ser visto na figura 6-8, que apresenta um exemplo, onde foi pesquisado todos os bancos cadastrados que iniciam com a palavra “Banco”. Quando o código procurado não existir é possível incluí-lo sem sair do formulário, através do botão cadastrar, que criará uma instância da classe responsável pela manutenção dos dados da tabela, então o usuário cadastra e volta para a consulta. Figura 6-8 Formulário - consultar chave estrangeira 98 6.9 Salvar Informações Quando o usuário solicitar que um registro seja salvo no banco de dados, ele passará pelo processo de validação que verifica se os valores informados atendem as regras de negócio implementadas, se a integridade referencial é atendida e se algum campo deve ser preenchido. Caso alguma inconsistência seja encontrada é apresentado um formulário com todas as mensagem, conforme é apresentado na figura 6-9, e o registro não é salvo sem que todas elas sejam atendidas. Figura 6-9 Salvando as informações CONCLUSÃO E TRABALHOS FUTUROS Frameworks e padrões vem sendo considerados como tecnologias importantes de reutilização em desenvolvimento de software, pois além de promoverem a reutilização, também promovem a modularidade e extensibilidade do software desenvolvido. A utilização de padrões de projeto é recomendada pela possibilidade de se obter uma estrutura de classes melhor organizada e mais apta a manutenção, pois os padrões representam uma base de conhecimento adquirida por especialistas durante muitos anos. Além disso a utilização de padrões na construção de um framework diminui o tempo de aprendizado de como utilizar o framework para desenvolver aplicações, uma vez que as pessoas que conhecem os padrões terão maior facilidade em utilizá-lo. Dentre as características dos frameworks, a principal é a inversão do controle, onde o framework tem o controle principal da aplicação, e é responsável por coordenar e definir a seqüência das atividades da aplicação, desta forma o desenvolvedor pode se concentrar nas funcionalidades específicas da aplicação que está desenvolvendo. Um framework possui métodos definidos e que devem ser estendidos pelo desenvolvedor para sua aplicação específica, o que dá força ao framework para servir de esqueletos extensíveis. Essa característica do framework servir como um esqueleto para as aplicações torna mais fácil sua manutenção, uma vez que todas as aplicações que forem estendidas do framework terão sua base muito similar, diminuindo o tempo de entendimento do código de uma aplicação para outra. Com frameworks bem projetados fica muito mais fácil fazer extensões, fatorar a funcionalidade comum, promover a interoperabilidade e melhorar a manutenção e confiabilidade do software. 100 Acredita-se que com a construção de um framework para persistência de dados consiga-se reduzir significativamente o tempo de desenvolvimento de novas aplicações, bem como a manutenção das aplicações existentes e que já tenham sido desenvolvidas sob sua arquitetura, pois todas terão o framework como base, o que facilita o entendimento de como elas funcionam. Com a redução do tempo de desenvolvimento e manutenção das aplicações a empresa se tornará mais competitiva no mercado, pois poderá reduzir seu custo sem perder qualidade. Outro benefício que acredita-se atingir com a construção do framework para persistência de dados, é a possibilidade de oferecer recursos que facilitem a forma de acessar e manter as informações no banco de dados, pois todas as funcionalidades implementadas no framework, as demais classes do sistema automaticamente herdarão. Como foi dito anteriormente, para desenvolver um sistema completo de gestão empresarial para um empresa, quer seja ela, uma indústria calçadista ou não, é necessário mais do que a entrada e manutenção das informações, embora seja uma parte fundamental. Então, como trabalhos futuros é possível se criar pequenos frameworks, que são chamados framelets (PREE, apud CRESPO, 2000, p. 22), e que complementariam as funcionalidades básicas necessárias em um sistema de gestão empresarial. Pode-se citar dois framelets que poderiam ser construídos: um para automatizar a criação de relatórios cadastrais, onde o próprio usuário definisse o layout do relatório e os filtros que seriam aplicados. Outro framelet poderia ser construído para servir como base para a criação de formulários de consultas e de emissão de relatórios administrativos, onde fossem implementadas funcionalidades para facilitar a interação do usuário com o sistema. É importante lembrar que um dos objetivos é que estas funcionalidades não tragam mais trabalho para o desenvolvimento das aplicações, pois se isso ocorrer, ficaria sem sentido o desenvolvimento de tais framelets. REFERÊNCIAS BIBLIOGRÁFICAS BEZERRA, Eduardo. Princípios de Análise e Projeto de Sistemas com UML. Rio de Janeiro: Campus, 2002. 286p. BOOCH, Grady; RUMBAUGH, James; JACOBSON, Ivar. UML, Guia do Usuário. Rio de Janeiro: Campus, 2000. 472p. CRESPO, Sérgio Coelho da Silva Pinto. Composição em WebFrameworks. Rio de Janeiro: 04 ago. 2000. 150 p. Tese(Doutor em Ciências em Informática) – Departamento de Informática, PUCRJ, 2000. FAYAD, Mohamed; SCHMIDT, Douglas C.. Object-Oriented Application Frameworks. Communications of the ACM, New York: v. 40, n. 10, Out. 1997. Disponível em: <http://www.cs.wustl.edu/~schmidt/CACM-frameworks.html>. Acesso em: 10 nov. 2003. FAYAD, Mohamed; SCHMIDT, Douglas C.; JOHNSON, Ralph. Building Application Frameworks: Object Oriented Foundations of Framework Design. New York: John Wiley & Sons, 1999. Disponível em: <http://media.wiley.com/product_data/excerpt/54/ 04712487/0471248754.pdf>. Acesso em 15 nov. 2003. GAMMA, Erich; HELM, Richard; JOHNSON, Ralph; VLISSIDES, John. Padrões de Projeto: Soluções Reutilizáveis de Software Orientado a Objetos. Porto Alegre: Bookman, 2000. 364p. GERBER, Luciano David. Uma Linguagem de Padrões para o Desenvolvimento de Sistemas de Apoio à Decisão Baseado em Frameworks. Porto Alegre: 1999. 144 p. Tese(Mestrado em Informática) – Faculdade de Informática, PUCRS, 1999. 102 JOHNSON, Ralph. Designing Reusable Classes. Journal of Object-oriented Programing, New York: v. 1, n. 2, Jun./Jul. 1988. Disponível em: <http://www- lifia.info.unlp.edu.ar/poo99/DesigningReusableClasses.doc>. Acesso em: 06 nov. 2003. JOHNSON, Ralph. Frameworks = (components + patterns). Communications of the ACM, New York: v. 40, n. 10, p. 39 – 43, Out. 1997. Disponível em: <http://wwwlifia.info.unlp.edu.ar/poo2001/Frameworks-patterns.pdf>. Acesso em: 06 nov. 2003. LARMAN, Craig. Utilizando UML e Padrões: Uma introdução à análise e ao projeto orientado a objetos. Porto Alegre: Bookman, 2000. 492p. LEE, Richard C.; TEPFENHART, Willian M. UML e C++: Guia Prático de Desenvolvimento Orientado a Objeto. São Paulo: Makron Books, 2001. 550p. MALDONADO, José Carlos et al. Padrões e Frameworks de Software. São Paulo: 2001. 37 p. Instituto de Ciências Matemáticas e de Computação, USP, 2001. Disponível em: <http://www.icmc.sc.usp.br/~rtvb/apostila.pdf>. Acesso em: 07 de nov. 2003. PAGE-JONES, Meilir. O Que Todo Programador Deveria Saber Sobre Projeto Orientado a Objeto. São Paulo: Makron Books, 1997. 386p. RUMBAUGH, James et al. Modelagem e Projetos Baseados em Objetos. Rio de Janeiro: Campus, 1994. 652p. SILVA, Ricardo Pereira. Suporte ao Desenvolvimento e Uso de Frameworks e Componentes. Porto Alegre: mar. 2000. 262 p. Tese(Doutor em Ciência da Computação) – Instituto de Informática, UFRGS, 2000. Disponível em: <http://www.inf.ufsc.br/~ricardo/ download/tese.pdf>. Acesso em: 07 nov. 2003. TALIGENT, Inc. Leveraging Object-Oriented Frameworks. A Taligent White Paper, 1993. Disponível em: <http://lhcb-comp.web.cern.ch/lhcb-comp/Components/ postscript/leveragingoo.pdf>. Acesso em: 02 nov. 2003. VLISSIDES, John. Pattern Hatching: Perspectives from the “Gang of Four”. Mar 1995. Disponível em: <http://www.research.ibm.com/designpatterns/pubs/pathatch.html>. Acesso em: 02 nov. 2003.