UNIVERSIDADE DO PLANALTO CATARINENSE DEPARTAMENTO DE CIÊNCIAS EXATAS E TECNOLÓGICAS CURSO DE SISTEMAS DE INFORMAÇÃO (BACHARELADO) MARIANA CARDOSO DE BEM CASTELLO BRANCO PROCESSO DE GERAÇÃO DE CÓDIGO EM JAVA A PARTIR DE UM DIAGRAMA DE CLASSES LAGES (SC) 2008 MARIANA CARDOSO DE BEM CASTELLO BRANCO PROCESSO DE GERAÇÃO DE CÓDIGO EM JAVA A PARTIR DE UM DIAGRAMA DE CLASSES Trabalho de Conclusão de Curso submetido à Universidade do Planalto Catarinense para obtenção dos créditos de disciplina com o nome equivalente no curso de Sistemas de Informação Bacharelado. Orientação: Prof. Alexandre Perin de Souza, M.Sc. LAGES (SC) 2008 MARIANA CARDOSO DE BEM CASTELLO BRANCO PROCESSO DE GERAÇÃO DE CÓDIGO EM JAVA A PARTIR DE UM DIAGRAMA DE CLASSES ESTE RELATÓRIO, DO TRABALHO DE CONCLUSÃO DE CURSO, FOI JULGADO ADEQUADO PARA OBTENÇÃO DOS CRÉDITOS DA DISCIPLINA DE TRABALHO DE CONCLUSÃO DE CURSO, DO 8º. SEMESTRE, OBRIGATÓRIA PARA OBTENÇÃO DO TÍTULO DE: BACHAREL EM INFORMAÇÃO SISTEMAS DE Lages (SC), 01 de Dezembro de 2008 Prof. Alexandre Perin de Souza, M.Sc. Orientador BANCA EXAMINADORA: Prof. Marcos André Pisching, M.Sc. UNIPLAC Prof. Daiana Petry, M.Sc. UNIPLAC Prof. Wilson Castello Branco Neto, Dr. Professor de TCC Prof. Ângelo Augusto Frozza, M.Sc. Coordenador de Curso Dedico este trabalho aos meus pais Édson e Arlete, meu irmão Eduardo, minha filha Beatriz e meu esposo Wilson, que sempre me apóiam direta ou indiretamente. Agradeço a Deus e aos bons guias por toda luz e proteção. Agradeço ao meu esposo Wilson por todo ensinamento, paciência e amor despendidos. Agradeço ao meu orientador Perin por toda paciência e dedicação. Quando você quer alguma coisa, todo o universo conspira para que você realize o seu desejo. (Paulo Coelho) LISTA DE ILUSTRAÇÕES FIGURA 1 - Ambiente Hipotético de Produção de Software alicerçado por uma ferramenta CASE .....................................................................................16 FIGURA 2 - Interface da ferramenta CASE JUDE......................................................22 FIGURA 3 - Interface da ferramenta CASE Enterprise Architect ...............................24 FIGURA 4 - Interface da ferramenta CASE Rational Rose .........................................25 FIGURA 5 - Interface da ferramenta CASE Umbrello ................................................27 FIGURA 6 - Interface da ferramenta CASE ArgoUML ...............................................29 FIGURA 7 - Interface da ferramenta CASE UML Modeling para NetBeans ..............30 FIGURA 8 - Mapeamento da classe Aluno para Java .................................................34 FIGURA 9 - Mapeamento da classe Aluno e seus atributos para Java .......................35 FIGURA 10 - Classe com associação unidirecional para 1 .........................................36 FIGURA 11 - Classe com associação unidirecional para 0..1 .....................................37 FIGURA 12 - Classe com associação unidirecional para * .........................................38 FIGURA 13 - Classe com associação ordenada ...........................................................39 FIGURA 14 - Classe com associação qualificada ........................................................40 FIGURA 15 - Classe de associação ..............................................................................41 FIGURA 16 - Classe com associação bidirecional ......................................................43 FIGURA 17 - Agregação ..............................................................................................44 FIGURA 18 - Agregação compartilhada ......................................................................45 FIGURA 19 - Agregação por composição ...................................................................45 FIGURA 20 - Classes Professor e Técnico Administrativo herdando da classe Funcionário ............................................................................................47 FIGURA 21 - Exemplo de hierarquia de herança ........................................................48 FIGURA 22 - Polimorfismo de sobreposição ..............................................................49 FIGURA 23 - Operação e consulta de sistema e método delegado .............................50 FIGURA 24 - Interface .................................................................................................52 FIGURA 25 - Barra de ferramentas para geração de código .......................................54 FIGURA 26 - Configuração da linguagem em que o código será gerado ...................55 FIGURA 27 - Definição dos objetos ............................................................................55 FIGURA 28 - Diagrama de classe de um laboratório de exames clínicos ...................58 FIGURA 29 - Diagrama de classe de um laboratório de exames clínicos para pessoa/animal ........................................................................................63 QUADRO 1 - Requisitos de sistema para funcionamento do JUDE ...........................22 QUADRO 2 - Requisitos de sistema para funcionamento do EA no Windows...........24 QUADRO 3 - Requisitos de sistema para funcionamento do EA no Linux ................24 QUADRO 4 - Requisitos de sistema para funcionamento do Rational Rose ...............26 QUADRO 5 - Requisitos de sistema para funcionamento do ArgoUML ....................29 QUADRO 6 - Requisitos de sistema para funcionamento do UML Modeling para NetBeans ................................................................................................31 QUADRO 7 - Resumo das ferramentas CASE ............................................................31 QUADRO 8 - Mapeamento de Sets e Gets da classe Aluno para Java ........................35 QUADRO 9 - Mapeamento da classe com associação unidirecional para 1 em Java .36 QUADRO 10 - Mapeamento da classe com associação unidirecional para 0..1 em Java .....................................................................................................37 QUADRO 11 - Mapeamento da classe com associação unidirecional para * em Java .............................................................................................................38 QUADRO 12 - Método para consultar um subconjunto específico de alunos .............38 QUADRO 13 - Mapeamento da classe com associação ordenada para Java ..............39 QUADRO 14 - Mapeamento da classe com associação qualificada para Java ...........40 QUADRO 15 - Mapeamento de classe de associação em Java ...................................41 QUADRO 16 - Mapeamento da classe com associação bidirecional em Java para a classe Aluno ........................................................................................43 QUADRO 17 - Mapeamento da classe com associação bidirecional em Java para a classe Curso .........................................................................................43 QUADRO 18 - Agregação compartilhada e seu código em Java ................................45 QUADRO 19 - Agregação por composição e seu código em Java ..............................45 QUADRO 20 - Mapeamento das classes Professor e Técnico Administrativo herdando da classe Funcionário em Java ............................................................47 QUADRO 21 - Polimorfismo de sobreposição e seu código em Java .........................49 QUADRO 22 - Implementação da operação de sistema e do método delegado ..........50 QUADRO 23 - Interface e seu código em Java ...........................................................52 QUADRO 24 - Código da classe Enfermeiro gerado no EA .......................................58 QUADRO 25 - Código da classe Enfermeiro corrigido para compilar ........................59 QUADRO 26 - Código da classe Paciente gerado no EA ............................................60 QUADRO 27 - Código da classe Paciente corrigido para compilar ............................61 QUADRO 28 - Código da classe Equipamento gerado no EA ....................................63 QUADRO 29 - Código da classe Equipamento corrigido para compilar .....................64 QUADRO 30 - Código da classe Equipamento gerado no UML Modeling para NetBeans ..............................................................................................65 QUADRO 31 - Código da classe Sala gerado no EA ...................................................66 QUADRO 32 - Código da classe Sala corrigido para compilar ...................................67 QUADRO 33 - Código da classe Sala gerado no UML Modeling para NetBeans .......68 QUADRO 34 - Código da classe Espera gerado no EA ...............................................68 QUADRO 35 - Código da classe Recuperação gerado no EA .....................................69 QUADRO 36 - Código da classe Espera corrigido para compilar ...............................69 QUADRO 37 - Código da classe Recuperação corrigido para compilar .....................69 QUADRO 38 - Código da classe Espera gerado no UML Modeling para NetBeans ...70 QUADRO 39 - Código da classe Recuperação gerado no UML Modeling para NetBeans ..............................................................................................70 QUADRO 40 - Código da interface Paciente gerado no EA........................................71 QUADRO 41 - Código da classe PacienteAnimal gerado no EA ................................71 QUADRO 42 - Código da classe PacienteAnimal corrigido para compilar ................71 QUADRO 43 - Código da classe PacienteAnimal gerado no UML Modeling para NetBeans ..............................................................................................72 LISTA DE ABREVIATURAS E SIGLAS CASE DER DFD EA ER IBM JPA JUDE JVM KDE UML XMI XML - Computer-Aided Software Engineering - Diagrama de Entidade e Relacionamento - Diagrama de Fluxo de Dados - Enterprise Architect - Entidade Relacionamento - International Business Machine - Java Persistence API - Java and UML Developer Environment - Java Virtual Machine - K Desktop Environment - Unified Modeling Language - XML Metadata Interchange - eXtensible Markup Language RESUMO Este trabalho trata da geração de código orientado a objetos em Java a partir de um diagrama de classes. Ele apresenta um breve estudo sobre as ferramentas CASE JUDE, Enterprise Architect, Rational Rose, Umbrello UML Modeler, Argo UML e UML Modeling para NetBeans, descrevendo suas principais características, com o objetivo de ressaltar as semelhanças e diferenças existentes entre as ferramentas mais usadas atualmente. Além disto, detalha como deve ser desenvolvido o código em Java a partir de um diagrama de classes, visando explicar como cada conceito do diagrama deve ser representado na linguagem Java. De posse deste conhecimento é possível verificar a consistência dos códigos gerados automaticamente pelas ferramentas, que é o objetivo central deste trabalho. Para isto, foram desenvolvidos dois diagramas de classes sobre um mesmo contexto, um laboratório de exames clínicos. O primeiro diagrama mostra conceitos mais simples, como classes, atributos e métodos, e o segundo conceitos mais complexos, como herança, interface e polimorfismo. Partindo dos diagramas, o código foi gerado no Enterprise Architect para o primeiro exemplo e no Enterprise Architect e no UML Modeling para NetBeans para o segundo exemplo. A escolha por estas duas ferramentas deve-se ao fato delas representarem situações bem distintas: enquanto a primeira é proprietária e visa exclusivamente à modelagem - não está diretamente integrada a nenhum ambiente de programação - a segunda é uma ferramenta livre e integrada ao NetBeans IDE, que consiste em uma das ferramentas mais usadas no desenvolvimento Java. Os códigos gerados nas duas ferramentas foram analisados e incluídos em um projeto no NetBeans para serem compilados, com o intuito de verificar se eles estavam corretos e completos. A partir da análise dos códigos gerados pelas duas ferramentas verificou-se a existência de problemas, pois ambas falharam em alguns pontos da geração. Ressalta-se como principal problema a não criação de métodos para manipular as associações entre classes. Isto leva à conclusão que as ferramentas CASE são úteis para agilizar o trabalho de codificação, mas ainda não são capazes de realizar integralmente o trabalho, sem a intervenção de um programador. Palavras-chave: Ferramenta CASE; Programação Orientada a Objetos; Geração Automática de Código; Java. ABSTRACT This job deals with the code generation in Java, based on class diagrams. It presents a brief study about CASE tools such as JUDE, Enterprise Architect, Rational Rose, Umbrello UML Modeler, Argo UML and UML Modeling to NetBeans, and shows the main features about CASEs aiming at showing similarities and differences between tools used nowadays. Furthermore, this work presents details about how Java code must be written based on class diagrams. This process has as goal to explain how each diagram’s concept should be represented in Java language. Based on this knowledge it is possible to verify the automatically generated code consistence, which is the main goal of this job. For this, two class diagrams about the same context, a laboratory of clinic exams, were developed. The first diagram displays basic oriented object concepts such as: class, attributes and methods and the second one shows complex concepts: inheritance, interface and polymorphism. Based on such diagrams, the code were generated using Enterprise Architect tool to the first example and Enterprise Architect and UML Modeling to NetBeans to the second one. The choice by these two tools is based on fact that they represent different contexts: while the first is owner and has as objective just the modeling – it is not integrated with programming environment – the second one is a free tool and is integrated to NetBeans IDE, which is quite used in the Java development. The code generated were analyzed and inserted into NetBeans project to be compiled, aiming at verifying if the codes were correct and complet or not. The code generated analysis showed some problems, because both tools don’t work correctly in code generation process. The main problem of this process is not creating methods to handle associations between classes. So, the conclusion is that CASE tools are important to speed up the implementation job, although the tools are not able to accomplish completely the generation code without the human intervention. Keywords: CASE Tools; object-oriented programming; automatic code generation; Java. SUMÁRIO LISTA DE ABREVIATURAS E SIGLAS ..................................................................9 1 INTRODUÇÃO ........................................................................................................14 1.1 Apresentação ...........................................................................................................14 1.2 Descrição do problema ............................................................................................15 1.3 Justificativa ..............................................................................................................16 1.4 Objetivo geral ..........................................................................................................17 1.5 Objetivos específicos ...............................................................................................17 1.6 Metodologia .............................................................................................................18 2 FERRAMENTAS CASE..........................................................................................20 2.1 Ferramentas CASE ..................................................................................................20 2.1.1 JUDE ............................................................................................................................... 21 2.1.2 Enterprise Architect......................................................................................................... 23 2.1.3 Rational Rose................................................................................................................... 24 2.1.4 Umbrello UML Modeller ................................................................................................. 26 2.1.5 ArgoUML ......................................................................................................................... 28 2.1.6 UML Modeling para Netbeans ........................................................................................ 29 2.1.7 Resumo das ferramentas estudadas................................................................................. 31 2.2 Conclusão ................................................................................................................32 3 GERAÇÃO DE CÓDIGO .......................................................................................34 3.1 Classes e atributos ...................................................................................................34 3.2 Associações .............................................................................................................35 3.2.1 Associação unidirecional com multiplicidade 1 .............................................................. 36 3.2.2 Associação unidirecional com multiplicidade 0..1 .......................................................... 37 3.2.3 Associação unidirecional com multiplicidade * .............................................................. 37 3.2.4 Associação unidirecional com multiplicidade ordenada ................................................ 39 3.2.5 Associação unidirecional qualificada ............................................................................. 40 3.2.6 Associação unidirecional com classe de associação ...................................................... 41 3.2.7 Associação unidirecional com multiplicidade 1 na origem ............................................ 42 3.2.8 Associação bidirecional .................................................................................................. 42 3.3 Agregação ................................................................................................................44 3.4 Herança ....................................................................................................................46 3.4.1 Hierarquias de herança ................................................................................................... 47 3.5 Polimorfismo ...........................................................................................................48 3.6 Métodos delegados e operações/consultas de sistema ............................................50 3.7 Interface ...................................................................................................................51 3.8 Conclusão ................................................................................................................52 4 ANÁLISE DE CÓDIGO GERADO A PARTIR DE DIAGRAMA DE CLASSES .....................................................................................................................54 4.1 Geração de código na ferramenta CASE Enterprise Architect ...............................54 4.2 Exemplo 1 ................................................................................................................56 4.2.1 Sumário executivo............................................................................................................ 56 4.2.2 Requisitos funcionais ....................................................................................................... 56 4.2.3 Diagrama de classes........................................................................................................ 57 4.2.4 Análise dos códigos gerados ........................................................................................... 58 4.3 Exemplo 2 ................................................................................................................61 4.3.1 Diagrama de Classes ....................................................................................................... 62 4.3.2 Análise dos Códigos Gerados.......................................................................................... 63 4.4 Conclusão ................................................................................................................72 5 CONSIDERAÇÕES FINAIS ...................................................................................74 REFERÊNCIAS BIBLIOGRÁFICAS ......................................................................77 BIBLIOGRAFIA COMPLEMENTAR .....................................................................80 APÊNDICES ................................................................................................................82 14 1 INTRODUÇÃO 1.1 Apresentação A Engenharia de Software é uma disciplina que integra processos, métodos e ferramentas para o desenvolvimento de software (PRESSMAN, 2001), buscando resolver os problemas com eficácia para criar softwares com qualidade. Ela foi dividida em várias áreas para melhor atingir seus objetivos. Uma destas áreas é a de Ferramentas e Ambientes de Desenvolvimento de Software, a qual tem recebido especial atenção nos últimos anos, devido a sua natural evolução. Sua finalidade está em agilizar e organizar a produção e manutenção dos diversos artefatos envolvidos na elaboração de um software. Para que o desenvolvimento do sistema ocorra com maior eficiência, existem diversas ferramentas que auxiliam neste processo, chamadas de ferramentas CASE (Computer-Aided Software Engineering). Uma atividade possível de ser feita através do uso de uma ferramenta CASE é a criação de diagramas com base na notação UML (Unified Modeling Language). Dentro da UML, que é uma linguagem de modelagem para visualizar, especificar, documentar e desenvolver sistemas, existem diversos diagramas, dentre eles, está o diagrama de classes que, segundo Barnes e Kölling (2004), mostra as classes de uma aplicação e os relacionamentos entre elas, fornece as informações sobre o código-fonte e apresenta a visualização estática de um programa. A partir do diagrama de classes, que foi criado a partir de um exemplo fictício de um laboratório de exames clínicos, é possível gerar o código do sistema em 15 diversas linguagens através de uma ferramenta CASE, que suporte desde a especificação e análise dos requisitos, até o projeto e implementação do sistema. Ferramentas CASE têm se mostrado cada vez mais importantes e poderosas, auxiliando o desenvolvedor na maximização de suas habilidades intelectuais e criativas (BARRÉRE, PRADO e BONAFE, 2008). A análise dos códigos gerados a partir do diagrama de classes torna possível corrigir aqueles gerados de forma inadequada e faz com que o usuário conheça melhor os aspectos positivos e negativos do gerador de código disponível nas ferramentas CASE. Por isso, um estudo que ofereça um melhor entendimento de como o processo de geração automática de código ocorre é essencial para a produção de sistemas com qualidade. Além desta apresentação, o restante do trabalho está organizado da seguinte maneira: no capítulo 2 é feito um estudo sobre ferramentas CASE, apresentando suas principais características; o capítulo 3 trata o processo de tradução de diagrama de classes para código na linguagem Java; a consistência dos códigos gerados pela ferramenta CASE Enterprise Architect e UML Modeling para NetBeans e as soluções para os códigos inconsistentes são apresentadas no capítulo 4. Por fim, o capítulo 5 mostra as considerações finais sobre o trabalho. 1.2 Descrição do problema Em virtude de uma maior inserção dos computadores na vida das pessoas, criar software tornou-se uma tarefa complexa, seja pelo aparecimento de novas necessidades, ou pela complexidade intrínseca das aplicações. Uma forma de contornar esta situação ou minimizar o seu impacto está no uso de ferramentas CASE. Uma vez definido o diagrama de classes, realiza-se a geração de código automática para uma determinada linguagem de programação usando uma ferramenta CASE. Em alguns casos, o resultado deste processo é insatisfatório, pois nem sempre há consistência entre ambos. 16 Diante do exposto, o desafio deste trabalho está em descobrir os motivos que levam à criação de classes incompletas ou inconsistentes a partir da geração automática de código realizada por uma ferramenta CASE, como a figura 1 apresenta. FIGURA 1 - Ambiente Hipotético de Produção de Software alicerçado por uma ferramenta CASE 1.3 Justificativa O tema de pesquisa abordado neste trabalho inspira-se em um objetivo primordial da área de Engenharia de Software: produzir sistemas com qualidade. Em função disso, surgiu a necessidade de realizar um estudo sobre o processo de geração de código orientado a objetos através de ferramentas CASE. Outro ponto de destaque e que ratifica a importância deste estudo, refere-se ao avanço da tecnologia, principalmente dos computadores. Estas máquinas estão inseridas cada vez mais na vida das pessoas, criando novas necessidades e desafios para Engenheiros de Software. Assim, para acompanhar o avanço da tecnologia e o surgimento de novas necessidades, engenheiros de sistemas precisam adotar novos 17 paradigmas, ferramentas, linguagens, etc. A programação orientada a objetos é um paradigma que vem conquistando cada vez mais a preferência dos programadores. Dentre alguns motivos que levam a esta escolha, estão a simplificação de requisitos, projetos e implementação (GUSTAFSON, 2003). Para poder programar orientado a objetos é necessário criar também um projeto orientado a objetos, cujo o núcleo é composto por um diagrama de classes (WAZLAWICK, 2004). Para agilizar o desenvolvimento do projeto, programadores estão buscando recursos, como ferramentas CASE, para auxiliar nas suas tarefas. Essas ferramentas CASE proporcionam o aumento da utilização da geração automática de código, diminuindo assim o tempo de desenvolvimento do software e aumentando a sua qualidade, o que facilita o trabalho dos desenvolvedores. Mas, para ter certeza de que esses códigos são gerados de maneira correta, é necessário entender como deve ser e como é feita a tradução do diagrama de classes pelas ferramentas CASE para determinada linguagem de programação orientada a objetos e verificar se há consistência entre ambos. 1.4 Objetivo geral Analisar a geração de código a partir de diagrama de classes através de ferramenta CASE para a linguagem de programação Java. 1.5 Objetivos específicos São objetivos específicos deste trabalho: a) Explorar as principais ferramentas CASE do mercado de forma a apresentar suas características mais importantes; b) Explicitar como se dá o processo de tradução de diagrama de classes para Java; c) Análise e ajuste dos códigos gerados pelas ferramentas CASE. 18 1.6 Metodologia Segundo Silva e Menezes (2005), existem várias formas de classificar as pesquisas. A forma tradicional prevê: i) quanto a natureza; ii) quanto aos objetivos; iii) quanto a abordagem do problema; e, iv) quanto a procedimentos técnicos para sua execução. Em função da classificação mencionada, este trabalho de conclusão de curso se enquadra metodologicamente da seguinte maneira: Do ponto de vista da sua natureza, o mesmo caracteriza-se como de natureza aplicada. Do ponto de vista da forma de abordagem do problema, este trabalho classifica-se como sendo de pesquisa qualitativa. Em relação aos objetivos, trata-se de uma pesquisa exploratória e também explicativa. Já sob o ponto de vista dos procedimentos técnicos, este trabalho classifica-se como sendo de pesquisa bibliográfica. O trabalho foi realizado da seguinte forma: primeiro, foi feito um estudo sobre algumas ferramentas CASE em livros e materiais disponíveis na Internet. O objetivo deste estudo foi compreender as principais características das mesmas. Em seguida, foi apresentado o processo de tradução de um diagrama de classes para Java. A execução deste passo foi baseada na proposta de geração de código descrita por Wazlawick (2004). Concluída a fundamentação teórica do trabalho, o passo seguinte foi a elaboração de dois exemplos de diagramas de classes, um mais simples e outro mais complexo, a geração de código de forma automática através de uma ferramenta CASE para o primeiro exemplo e duas ferramentas para o segundo exemplo, e este mesmo código colocado no Netbeans para a verificação da sua consistência. Nesta etapa foram utilizadas as ferramentas CASE proprietária - Enterprise Architect (SPARX SYSTEMS, 2008) e livre - UML Modeling para NetBeans. As ferramentas foram 19 utilizadas para gerar os códigos dos exemplos propostos anteriormente. Após a geração de código, os resultados foram verificados em relação à propriedade de consistência de código. Ainda nesta etapa, soluções para os modelos inconsistentes foram propostas. O trabalho foi finalizado com a elaboração de um artigo, do relatório de TCC e da apresentação do trabalho em banca. 20 2 FERRAMENTAS CASE Este capítulo apresenta um apanhado geral sobre algumas das ferramentas CASE (Computer-Aided Software Engineering) mais utilizadas e importantes do mercado, a fim de compreender suas principais características. O capítulo inicia com uma breve introdução sobre CASEs, partindo para a apresentação de aspectos importantes de cada uma das ferramentas CASE estudadas. 2.1 Ferramentas CASE Juntamente com a evolução da Engenharia de Software surgiram as ferramentas CASE, que auxiliam os desenvolvedores no processo de criação de software, melhorando, assim, a qualidade dos mesmos. As ferramentas CASE dão suporte computacional ao desenvolvedor ao longo do ciclo de vida da criação de sistemas, reduzindo o tempo total de desenvolvimento (SILVA e ROCHA, 1998). Elas são de suma importância também para a manutenção do software, auxiliando, assim, em todo o processo de desenvolvimento (Gerência, Análise, Projeto, Implementação, Teste e Manutenção) (PELOSO, 2004). Através das ferramentas CASE é possível modelar o sistema antes de escrever o seu código, o que possibilita a detecção de falhas de projeto no seu início, sendo este o período mais fácil para corrigí-las (BOGGS e BOGGS, 2002). Existem diversas ferramentas CASE no mercado, cada uma com características próprias, como a linguagem de modelagem utilizada, linguagem para a geração de código e diagramas que podem ser criados. Nas subseções 2.1.1 a 2.1.6 são apresentadas as principais características de seis destas ferramentas, após instalação e 21 uso das mesmas. 2.1.1 JUDE O JUDE (Java and UML Developer Environment), fabricado pela Change Vision (JUDE, 2007), desde sua primeira versão, é uma das ferramentas livres mais poderosas disponíveis para modelagem UML (Unified Modeling Language). Possui características que não são encontradas em outras ferramentas gratuitas, como a possibilidade de adicionar métodos no diagrama de seqüência, alterando automaticamente o diagrama de classes (PORTAL JAVA, 2008). O JUDE possui uma versão livre que é incentivada pela JUDE Community e a versão proprietária, chamada JUDE Professional, a qual possui uma versão trial por 20 dias. Uma das diferenças encontradas em ambas, é que alguns recursos da versão proprietária não são disponibilizados para a versão gratuita, como a possibilidade de criar Diagramas de Entidade Relacionamento (DER) e Diagramas de Fluxo de Dados (DFD), de converter DER em modelos UML, além do suporte ao XMI (XML Metadata Interchange) (JUDE, 2007). O XMI é um modelo para definir, trocar, manipular e integrar dados e objetos XML (eXtensible Markup Language), cujos padrões são usados para integrar ferramentas, repositórios, aplicações, etc. Este padrão é usado para troca de informações entre diferentes aplicativos para modelagem de sistemas que fazem uso da UML (OMG, 2008). O JUDE possuía, em 2006, 60 mil usuários e, segundo a empresa responsável pelo seu desenvolvimento, 5 mil novos usuários estavam aderindo à ferramenta a cada mês (JUDE, 2007). Os diagramas suportados pelo JUDE na fase de análise são os de Caso de Uso, Seqüência e Atividade. Na fase do projeto ele possibilita o desenvolvimento dos diagramas de Classes, Colaboração, Componentes, Distribuição e Estados. A figura 2 apresenta uma interface desta ferramenta. Na parte superior fica localizado o menu principal, que permite criar, salvar, abrir arquivos, pacotes, elementos, selecionar diagramas, etc. À esquerda, uma barra de ferramentas mostra a 22 estrutura do diagrama criado, a herança, o mapa, os diagramas que foram desenvolvidos e uma opção de busca. À direita, na parte principal da interface, apresentam-se os diagramas criados, com seus atributos, métodos e associações. FIGURA 2 - Interface da ferramenta CASE JUDE O JUDE é voltado para a linguagem de programação Java e pode ser utilizado em todos os sistemas operacionais que possuam a Máquina Virtual Java (JVM – Java Virtual Machine). Além de gerar código nesta linguagem ele também é capaz de realizar engenharia reversa, transformando códigos Java em diagramas. Os requisitos mínimos para o funcionamento da ferramenta são descritos no quadro 1. QUADRO 1 - Requisitos de sistema para funcionamento do JUDE Sistema Operacional Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Outros Versão Windows 2000, XP, Vista 256MB 128MB Pentium III de 700MHz J2SE1.4.1_07 ou superior, ou J2SE1.4.2_05 ou superior ou JDK5.0 JUDE Community 5.2.1 e JUDE Professional 5.2.1 23 2.1.2 Enterprise Architect O Enterprise Architect (EA) é uma ferramenta de análise e projeto UML, que possibilita o desenvolvimento de software a partir de um conjunto de requisitos, análise de estágios, modelos de projeto, testes e manutenção. O EA é uma ferramenta multi-usuário, projetada para auxiliar na construção de softwares robustos e eficazes (KATÁLOGO, 2008). O EA é uma ferramenta proprietária, fabricada pela Sparx Systems (SPARX SYSTEMS, 2008) e tem uma versão trial que pode ser usada por 30 dias. O EA suporta os 13 diagramas UML, entre outros. Na fase de análise: Caso de Uso, Seqüência, Atividade e Objeto. Na fase de Projeto: Classe, Distribuição, Componente e Estado. Além disso, possui suporte ao XMI. A figura 3 apresenta uma interface da ferramenta com o menu principal na parte superior, que possíbilita criar, salvar, abrir arquivos, pacotes, diagramas, elementos, etc. À esquerda encontram-se duas barras de ferramentas. Na primeira (Toolbox), estão os elementos que podem ser usados nos diversos diagramas, como Classes, Associações, Atores e Casos de Uso. Na segunda (Project Browser), encontram-se os diagramas que fazem parte do projeto, os quais são definidos no momento da sua criação. À direita, está a parte principal da interface, onde os diagramas são desenvolvidos. O Enterprise Architect possui versões para Windows e Linux a qual possibilita a geração de código e a engenharia reversa em várias linguagens de programação, como Java, C#, C++, Visual Basic, VB .Net, Delphi e PHP. Por ser de fácil utilização, esta ferramenta possui mais de 50.000 usuários (licenças pagas) em mais de 60 países, entre eles: Estados Unidos, Canadá, Reino Unido, Espanha, Alemanha, Japão, Escandinávia, França, Holanda entre outros. Apresenta forte suporte na Austrália, Brasil, México, Nova Zelândia, Coréia, África do Sul, Argentina, Chile, etc. (MOMBACH, 2005). 24 FIGURA 3 - Interface da ferramenta CASE Enterprise Architect Os requisitos mínimos para o funcionamento da ferramenta no Windows e no Linux são descritos nos quadros 2 e 3. QUADRO 2 - Requisitos de sistema para funcionamento do EA no Windows Sistema Operacional Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Outros Versão Windows 128 MB 70 MB Pentium 7.1 QUADRO 3 - Requisitos de sistema para funcionamento do EA no Linux Sistema Operacional Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Outros Versão Linux 64MB 70 MB Pentium II Linux Operating System (kernel 2.4) 7.1 2.1.3 Rational Rose Rational Rose é uma ferramenta que auxilia os desenvolvedores nos 25 processos de construção de um software, utilizada por diversos profissionais e grandes empresas. Foi criada pela Rational, posteriormente adquirida pela IBM (International Business Machine), sendo uma ferramenta proprietária, com versão trial por 30 dias (IBM, 2008). Ela viabiliza aos analistas de sistemas a realização de diversas tarefas, que vão desde a criação dos modelos, configuração e criação dos diagramas da UML, tais como o de Caso de Uso, Seqüência e Atividade, na fase de análise; Classe, Objetos, Colaboração, Componentes, Distribuição e Estados, na fase de projeto (BOGGS e BOGGS, 2002). A figura 4 apresenta uma interface da ferramenta com o menu principal na parte superior, sendo possível criar, salvar, abrir arquivos, pacotes, diagramas, elementos, etc. À esquerda encontram-se os diagramas que fazem parte do projeto e os elementos que podem ser usados nos diversos diagramas, como Classes, Associações, Atores e Casos de Uso. À direita, está a parte principal da interface, onde os diagramas são desenvolvidos. FIGURA 4 - Interface da ferramenta CASE Rational Rose 26 O Rational Rose gera código em várias linguagens disponíveis no mercado, como C++, Ada, CORBA, Java, Visual Basic e XML, e também pode aplicar engenharia reversa ao código destas mesmas linguagens. Esta ferramenta é executada no sistema operacional Windows (IBM, 2008). Atualizações como o CASE Tools XMI Update (ESRI, 2008) e o XMI Toolkit (IBM, 2008) permitem que o Rational Rose importe e exporte arquivos no formato XMI. Os requisitos mínimos para o funcionamento da ferramenta são descritos no quadro 4. QUADRO 4 - Requisitos de sistema para funcionamento do Rational Rose Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Outros Versão 256 MB 450 MB Pentium II de 450MHz 7.0 2.1.4 Umbrello UML Modeller O Umbrello UML Modeller é uma ferramenta criada com o apoio da comunidade de software livre, cujo projeto é liderado por Jonathan Riddell (UMBRELLO UML MODELLER, 2008). É uma ferramenta de domínio público, que possibilita a criação de diagramas UML para auxiliar no processo de desenvolvimento de software, ajudando a obter um produto de qualidade, especialmente durante as fases de análise e projeto (VIEIRA, 2008). Ele suporta os seguintes diagramas UML: Caso de Uso, Seqüência e Atividade, na fase de análise, e de Classes, Colaboração, Componente, Estados e Distribuição, na fase de projeto. Esta ferramenta salva seus arquivos no formato padronizado XMI, que também é utilizado e compatível com vários outros softwares do gênero. A figura 5 apresenta a tela principal da ferramenta com o menu principal na parte superior, sendo possível criar, salvar, abrir arquivos, pacotes, diagramas, elementos, etc. À esquerda, encontra-se uma barra de ferramentas (Tree View) que 27 contém as opções dos diagramas que podem ser criados. À direita, na parte principal da interface, é apresentado o diagrama que está sendo desenvolvido pelo usuário. FIGURA 5 - Interface da ferramenta CASE Umbrello O Umbrello é capaz de gerar o código a partir dos diagramas UML nas linguagens: ActionScript, Ada, C++, IDL (CORBA), Java, JavaScript, Perl, PHP, Python, Ruby, SQL, TCL, XMLSchema. Também é possível importar código para gerar diagramas (engenharia reversa), a partir das linguagens C++, Java e Python. Os sistemas operacionais em que a ferramenta pode ser executada são o Linux, Unix, FreeBSD e Solaris. A ferramenta acompanha o KDE (K Desktop Environment), ou seja, está presente em todas as distribuições do GNU/Linux, sendo que os requisitos mínimos para instalação dependem das exigências da distribuição do Linux que está instalada (UMBRELLO UML MODELLER, 2008). 28 2.1.5 ArgoUML O ArgoUML é uma ferramenta desenvolvida pela Tigris.org Open Source Software Engineering Tools (Ferramentas Livres para Engenharia de Software), que é uma comunidade focada em construir ferramentas com melhor qualidade para o desenvolvimento de software colaborativo (TIGRIS.ORG, 2008). Da versão 0.24 aconteceram mais de 120 mil downloads desde que foi disponibilizada em 2007. Considerando todas as versões, o número de downloads chega a 500 mil, demonstrando assim, uma estimativa do número de usuários desta ferramenta (TIGRIS.ORG, 2008). O ArgoUML é uma ferramenta CASE em Java para projetos orientados a objetos, que inclui os mesmos recursos de edição e geração de códigos encontrados em ferramentas CASE comerciais, inclusive o suporte a XMI (GOMES, 2008). Ela é uma ferramenta gratuita que permite modelar diagramas da UML como de Caso de Uso, Seqüência e Atividade, na fase de análise; Classe, Colaboração, Distribuição e Estados, na fase de projeto. A interface principal da ferramenta é apresentada na figura 6, com um menu na parte superior que possibilita criar, salvar, abrir arquivos, pacotes, diagramas, elementos, etc. Na esquerda encontram-se os diagramas que fazem parte do projeto, os quais são definidos no momento da sua criação. À direita, está a parte principal da interface, onde os diagramas são desenvolvidos. Essa ferramenta pode gerar código nas linguagens de programação C++, C#, Java, PHP e faz engenharia reversa. Pode ser utilizado em todos os sistemas operacionais que possuam a JVM. Outra característica é o suporte à internacionalização, ou seja, o programa é adaptado para que seja traduzido para diversos idiomas. Um dos pontos negativos é que ainda não suporta todas as características da UML, como, por exemplo, não oferece total suporte a alguns diagramas como o diagrama de seqüência. Os requisitos mínimos para o funcionamento da ferramenta são descritos no quadro 5. 29 FIGURA 6 - Interface da ferramenta CASE ArgoUML QUADRO 5 - Requisitos de sistema para funcionamento do ArgoUML Sistema Operacional Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Windows 64MB Outros Versão Java 2 JRE ou JDK instalado 10MB Intel Pentium de 200MHz, AMD K6 ou um processador semelhante 0.24 2.1.6 UML Modeling para Netbeans O NetBeans é um projeto Open Source, com diversos usuários e uma comunidade crescente, com aproximadamente 100 parceiros pelo mundo. A Sun Microsystem fundou este projeto em junho de 2000 e continua sendo seu principal patrocinador (NETBEANS, 2008). O NetBeans possui além de outros recursos, a modelagem UML, facilitando o trabalho de desenvolvedores, pois permite o desenvolvimento da modelagem e a 30 geração do código em uma mesma ferramenta. É uma ferramenta gratuita que permite modelar 8 diagramas da UML, como de Caso de Uso, Seqüência e Atividade, na fase de análise; Classe, Colaboração, Componente, Implantação e Estado, na fase de projeto. Essa ferramenta gera código na linguagem Java, faz engenharia reversa e pode ser utilizada pelos sistemas operacionais Windows, Linux, Mac OS e Solaris. Um dos pontos negativos é não possuir suporte à XMI, nem à internacionalização. A interface principal da ferramenta é apresentada na figura 7, com um menu na parte superior que possibilita criar, salvar, abrir arquivos, pacotes, elementos, etc. Na esquerda encontram-se os elementos que fazem parte do projeto. Ao centro está a parte principal da interface, onde os diagramas são desenvolvidos, e à direita uma paleta com os elementos que podem ser usados nos diversos diagramas. FIGURA 7 - Interface da ferramenta CASE UML Modeling para NetBeans Os requisitos mínimos para o funcionamento da ferramenta no Windows são 31 descritos no quadro 6. QUADRO 6 - Requisitos de sistema para funcionamento do UML Modeling para NetBeans Windows 512MB Sistema Operacional Quantidade Recomendada de Memória Espaço em Disco Disponível Processador Outros Versão 750MB Pentium III, 800MHz JDK instalado 6.1 2.1.7 Resumo das ferramentas estudadas No quadro 7, encontra-se um resumo das ferramentas CASE estudadas. O mesmo foi organizado levando em consideração características gerais que uma ferramenta CASE deve prover. Tais aspectos se justificam na perspectiva de que um desenvolvedor possa compreendê-los e, assim, ter uma visão abrangente de uma determinada ferramenta CASE. QUADRO 7 - Resumo das ferramentas CASE Características JUDE Distribuição Proprietária e Livre Sim Proprietária Proprietária Livre Livre UML Modeling para NetBeans Livre Sim Sim Sim Sim Sim Todos Windows (9x, NT, ME, 2000, XP), Linux UML Windows (9x, NT, ME, 2000, XP) UML Linux, Unix, FreeBSD, e Solaris Windows 95, 98, 2000, NT UML UML Windows, Linux, Mac OS e Solaris UML Caso de Uso, Classes, Seqüência, Atividade, Objeto, Componente, Distribuição e Estado Casos de Uso, Classes, Componente, Desenvolvimento, Objetos, Seqüência, Colaboração, Estado Caso de Uso, Classes, Seqüência, Caso de Uso, Seqüência, Atividade, Classes, Faz Engenharia Reversa Sistema Operacional Quais Linguagens de Modelagem Utiliza Diagramas UML Suportados UML Caso de Uso, Classes, Seqüência, Colaboração, Atividade, Componente, Desenvolvimento e Enterprise Architect Rational Rose Umbrello Colaboração, Atividade, Componente, Estado e Distribuição ArgoUML Colaboração, Distribuição e Estado Caso de Uso, Seqüência, Atividade, Classes, Colaboração, Componente, Implanta- 32 Estado e Atividades Gera Código em quais Linguagens de Programação Java C++, Java, C#, Visual Basic, PHP, VB .Net, Delphi C++, C#, Ada, CORBA, Java, PHP, Visual Basic, XML, Net Suporte a XMI Sim1 Sim Sim, com o uso de ferramentas complementares Suporte a Internacionalização Versão Trial Sim, na versão Professional Sim Sim ção e Estado ActionScript, Ada, C++, IDL (CORBA), Java, JavaScript, Perl, PHP, PHP5, Python, Ruby, SQL, TCL, XML Schema Sim Não se aplica C++, C#, Java, PHP Java Sim Não Sim Não Não se aplica Não se aplica 2.2 Conclusão Neste capítulo foi realizado um estudo sobre ferramentas CASE, apontando suas principais características, tais como: modo de distribuição, realização de engenharia reversa, suporte a XMI, entre outras; as quais foram resumidas e organizadas em um quadro. Este quadro é a principal contribuição deste capítulo, pois para desenvolvê-lo foi necessário um estudo das ferramentas através de várias referências bibliográficas e, também, através do uso de cada uma delas. Além disso, ele é importante porque apresenta de forma sucinta as semelhanças e diferenças entre as ferramentas estudadas sob vários aspectos, permitindo que um usuário possa facilmente identificar aquela que possui os recursos que ele necessita. Percebeu-se com este estudo que, embora existam diferenças entre as ferramentas proprietárias e as livres, todas possuem características parecidas, tanto no layout como nos recursos disponíveis. Isto permite concluir que o conhecimento 1 Apenas na versão JUDEProfessional. 33 adquirido em uma ferramenta possa ser usado de forma a permitir a um Engenheiro de Software usar qualquer outra sem grandes dificuldades. Outro ponto a destacar é o suporte ao XMI, uma novidade que está presente em todas as ferramentas estudadas, tendo como principal objetivo, fornecer as empresas uma forma fácil de integrar artefatos escritos em diferentes sistemas computacionais, ou seja, conforme documentação de cada CASE estudada, é possível a migração de um trabalho desenvolvido em uma das ferramentas CASE estudadas para outra ferramenta, devido as suas semelhanças. 34 3 GERAÇÃO DE CÓDIGO Este capítulo apresenta os principais conceitos de orientação a objetos necessários para o entendimento do trabalho. Cada conceito é representado através de um diagrama de classes que por sua vez é convertido em código expresso na linguagem Java. A modelagem e o processo de geração de código foram baseados em Wazlawick (2004), que explica como ocorre todo esse processo. 3.1 Classes e atributos Uma classe, segundo Barnes e Kölling (2004), descreve um objeto de um tipo em particular. A figura 8 mostra como uma classe do diagrama de classes é convertida em uma classe na linguagem de programação Java. FIGURA 8 - Mapeamento da classe Aluno para Java Os atributos armazenam dados para um objeto (BARNES e KÖLLING, 2004). Os atributos das classes são transformados em variáveis de instância privadas da classe como mostra a figura 9. 35 FIGURA 9 - Mapeamento da classe Aluno e seus atributos para Java As variáveis que armazenam os atributos, neste caso privadas, devem implementar métodos para acessar e alterar os valores de seus atributos. O quadro 8 mostra a implementação dos métodos assessores Getter e Setter que, respectivamente, fazem alteração e consulta nos atributos da classe da figura 9. Esses métodos não estão presentes no diagrama porque fazem parte dos atributos da classe. QUADRO 8 - Mapeamento de Sets e Gets da classe Aluno para Java package tccquadros; public class Aluno { private float altura; private String nome; private boolean pne; //portadores de necessidades especiais private char sexo; public public public public void void void void setAltura(float altura) {this.altura = altura;} setNome(String nome) {this.nome = nome;} setPne(boolean pne) {this.pne = pne;} setSexo(char sexo) {this.sexo = sexo;} public public public public float getAltura(){return altura;} String getNome(){return nome;} boolean isPne(){return pne;} char getSexo(){return sexo;} public Aluno() {} } 3.2 Associações As associações do diagrama de classes são transformadas em variáveis de instância no código em Java e têm métodos para modificação e consulta. Elas geram tipos e variáveis que são classes de objetos ou estruturas de dados, além de haver algumas distinções a fazer quanto aos métodos associados. De modo geral, cada associação deve implementar no mínimo três métodos: 36 um para criar a associação, um para destruir a associação e um para consultar os elementos associados. Esses métodos variam de acordo com a multiplicidade de cada associação, como mostram as subseções 3.2.1 a 3.2.8. 3.2.1 Associação unidirecional com multiplicidade 1 A associação unidirecional para 1 deve ser armazenada em uma variável de instância na classe de origem da associação e seu tipo deve ser a classe de destino. Uma associação unidirecional para 1 de BoletoBancario para Aluno corresponde a uma variável de instância na classe BoletoBancario declarada com tipo Aluno. Como a associação é para 1, não é possível destruí-la, sendo que esse método não deve ser implementado. O método criador da classe deve ter como parâmetro o elemento a ser associado, para que todas as instâncias da classe na origem da associação estejam consistentes desde o início. A consulta, nesse caso, baseia-se no nome da classe no lado oposto da associação, sem parâmetros. A figura 10 mostra uma classe com associação unidirecional para 1 e o quadro 9 apresenta o código a ser implementado. FIGURA 10 - Classe com associação unidirecional para 1 QUADRO 9 - Mapeamento da classe com associação unidirecional para 1 em Java package tccquadros; public class BoletoBancario { private Aluno aluno; public BoletoBancario(Aluno alu) { this.setAluno(alu);} public void setAluno(Aluno alu){ this.aluno = alu;} public Aluno getAluno(){ return this.aluno;} } 37 3.2.2 Associação unidirecional com multiplicidade 0..1 O procedimento de geração de código é semelhante ao da associação para 1, sendo que a consulta e a criação da associação são implementadas exatamente como no caso anterior. A diferença é que nesse caso é possível destruir a associação. Na figura 11 é mostrado uma classe com associação unidirecional para 0..1 e seu código é apresentado no quadro 10. FIGURA 11 - Classe com associação unidirecional para 0..1 QUADRO 10 - Mapeamento da classe com associação unidirecional para 0..1 em Java package tccquadros; public class BoletoBancario { private Pagamento pagamento; public BoletoBancario(){} public void setPagamento(Pagamento pag){ this.pagamento = pag;} public void removePagamento(){ this.pagamento = null;} public Pagamento getPagamento(){ return this. pagamento;} } 3.2.3 Associação unidirecional com multiplicidade * A associação unidirecional para * corresponde à implementação de um conjunto, constituindo-se pela implementação de uma variável do tipo Conjunto (Set em inglês), ou de acordo com as especificações da JPA (Java PersistenceAPI), pode ser uma Collection. Nesse caso, a variável que contém a associação tem seu nome no plural e seu tipo é Set. A classe Set, que representa o conjunto, possui um método add para associar elementos no conjunto e um método remove para desassociar elementos no conjunto. A figura 12 apresenta a classe com associação unidirecional com 38 multiplicidade para * e seu respectivo código é mostrado no quadro 11. A operação de consulta é getAluno, que retorna o Set com todos os alunos da turma. É possível implementar métodos de consulta para retornar alunos específicos ou subconjuntos de alunos, sendo que cada consulta seria um método distinto. Já na classe Aluno, não existe atributo que permita identificar um aluno, não sendo possível implementar uma consulta para retornar um aluno específico. Mas é possível implementar uma consulta que retorne o conjunto de todos os alunos que pertencem a uma turma num determinado tempo, conforme mostra o quadro 12. FIGURA 12 - Classe com associação unidirecional para * QUADRO 11 - Mapeamento da classe com associação unidirecional para * em Java package tccquadros; public class Turma { private Set alunos = new Set(); public Turma() {} public void addAluno(Aluno alu){ this.alunos.add(alu);} public void removeAluno(Aluno alu){ this.alunos.remove(alu);} public Set getAluno(){ return this.alunos;} } QUADRO 12 - Método para consultar um subconjunto específico de alunos public Set getAlunosdaTurma(String turma){ Set aluTur = new Set(); Aluno atual; alunos.start(); while(alunos.hasNext()){ atual = alunos.next(); if (atual.turma().equalsIgnoreCase(turma)){ aluTur.add(atual);} } return aluTur;}} 39 3.2.4 Associação unidirecional com multiplicidade ordenada Quando a multiplicidade para * for ordenada, na implementação deve-se usar uma lista como estrutura de dados e não um conjunto. A associação ordenada é implementada de maneira semelhante à associação simples com multiplicidade *, com a diferença de ter dois métodos para desassociar. Além da forma de remoção usada no conjunto, também é possível desassociar um objeto indicando a posição em que ele se encontra. O método para associação de um elemento deve indicar a posição em que o elemento é inserido e podem ser implementadas variações do método de associação como addFirst e addLast. Uma forma de evitar alguns problemas como, por exemplo, associação ou desassociação em uma posição inválida, é tratar a lista como uma fila ou pilha, com métodos de associação e desassociação mais comportados que a lista, acessando assim, somente as extremidades dessas estruturas. A figura 13 mostra a associação ordenada entre Turma e Aluno, sendo muito semelhante à associação simples com multiplicidade *. Sua implementação é apresentada no quadro 13. FIGURA 13 - Classe com associação ordenada QUADRO 13 - Mapeamento da classe com associação ordenada para Java package tccquadros; import java.util.ArrayList; public class Turma { private ArrayList alunos = new ArrayList(); public Turma() {} public void addAluno(Aluno alu, int posicao){ this.alunos.add(posicao, alu);} public void removeAluno(Aluno alu){ this.alunos.remove(alu);} public void removeAlunoNaPosicao(int posicao){ 40 this.alunos.remove(posicao);} public ArrayList getAlunos(){ return this.alunos;} public Aluno getAlunoNaPosicao(int posicao){ return (Aluno) this.alunos.get(posicao);} } 3.2.5 Associação unidirecional qualificada Esta associação é implementada de forma muito parecida com a associação com multiplicidade *. Mas, ao invés de conjunto, é utilizada uma estrutura de dicionário (Map), associando o atributo qualificador ao objeto. Assim, é possível implementar um método de consulta que retorne um objeto da coleção se for dado um valor para o qualificador, como mostram a figura 14 e o quadro 14. O mapeamento é feito de String(nome) para Aluno, sendo que o conjunto de nomes é cadastro.get e o conjunto de alunos é cadastro.value. A operação de desassociação pode ser implementada de duas formas: pela chave e pelo valor. FIGURA 14 - Classe com associação qualificada QUADRO 14 - Mapeamento da classe com associação qualificada para Java package tccquadros; import java.util.Map; public class Universidade { private Map cadastro = new Map(); public Universidade(){} public void addNoCadastro(Aluno alu){ this.cadastro.put(alu.getNome(), alu);} public void removeDoCadastro(Aluno alu){ this.cadastro.remove(alu);} public void removeDoCadastroPorNome(String nome){ this.cadastro.remove(nome);} public Set getCadastro(){ return (Set) this.cadastro.values();} public Aluno getAluno(String nome){ return (Aluno) this.cadastro.get(nome);} } 41 3.2.6 Associação unidirecional com classe de associação Neste caso, é necessário implementar a criação e a remoção de instâncias da classe de associação, cada vez que uma associação é criada ou removida. Classes de associação podem existir em associações com qualquer multiplicidade, mas o mais comum é ser utilizada em associações de * para *. A implementação consiste em um Map, que associa instâncias do destino da associação a instâncias da classe de associação. Ao adicionar uma nova associação de Aluno com Curso, automaticamente é adicionado uma nova Matrícula na associação, sendo possível desassociar um elemento da associação por referência ao Curso (keySet) ou por Matrícula (values). A figura 15 mostra uma classe de associação e o quadro 15 mostra a implementação da associação na classe de origem. No último método do quadro 15 é apresentado como obter uma Matrícula específica a partir de um Curso. FIGURA 15 - Classe de associação QUADRO 15 - Mapeamento de classe de associação em Java package tccquadros; import java.util.Map; public class Aluno { private Map cursos = new Map(); public Aluno() {} public void addCurso(Curso curso){ this.cursos.put(curso, new Matricula());} public void removeCurso(Curso curso){ this.cursos.remove(curso);} public void removeMatricula(Matricula matricula){ 42 this.cursos.remove(matricula);} public Set getCursos(){ return (Set) this.cursos.keySet();} public Set getMatriculas(){ return (Set) this.cursos.values();} public Matricula getMatriculaNoCurso(Curso curso){ return (Matricula) this.cursos.get(curso);} } 3.2.7 Associação unidirecional com multiplicidade 1 na origem É necessário sempre observar se a multiplicidade na origem é 1 para todos os tipos de associação unidirecional definidos. Se for o caso, a destruição da associação só é possível quando o objeto também destrói o objeto no destino da associação, senão o objeto fica inconsistente, pois necessita estar associado a um elemento. O mesmo cuidado deve ser tomado em associações de 1 para 0..1 ou de 1 para 1. 3.2.8 Associação bidirecional Se a associação for bidirecional, ela deve ser implementada em ambas as classes, independente de a multiplicidade ser para 1, para 0..1 ou para *, sendo que cada lado da associação é implementado de acordo com as regras definidas anteriormente. Os métodos de criação e destruição da associação são uma das grandes diferenças da associação bidirecional com relação à unidirecional, devendo existir em cada uma das classes um método auxiliar para criar e destruir a associação e outro método para chamar esse método auxiliar. Se, em uma associação bidirecional, um dos lados tiver multiplicidade 1, não é possível implementar o método de destruição da associação, pois como já foi visto, uma associação para 1 não pode ser destruída. Por exemplo, se um Curso criar associação com um Aluno a e depois com um Aluno b, o Aluno a mantém uma referência inconsistente com o Curso, pois é necessário remover a associação que já existe antes de criar uma nova associação, sendo que esta situação também deve ser tratada no código. 43 Os métodos auxiliares associaCursoAux, adicionaCursoAux e removeCursoAux, não devem ser públicos, mas exportados exclusivamente para a classe associada. Esses métodos não podem ser usados em outro lugar além dos métodos associaAluno e adicionaAluno. A figura 16 mostra uma associação de 1 para *, sendo este o caso mais comum. Sua implementação é apresentada nos quadros16 e 17. FIGURA 16 - Classe com associação bidirecional QUADRO 16 - Mapeamento da classe com associação bidirecional em Java para a classe Aluno package tccquadros; import java.util.Set; public class Aluno { private Set cursos = new Set(); public Aluno() {} public void addCursoAux(Curso curso){ cursos.add(curso);} public void removeCursoAux(Curso curso){ cursos.remove(curso);} public void addCurso(Curso curso){ if(curso.getAluno()!=null){ curso.getAluno().removeCursoAux(curso); }; this.addCursoAux(curso); curso.addAlunoAux(this);} public void removeCurso(Curso curso){ this.removeCursoAux(curso); curso.destroi();} public Set getCursos(){ return (Set) this.cursos;} } QUADRO 17 - Mapeamento da classe com associação bidirecional em Java para a classe Curso package tccquadros; public class Curso { private Aluno aluno; public Curso(Aluno aluno){ 44 this.addAluno(aluno); } public void addAlunoAux(Aluno aluno){ this.aluno = aluno;} public void addAluno(Aluno aluno){ if(this.aluno!=null){ this.aluno.removeCursoAux(this);} this.addAlunoAux(aluno); aluno.addCursoAux(this);} public Aluno getAluno(){ return this.aluno;} } 3.3 Agregação Uma agregação é um relacionamento do tipo todo-parte. Por exemplo, salas de aula são partes de um bloco. Se os blocos forem modelados por uma classe e as salas por outra classe, o relacionamento entre essas classes é uma agregação. Essas partes e o todo devem ser de mesma natureza fisica, para efetivamente ser considerado uma agregação. Na UML (Unified Modeling Language), uma agregação é identificada por uma linha que une as classes que fazem parte da agregação com um losango sem preenchimento em uma de suas extremidades, como mostra a figura 17. O losango é posicionado na extremidade que liga a classe que compõe o todo. Na agregação, a parte pode ou não pertencer a mais de um todo. Quando pertence a mais de um, há uma agregação compartilhada. Quando não puder pertencer a mais de um, há uma composição. FIGURA 17 - Agregação Na agregação compartilhada, por exemplo, a disciplina de Matemática pode pertencer aos cursos de Administração e de Sistemas de Informação. O mesmo 45 acontece com aluno: o aluno a pode pertencer a um curso ou mais. Uma agregação compartilhada é identificada na UML por um losango sem preenchimento, como mostra a figura 18. Seu código é apresentado no quadro 18. Na composição, quando o todo é destruído, as partes são também destruídas. Por exemplo, bloco e suas salas é uma composição, pois quando o bloco é destruído, suas salas também são destruídas. Uma composição é identificada na UML por um losango sólido, como mostra a figura 19 e seu código é apresentado no quadro 19. (ALBUQUERQUE, 1999). FIGURA 18 - Agregação compartilhada QUADRO 18 - Agregação compartilhada e seu código em Java package tccquadros; import java.util.Set; public class Curso { private Set Disciplinas = new Set(); public Curso(){} public void addDisciplinas(Disciplina disc){ this.Disciplinas.add(disc);} public void removeDisciplinas(Disciplina disc){ this.Disciplinas.remove(disc);} public Set getDisciplinas(){ return this.Disciplinas;} } FIGURA 19 - Agregação por composição QUADRO 19 - Agregação por composição e seu código em Java package tccquadros; import java.util.Set; public class Bloco { 46 private Set Salas = new Set(); public Bloco() {} public void addSalas(Sala sal){ this.Salas.add(sal);} public void removeSalas(Sala sal){ this.Salas.remove(sal);} public Set getSalas(){ return this.Salas;} } 3.4 Herança A herança é um mecanismo que fornece uma solução para problemas de duplicação: em vez de definir as classes Professor e TecnicoAdministrativo de forma completa e independente, primeiro define-se uma classe que contém tudo que essas duas classes têm em comum, que é exemplificada como Funcionario. Assim, Professor é um Funcionario e TecnicoAdministrativo é um Funcionario. Por fim, são adicionados detalhes extras necessários às classes Professor e TecnicoAdministrativo. A principal vantagem desta técnica é descrever os recursos comuns entre as classes somente uma vez. A figura 20 mostra as classes para essa estrutura, com a classe Funcionario na parte superior, definindo todos os atributos comuns para todos os funcionários (professor e técnico administrativo). Na parte inferior, estão as classes Professor e TecnicoAdministrativo, armazenando somente os atributos que são únicos para cada classe em particular. Cada classe (Professor e TecnicoAdministrativo) pode definir seus próprios métodos, como é exemplificado posteriormente. O mapeamento dessas classes de herança é apresentado no quadro 20. As setas no diagrama de classe (sem preenchimento) representam o relacionamento de herança. Em Java, utiliza-se a palavra extends para definir este mesmo relacionamento. A classe Funcionário é chamada superclasse, que é a classe da qual as outras classes herdam suas características. As classes Professor e TecnicoAdministrativo são as subclasses, ou seja, as classes que herdam a superclasse. 47 A herança permite criar duas classes que são semelhantes, ao mesmo tempo em que evita escrever a parte idêntica duas vezes (BARNES E KÖLLING, 2004). FIGURA 20 - Classes Professor e Técnico Administrativo herdando da classe Funcionário QUADRO 20 - Mapeamento das classes Professor e Técnico Administrativo herdando da classe Funcionário em Java public class Funcionario { private int cpf; private String endereco; private String nome; //construtores e metodos} public class Professor extends Funcionario { private float cargaHoraria; private String departamento; private float valorHoraAula; //construtores e metodos} public class TecnicoAdministrativo extends Funcionario{ private float salarioBase; private String setor; //construtores e metodos} 3.4.1 Hierarquias de herança A herança pode ser utilizada de maneira mais geral do que foi mostrado na seção 3.4, na qual mais de duas subclasses podem herdar da mesma superclasse e uma subclasse pode ser uma superclasse para outras subclasses. Formando, assim, uma hierarquia de heranças. A figura 21 mostra um exemplo com uma pequena parte de hierarquia de heranças, sendo que um mestre é um professor, que é um funcionário. A herança é uma técnica de abstração que permite categorizar as classes de 48 objetos sob certos critérios e ajuda a especificar características dessas classes (BARNES e KÖLLING, 2004). FIGURA 21 - Exemplo de hierarquia de herança 3.5 Polimorfismo Polimorfismo é um código que pode ser aplicado a várias classes de objetos, sendo que a mesma mensagem é enviada a objetos de classes distintas, podendo elas reagirem de maneiras diferentes. O polimorfismo também permite que uma operação de uma mesma classe possa ser implementada por mais de um método. O usuário não precisa saber quantas implementações existem para uma operação, ou explicitar qual método deve ser utilizado, pois a linguagem de programação deve ser capaz de selecionar o método correto a partir do nome da operação, classe do objeto e argumentos para a operação. Desta forma, novas classes podem ser adicionadas sem a necessidade de modificação de código já existente, pois cada classe apenas define os seus métodos e atributos. (BLANCO, 2008). Segundo Novatec (2008), existem três formas de polimorfismo: inclusão, paramétrico e sobreposição. O polimorfismo de inclusão, também chamado de polimorfismo puro, permite a criação de métodos capazes de receber parâmetros de várias classes 49 diferentes, se pertencerem a uma árvore de herança. Também permitem que em um método, um parâmetro do tipo de uma classe base possa ser utilizado para receber objetos do tipo das classes especializadas. O polimorfismo paramétrico permite que se criem métodos e tipos genéricos. Pode-se, com ele, retirar das declarações de atributos, parâmetros de métodos e tipos de retorno de métodos, referências ao tipo de dado. A definição do tipo é adiada para o momento da execução. Esse tipo de polimorfismo não é suportado pelas linguagens de orientação a objetos, não tendo suporte na versão atual do Java. O polimorfismo de sobreposição dá suporte para que seja possível a especialização de classes. Esse tipo de polimorfismo permite redefinir um método em uma classe especializada, como mostra a figura 22, implementando um novo comportamento, apresentado no quadro 21. FIGURA 22 - Polimorfismo de sobreposição QUADRO 21 - Polimorfismo de sobreposição e seu código em Java public class abstract Funcionario{ private int cpf; private String endereco; private String nome; abstract public double calculeSalarioBruto(); } public class Professor extends Funcionario { private float cargaHoraria; private String departamento; private float valorHoraAula; 50 public double calculeSalarioBruto(){ return ((this.cargaHoraria * 4.5) * this.valorHoraAula);} } public class TecnicoAdministrativo extends Funcionario { private float salarioBase; private String setor; public double calculeSalarioBruto(){ return ((this.salarioBase)} } 3.6 Métodos delegados e operações/consultas de sistema As operações de sistema são métodos ativados a partir de um evento de sistema, ou seja, como resposta a uma ação do usuário, indicando um fluxo de informações do exterior para o interior do sistema, alterando assim, as informações do sistema. Consultas de sistema são métodos que correspondem à verificação de informação que já está armazenada, não podendo inserir, remover ou alterar essas informações. Os métodos delegados são usados para chamar os métodos de outros objetos e devem ser tratados da mesma forma que as operações de sistema (WAZLAWICK, 2004). A figura 23 mostra a classe Universidade (controlador) que possui a operação de sistema MatriculaAlunoNoCurso, a consulta de sistema RetorneFormandosDoCurso e a classe Curso com o método delegado MatriculaAluno. Na implementação da operação de sistema, como mostra o quadro 22, percebe-se a chamada ao método delegado por meio de uma instância da classe Curso. FIGURA 23 - Operação e consulta de sistema e método delegado QUADRO 22 - Implementação da operação de sistema e do método delegado 51 package tccquadros; public class Universidade { Curso cursoAtual; public void matriculaAlunoNoCurso(String nomeAluno){ cursoAtual.matriculaAluno(nomeAluno);} public Set retorneFormandosDoCurso(){ return cursoAtual.retorneFormandos;} } 3.7 Interface Interface é um mecanismo simplificado de implementação de herança múltipla em Java que permite que mais de uma interface determine os métodos que uma classe herdeira deve implementar. As interfaces especificam formas de acesso e não como algo deve ser implementado, aumentando assim, a coesão. Isto permite ao desenvolvedor criar implementações específicas para interfaces de forma a não infligir uma especificação prévia (SANTOS, 2003). Se uma classe não tiver nenhum método não-abstrato, pode-se criá-la como uma interface, que possui um modo de declaração diferente do utilizado para classes, mas tem a mesma funcionalidade de classes abstratas. A sintaxe para definição de uma interface é semelhante à utilizada na definição de classes. Todos os métodos em uma interface são implicitamente abstratos e públicos. Interfaces não podem ter atributos, mas podem possuir constantes definidas. Uma vez definida, a interface é compilada normalmente (um arquivo.class é gerado, como se fosse uma classe qualquer). Uma classe pode ainda implementar mais de uma interface, neste caso, elas são colocadas lado a lado, separadas por vírgula juntamente com a cláusula implements. Quando uma classe implementa uma interface, ela deve obrigatoriamente implementar os métodos definidos nesta interface (BARTH, 2008). As interfaces são declaradas com a palavra-chave interface e não com a palavra class (SANTOS, 2003), como mostra a figura 24. Seu código é apresentado no quadro 23. 52 FIGURA 24 - Interface QUADRO 23 - Interface e seu código em Java package tccquadros; public interface BancodeDados{ public void consultar(); public void alterar(); public void excluir(); public void incluir();} public class BancodeDadosA implements BancodeDados { public void inserir(){} public void excluir(){} public void alterar(){} public void consultar(){}} public class BancodeDadosB implements BancodeDados { public void inserir(){} public void excluir(){} public void alterar(){} public void consultar(){}} 3.8 Conclusão Como existem regras bem definidas para a tradução de um diagrama de classes para código orientado a objetos, é possível criar um algoritmo com as regras ou passos a serem realizados para que esta tradução seja feita de forma correta. A partir dessas regras, pode-se gerar um código, diminuindo a complexidade da programação. Além disso, com o código resultante, pode-se verificar se os códigos gerados pela ferramenta CASE a partir de um dado diagrama de classes estão corretos ou não. 53 Caso esses códigos não estejam corretos, é possível identificar o erro, sendo este o principal objetivo do capítulo 4. Apesar de Wazlawick (2004) ser a base para a elaboração do capítulo 3, muitos conceitos de orientação a objetos necessitaram de uma abordagem em outras referências. Isto foi necessário para facilitar o entendimento dos conceitos, tanto do ponto de vista da modelagem quanto da implementação orientada a objetos, e para realizar o aprofundamento necessário para geração de código. O entendimento destes conceitos constitui-se em uma das maiores dificuldades enfrentadas na elaboração do capítulo, tornando complexa também a elaboração de exemplos relacionados aos conceitos, dentro de um mesmo estudo de caso. 54 4 ANÁLISE DE CÓDIGO GERADO A PARTIR DE DIAGRAMA DE CLASSES Este capítulo mostra como realizar a geração de código na ferramenta CASE (Computer-Aided Software Engineering) Enterprise Architect, a partir de exemplos de diagramas de classes desenvolvidos nesta mesma ferramenta, apresentando diversos conceitos de orientação a objetos abordados no capítulo 3 deste trabalho. Além disso, apresentam-se algumas sugestões para corrigir os códigos gerados de forma inconsistente. 4.1 Geração de código na ferramenta CASE Enterprise Architect No EA (Enterprise Architect), após a conclusão do diagrama de classes, a etapa de geração deve passar pelos seguintes passos: Ao criar uma classe, deve-se escolher a linguagem em que o código deve ser criado, através da opção Language, neste caso, Java; Verificar se a opção View – Toolbars – Code Generation está habilitada para que o usuário tenha acesso aos ícones de geração de código, como apresenta a figura 25; FIGURA 25 - Barra de ferramentas para geração de código Através da janela Local Options, no menu Tools – Options, seleciona-se Java Specifications. É necessário configurar a linguagem que será utilizada, indicando qual sua extensão, o tipo de atributo padrão e os prefixos de get e set, como mostra a figura 26; 55 FIGURA 26 - Configuração da linguagem em que o código será gerado Ainda na janela Local Options, é necessário clicar em Collection Class para definir qual o tipo de objeto será utilizado nas associações para *. Neste caso, utiliza-se Set, HashMap e ArrayList, como mostra a figura 27. Caso estes tipos de objetos não sejam definidos, será gerada uma instância da classe origem e não uma coleção de instâncias; FIGURA 27 - Definição dos objetos Para que no código gerado apareçam os métodos get e set, que fazem parte dos 56 atributos da classe, é necessário indicar que os atributos são propriedades, através da opção Property, durante a sua criação; Quando estes ajustes estiverem prontos, existem duas formas de gerar o código. Uma é gerar o código de uma classe por vez, selecionando a classe desejada e clicando no segundo ícone da figura 25. A outra é gerar o código de todas as classes, selecionando todas elas e clicando no terceiro ícone da figura 25. Após o usuário deve informar o endereço onde o arquivo deve ser salvo e clicar no botão Generate. 4.2 Exemplo 1 Este exemplo apresenta um diagrama de classes criado para um laboratório de exames clínicos fictício, com o intuito de abordar alguns conceitos básicos de orientação a objetos, como: classe, atributo, associações, herança, variável do tipo conjunto (Set) e método delegado. 4.2.1 Sumário executivo É proposto o desenvolvimento de um sistema para o controle de um laboratório de exames clínicos, que informatizará as funções de cadastros de funcionário, paciente, médico e sala, o controle de equipamentos, fornecedores dos mesmos e tipos de exames que cada paciente pode realizar. O objetivo do sistema é agilizar o processo de cadastros, garantindo assim um melhor controle de todas as informações manipuladas no âmbito do laboratório. 4.2.2 Requisitos funcionais Apesar de existir formas de registro e organização de requisitos, como o foco deste exemplo e deste trabalho é outro, serão listados apenas os nomes dos requisitos funcionais: Manter informações sobre pacientes com os seguintes dados: nome, 57 endereço, telefone e data de nascimento; Manter informações sobre fornecedor com os seguintes dados: CNPJ, endereço, nome e telefone; Manter informações sobre equipamentos com os seguintes dados: data de aquisição e nome; Manter informações sobre exame com os seguintes dados: data e nome; Manter informações sobre salas com os seguintes dados: número, descrição e sigla; Manter informações sobre médicos com os seguintes dados: nome, endereço, telefone e CRM; Manter informações sobre especialidade com o seguinte dado: nome; Manter informações sobre funcionários com os seguintes dados: nome, endereço, telefone; Manter informações sobre enfermeiro com o seguinte dado: COREN. 4.2.3 Diagrama de classes A figura 28 apresenta o diagrama de classes criado a partir das informações descritas nos requisitos do sistema. Além das classes, atributos e associações criados para representar estas informações, existem dois métodos na classe Paciente. O primeiro, CalculeIdade, calcula a idade de um paciente através da data de nascimento e da data atual. O outro método, RealizeExame, é um método delegado que permite criar um registro de exame. Para que a geração dos métodos get e set aconteça de forma automática, é necessário que os atributos sejam salvos como Property, mas quando essa opção é definida, o EA os coloca no diagrama de classes, o que não é necessário, pois são métodos que já fazem parte da classe, por isso, optou-se por não colocá-los no diagrama dos exemplos. 58 FIGURA 28 - Diagrama de classe de um laboratório de exames clínicos 4.2.4 Análise dos códigos gerados Esta análise é feita com base nos códigos gerados pela ferramenta CASE EA, a partir do diagrama de classes do exemplo 1 (figura 28). Destacam-se aqui, os códigos das classes Enfermeiro e Paciente, que apresentam os principais conceitos que são focos deste exemplo. Após a geração do código de cada classe na ferramenta CASE Enterprise Architect, foi criado um projeto no Netbeans e estes códigos foram colocados na pasta src (source) do projeto criado. O quadro 24 mostra o código gerado no EA da classe Enfermeiro. 1 2 3 4 QUADRO 24 - Código da classe Enfermeiro gerado no EA public class Enfermeiro extends Funcionario { private int coren; public Set _Exame; 59 5 6 7 8 9 10 11 12 } public Enfermeiro(){} public void finalize() throws Throwable { super.finalize();} public int getcoren(){ return coren;} public void setcoren(int newVal){ coren = newVal;} As definições da classe e a herança são geradas de forma correta, com a palavra extends, como mostra a linha 1 do quadro 24. A definição dos atributos (linhas 2 e 3), do método construtor (linha 5) e dos métodos para consulta e definição do valor deste atributo (get e set) (linhas 8 a 11), também foram realizadas corretamente pelo EA. Entretanto, para que o código desta classe compile, é necessário informar a qual projeto ela pertence, através da palavra package e do nome do projeto, como mostra a linha 1 do quadro 25. Este quadro mostra o código do quadro 24 com as alterações necessárias para compilar, neste caso, utilizando o Netbeans. O método destrutor avisa que o método finalize é subscrito, através da anotação @Override, como mostra a linha 10 do quadro 25. Quando existe uma associação para *, é necessário que seja implementada uma variável do tipo conjunto que em Java é representada pela palavra Set. O código gerado no EA não define a importação da classe Set, que é uma classe que faz parte da Collection do Java, por isso, é preciso importá-la como mostra a linha 2 do quadro 25. As associações são criadas, mas os métodos add e remove e seus variantes, não são gerados, o que seria de fundamental importância, para o bom funcionamento do código. Esses métodos foram criados manualmente através do editor de código presente no Netbeans, como mostram as linhas de 17 a 22 do quadro 25. 1 2 3 4 5 6 QUADRO 25 - Código da classe Enfermeiro corrigido para compilar package exemplo1; import java.util.Set; public class Enfermeiro extends Funcionario{ private int coren; public Set _Exame; 60 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public Enfermeiro(){} @Override public void finalize() throws Throwable{ super.finalize();} public int getcoren(){ return coren;} public void setcoren(int newVal){ COREN = newVal;} public void addExame(Exame ex){ this._Exame.add(ex);} public void removeExame(Exame ex){ this._Exame.remove(ex);} public Set getExame(){ return this._Exame;} } O quadro 26 mostra o código gerado no EA da classe Paciente. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 QUADRO 26 - Código da classe Paciente gerado no EA public class Paciente { private String nome; ... public Set _Exame; public Paciente(){} public void finalize() throws Throwable {} public String getnome(){ return nome; } public void setnome(String newVal){ nome = newVal; } ... } public int calculeIdade(){ return 0; } public void realizeExame(String nome){} } A criação da classe, dos atributos, do método construtor e dos métodos get e set, foi feita corretamente, semelhante à classe Enfermeiro, no quadro 24. Por isso, o nome do projeto ao qual esta classe pertence teve que ser informado. A importação da classe Set teve que ser feita manualmente como mostram as linhas 1 e 2 do quadro 27, que apresenta o código do quadro 25 com as alterações necessárias para compilar. 61 O método calculeIdade foi gerado corretamente, bem como o método realizeExame. Cabe ressaltar que através da classe Paciente é que o controlador pode enviar uma mensagem à classe Exame, de forma a criar uma instância de exame. Isto é feito através do método delegado realizeExame. A inclusão deste método na classe Paciente se justifica em virtude dos padrões de projeto: baixo acoplamento e não fale com estranhos, igualmente importantes para construção de sistemas com qualidade. O código gerado para a classe Paciente pode ser analisado no quadro 27. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 QUADRO 27 - Código da classe Paciente corrigido para compilar package exemplo1; import java.util.Set; public class Paciente { private String nome; ... public Set _Exame; public Paciente(){} @Override public void finalize() throws Throwable {} public String getnome(){ return nome;} public void setnome(String newVal){ nome = newVal;} ... public int calculeIdade(){ return 0;} public void realizeExame(String nome){} public void addExame(Exame ex){ this._Exame.add(ex);} public void removeExame(Exame ex){ this._Exame.remove(ex);} public Set getExame(){ return this._Exame;} } 4.3 Exemplo 2 Este exemplo apresenta o diagrama de classes referente ao mesmo contexto de um laboratório de exames clínicos mostrado no exemplo 1. Para a construção e desenvolvimento deste exemplo, considera-se o mesmo sumário executivo e a mesma relação de requisitos já listados no exemplo anterior, já 62 que o foco principal deste exemplo é abordar outros conceitos de orientação a objetos, são apresentados outros conceitos além dos já vistos, como: agregação compartilhada, agregação por composição, polimorfismo e interface. Além dos requisitos do exemplo 1, outros foram definidos para que seja possível apresentar novos conceitos de orientação a objetos, são eles: Manter informações de motor com o seguinte dado: nome; Manter informações sobre banheiro com os seguintes dados: descrição e nome; Manter informações de dois tipos de salas: espera e recuperação; Manter informações sobre a interface paciente; Manter informações sobre dois tipos de paciente: paciente animal ou paciente pessoa; Manter informações sobre relatório. 4.3.1 Diagrama de Classes O diagrama de classes da figura 29 foi derivado dos artefatos produzidos e já registrados no exemplo 1 deste capítulo, juntamente com os novos requisitos apresentados na seção anterior. Algumas classes não são mostradas no exemplo 2, pois não agregam nenhum conceito novo. O conceito de Interface pode ser visto na Interface Paciente e nas classes PacientePessoa e PacienteAnimal que implementam seus métodos. O polimorfismo está presente nas classes Sala, Espera e Recuperação, onde o método retorneSigla age de forma diferente em cada uma das classes derivadas de Sala. A agregação por compartilhamento existe entre as classes Equipamento e Motor, pois não pode haver um motor se não houver um equipamento. A agregação por composição existe entre as classes Sala e Banheiro, já que pode haver um banheiro dentro ou não da sala. 63 FIGURA 29 - Diagrama de classe de um laboratório de exames clínicos para pessoa/animal 4.3.2 Análise dos Códigos Gerados A análise feita nesta seção é similar a do exemplo 1. Nela destacam-se apenas os conceitos novos, os quais estão presentes nas classes Equipamento, Sala, Espera, Recuperação, PacienteAnimal, PacientePessoa e na interface Paciente. A partir destes códigos são analisados tanto os gerados automaticamente pelo EA e pelo UML Modeling para NetBeans quanto os criados manualmente no Netbeans. O quadro 28 mostra o código gerado no EA da classe Equipamento. 1 2 3 4 5 6 7 8 QUADRO 28 - Código da classe Equipamento gerado no EA public class Equipamento { private Date dataAquisicao; private String nome; public Set _Fornecedor; public Motor _Motor; public Equipamento(){} public Date getdataAquisicao(){ 64 9 10 11 12 13 14 15 16 return dataAquisicao;} public String getnome(){ return nome;} public void setdataAquisicao(Date newVal){ dataAquisicao = newVal;} public void setnome(String newVal){ nome = newVal;} } A definição dos atributos, método construtor e dos métodos para consulta e definição (get e set) ocorreram corretamente, de maneira igual ao exemplo 1. Da mesma forma, os erros registrados no exemplo 1 referentes ao nome do projeto e aos métodos para manipulação das associções (add e remove), também ocorreram no código gerado para este exemplo. O código gerado no EA também não define a importação da classe Date, por isso, é preciso importá-la como mostra a linha 2 do quadro 29. O EA não gera o código da agregação por compartilhamento, conforme orientações no capítulo 3, por isso foram criados os métodos setMotor e getMotor no Netbeans para mostrar de forma correta esta associação. Estes métodos são apresentados nas linhas 20 a 23 do quadro 29, bem como a associação existente entre fornecedor e equipamento como mostram as linhas 24 a 29 do quadro 29. As alterações necessárias para que o código presente no quadro 28 seja compilado, estão presentes no quadro 29. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 QUADRO 29 - Código da classe Equipamento corrigido para compilar package exemplo2; import java.util.Date; import java.util.Set; public class Equipamento { private Date dataAquisicao; private String nome; public Set _Fornecedor; public Motor _Motor; public Equipamento(){} public Date getdataAquisicao(){ return dataAquisicao;} public String getnome(){ return nome;} public void setdataAquisicao(Date newVal){ 65 17 18 19 20 21 22 23 24 25 26 27 28 29 30 dataAquisicao = newVal;} public void setnome(String newVal){ nome = newVal;} public void setMotor(Motor m){ this._Motor = m;} public Motor getMotor(){ return this._Motor;} public void addFornecedor(Fornecedor f){ this._Fornecedor.add(f);} public void removeFornecedor(Fornecedor f){ this._Fornecedor.remove(f);} public Set getFornecedor(){ return this._Fornecedor;} } O quadro 30 apresenta o código gerado pelo UML Modeling para NetBeans também para a classe Equipamento. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 QUADRO 30 - Código da classe Equipamento gerado no UML Modeling para NetBeans package exemplo2a; import java.util.Date; import java.util.Set; public class Equipamento { private Date dataAquisicao; private String nome; private Motor _Motor; private Set<Fornecedor> Fornecedores; public Equipamento () {} public Date getdataAquisicao () { return null;} public String getnome () { return null;} public void setdataAquisicao (Date val) {} public void setnome (String val) {} public Set<Fornecedor> getFornecedores () { return Fornecedores;} public void setFornecedores (Set<Fornecedor> val) { this.Fornecedores = val;} public Motor getMotor () { return Motor;} public void setMotor (Motor val) { this.Motor = val;} } Como o código é gerado no próprio NetBeans, a definição do projeto ao qual a classe está vinculada e a importação das bibliotecas necessárias ocorre de forma 66 correta, como mostram as linhas 1, 2 e 3. Ele também gera corretamente as definições da classe e dos atributos e o código gerado é compilável. O que não acontece de forma correta é que os métodos get dos atributos dataAquisição e nome, apresentados nas linhas 13 e 15, retornam o valor null no lugar do valor do atributo. Além disto, os métodos set dos mesmos atributos não fazem atribuição do parâmetro ao atributo da classe, linhas 16 e 17. Os métodos add e remove da associação fornecedor não foram criados. Em seu lugar, o UML Modeling para NetBeans criou o método setFornecedores que recebe uma lista de fornecedores para associar ao objeto, em vez de adicioná-los um a um na lista. O código gerado no EA para a classe Sala, que prevê um relacionamento de agregação compartilhada com a classe Banheiro, é mostrado no quadro 31. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 QUADRO 31 - Código da classe Sala gerado no EA public abstract class Sala { private String descricao; private String numero; public Set _Equipamento; public Set _Banheiro; public Sala(){} public String getdescricao(){ return descricao;} public String getnumero(){ return numero;} public abstract String retorneSigla(); public void setdescricao(String newVal){ descricao = newVal;} public void setnumero(String newVal){ numero = newVal;} } Neste código, destaca-se o método abstrato retorneSigla (linha 12), que foi gerado corretamente pelo EA, assim como o cabeçalho da classe, atributos e métodos get e set descritos anteriormente. Também neste exemplo percebe-se os mesmos erros em relação às associações já relatados nas outras classes, inclusive na agregação por compartilhamento, que é uma forma de associação. Assim como nos exemplos 67 anteriores, não foram gerados os métodos para manipulação da agregação (associação). Além disto, a importação da classe Set não foi definida e o nome do projeto não foi especificado. Essas correções foram feitas no Netbeans como mostra o quadro 32. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 QUADRO 32 - Código da classe Sala corrigido para compilar package exemplo2a; import java.util.Set; public abstract class Sala { private String descricao; private String numero; public Set _Equipamento; public Set _Banheiro; public Sala(){} public String getdescricao(){ return descricao;} public String getnumero(){ return numero;} public abstract String retorneSigla(); public void setdescricao(String newVal){ descricao = newVal;} public void setnumero(String newVal){ numero = newVal;} public void addEquipamento(Equipamento e){ this._Equipamento.add(e);} public void removeEquipamento(Equipamento e){ this._Equipamento.remove(e);} public Set getEquipamento(){ return this._Equipamento;} public void addBanheiro(Banheiro b){ this._Banheiro.add(b);} public void removeBanheiro(Banheiro b){ this._Banheiro.remove(b);} public Set getBanheiro(){ return this._Banheiro;} } O quadro 33 apresenta o código da classe Sala gerado no UML Modeling para NetBeans. No código desta classe, o método abstrato também foi gerado de forma correta, como mostra a linha 14. Os mesmos erros ocorridos anteriormente em relação aos métodos get e set, e a não criação dos métodos add e remove também fazem parte da geração do código desta classe. 68 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 QUADRO 33 - Código da classe Sala gerado no UML Modeling para NetBeans package exemplo2a; import java.util.Set; public abstract class Sala { private String descricao; private String numero; private Set<Equipamento> Equipamentos; private Set<Banheiro> Banheiros; public Sala () {} public String getdescricao () { return null;} public String getnumero () { return null;} public abstract String retorneSigla (); public void setdescricao (String val) {} public void setnumero (String val) {} public Set<Banheiro> getBanheiros () { return Banheiros;} public void setBanheiros (Set<Banheiro> val) { this.Banheiros = val;} public Set<Equipamento> getEquipamentos () { return Equipamentos;} public void setEquipamentos (Set<Equipamento> val) { this.Equipamentos = val;} } Entre as classes Sala, Espera e Recuperação, além da herança, existe polimorfismo, pois o método retorneSigla é um método abstrato na classe Sala e é implementado nas outras duas classes, com o mesmo nome, mas de formas diferentes. É importante ressaltar que neste contexto, o polimorfimo, pode ser verificado através da capacidade da classe Sala assumir a forma de uma das classes mais especializadas e assim invocar o método de acordo com a classe especializada através de sobreposição de método. O EA faz sua criação de forma correta como mostram os quadros 34 e 35 nas linhas 8 e 9, respectivamente. Estes quadros mostram o código gerado pelo EA para as classes Espera e Recuperação. 1 2 3 4 5 6 QUADRO 34 - Código da classe Espera gerado no EA public class Espera extends Sala { private int totalLugares; public Espera(){} public int gettotalLugares(){ return totalLugares;} 69 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 public String retorneSigla(){ return 0;} public void settotalLugares(int newVal){ totalLugares = newVal;} } QUADRO 35 - Código da classe Recuperação gerado no EA public class Recuperacao extends Sala { private float temperatura; public Recuperacao(){} public float gettemperatura(){ return temperatura;} public String retorneSigla(){ return 0;} public void settemperatura(float newVal){ temperatura = newVal;} } O método retorneSigla teve que ser implementado no Netbeans, para mostrar de forma mais clara o conceito de polimorfismo, como mostram as linhas 9 e 10 dos quadros 36 e 37. 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 QUADRO 36 - Código da classe Espera corrigido para compilar package exemplo2a; public class Espera extends Sala { private int totalLugares; public Espera(){} public int gettotalLugares(){ return totalLugares;} public String retorneSigla(){ return "ESP" + this.getnumero();} public void settotalLugares(int newVal){ totalLugares = newVal;} } QUADRO 37 - Código da classe Recuperação corrigido para compilar package exemplo2a; public class Recuperacao extends Sala { private float temperatura; public Recuperacao(){} public float gettemperatura(){ return temperatura;} public String retorneSigla(){ return "REC" + this.getnumero();} public void settemperatura(float newVal){ temperatura = newVal;} 70 12 } Os quadros 38 e 39 mostram os códigos gerados no UML Modeling para NetBeans, das classes Espera e Recuperação. Nesses códigos a herança foi gerada de forma correta, como mostra a linha 2 de ambos os quadros, bem como o cabeçalho do método polimórfico retorneSigla, ficando para o programador a tarefa de desenvolvêlo, mostrado na linha 8 dos dois quadros. Os erros registrados anteriormente também ocorreram na geração do código destas classes, em relação aos métodos get e set. 1 2 3 4 5 6 7 8 9 10 QUADRO 38 - Código da classe Espera gerado no UML Modeling para NetBeans package exemplo2a; public class Espera extends Sala { private int totalLugares; public Espera () {} public int gettotalLugares () { return 0;} public String retorneSigla () { return null;} public void settotalLugares (int val) {} } 1 2 3 4 5 6 7 8 9 10 QUADRO 39 - Código da classe Recuperação gerado no UML Modeling para NetBeans package exemplo2a; public class Recuperacao extends Sala { private float temperatura; public Recuperacao () {} public float gettemperatura () { return 0.0f;} public String retorneSigla () { return null;} public void settemperatura (float val) {} } Outro conceito importante relacionado a orientação a objetos é o de interface. Para tanto, neste exemplo, criou-se uma interface Paciente cujo objetivo é facilitar a tarefa do programador em relação as alterações necessárias para que o sistema possa ser utilizado tanto para um laboratório de pessoas quanto de animais. O quadro 40 mostra o código da interface Paciente gerado no EA. 71 1 2 QUADRO 40 - Código da interface Paciente gerado no EA public interface Paciente { public int calculeIdade();} O código da interface Paciente foi gerado de forma correta pelo EA e pelo UML Modeling para NetBeans, por isso não foi necessário criar o quadro dessa interface corrigido para ser compilado. O quadro 41 mostra o código da classe PacienteAnimal gerado no EA, o qual está correto. Esta classe implementa a interface Paciente com a palavra implements, na linha 1. 1 2 3 4 5 6 7 QUADRO 41 - Código da classe PacienteAnimal gerado no EA public class PacienteAnimal implements Paciente { private Set _Exame; private Pessoa _Pessoa; public PacienteAnimal(){} public int calculeIdade(){} } Na classe PacienteAnimal, os mesmos erros anteriores ocorreram na geração do código no EA em relação ao nome do pacote, importação da classe Set, implementação dos métodos de associação, como podem ser vistos no quadro 42, linhas 1, 2 e 10 a 20. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 QUADRO 42 - Código da classe PacienteAnimal corrigido para compilar package exemplo2a; import java.util.Set; public class PacienteAnimal implements Paciente { public Set _Exame; public Pessoa _Pessoa; public PacienteAnimal(){} public int calculeIdade(){return 0} public void addExame(Exame e){ this._Exame.add(e);} public void removeExame(Exame e){ this._Exame.remove(e);} public Set getExame(){ return this._Exame;} public void setPessoa(Pessoa p){ this._Pessoa= p;} 72 18 19 20 public Pessoa getPessoa(){ return this._Pessoa;} } O quadro 43 mostra o código da classe PacienteAnimal gerado no UML Modeling para NetBeans. Nesta classe, os erros em relação a não criação dos métodos add e remove também ocorreram. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 QUADRO 43 - Código da classe PacienteAnimal gerado no UML Modeling para NetBeans package exemplo2a; import java.util.Set; public class PacienteAnimal implements Paciente { private Pessoa Proprietario; private Set<Exame> Exames; public PacienteAnimal () {} public int calculeIdade () { return 0;} public Set<Exame> getExames () { return Exames;} public void setExames (Set<Exame> val) { this.Exames = val;} public Pessoa getProprietario () { return Proprietario;} public void setProprietario (Pessoa val) { this.Proprietario = val;} } Como o código da classe PacientePessoa foi gerado de forma semelhante ao da classe PacienteAnimal, não houve a necessidade de apresentá-lo. 4.4 Conclusão Este capítulo mostrou como as ferramentas CASE EA e UML Modeling para NetBeans fazem a geração do código a partir de um diagrama de classes. Um breve tutorial foi criado para ensinar quais passos devem ser seguidos para que a ferramenta EA fique habilitada a gerar o código. Tal passo não foi necessário com o UML Modeling para NetBeans, pelo fato deste processo ser bastante simples de ser executado por qualquer pessoa que tenha um conhecimento mínimo sobre o NetBeans. 73 A partir do código gerado e dos estudos dos conceitos de orientação a objetos foi possível identificar quais conceitos a ferramenta gera corretamente e em quais deixa a desejar. Foram elaborados dois exemplos. O primeiro aborda apenas os conceitos mais simples, como: classes, atributos e herança. O diagrama deste exemplo foi desenvolvido no EA e o próximo passo foi colocar o código gerado no Netbeans para verificar sua consistência, fazendo as alterações necessárias para que o código ficasse da forma correta e pudesse compilar. O EA gerou de forma correta as definições de classe, atributos, método construtor e herança. Porém, ele não define a importação de classes que fazem parte da Collection do Java, como Set e Date. Cria associações, mas não cria os métodos para manipular associações entre as classes (associa, desassocia). O segundo exemplo abordou outros conceitos como interface, polimorfismo, agregação compartilhada e agregação por composição. Este exemplo foi criado no EA e, também, no UML Modeling para NetBeans. Da mesma forma, os códigos gerados foram colocados no NetBeans e alterados para que compilassem. Neste exemplo, o EA apresentou os mesmos problemas relatados no exemplo1. No UML Modeling para NetBeans, os métodos get dos atributos retornam sempre valor null ao invés do valor do atributo. Os métodos set destes mesmos atributos não fazem atribuição do parâmetro ao atributo da classe. Os métodos adiciona e remove também não foram criados por esta ferramenta. Percebeu-se, com o uso destas duas ferramentas CASE, que elas facilitam o trabalho de desenvolvedores na tarefa de geração de código, embora ambas gerem erros em seus códigos. 74 5 CONSIDERAÇÕES FINAIS O principal objetivo deste trabalho foi estudar a geração de código orientado a objetos em Java a partir de um diagrama de classes. O estudo realizado sobre ferramentas CASE foi de fundamental importância para conhecer melhor as principais características de cada uma delas, dando ao desenvolvedor uma noção das atividades possíveis de serem realizadas de acordo com sua necessidade. Dentre as características destaca-se a engenharia reversa, o suporte a XMI, qual linguagem de modelagem utiliza, tem suporte a quais diagramas, em qual sistema operacional pode ser utilizada, etc. Este estudo foi demorado e trabalhoso, pois exigiu uma ampla pesquisa em sites das próprias ferramentas e em artigos e livros, para esclarecer vários aspectos das mesmas, além da instalação e uso das ferramentas. As ferramentas CASE agilizam o trabalho dos desenvolvedores, pois a partir de uma análise e de um projeto bem feitos, a geração de código torna-se um processo mais rápido e menos complexo. A ferramenta Umbrello pode ser utilizada apenas no sistema operacional Linux, o que dificultou em alguns pontos o estudo, pois foi necessário instalar este sistema operacional para então fazer alguns testes. No estudo sobre UML Modeling para NetBeans, observou-se que as ferramentas CASE estão cada vez mais fazendo parte das próprias ferramentas de programação. Isto facilita o trabalho do desenvolvedor, pois pode-se usar vários recursos em uma mesma ferramenta de desenvolvimento. A tradução de diagramas de classe para Java teve como base o trabalho proposto por Wazlawick (2004), que explica de forma simples e objetiva este processo. Alguns conceitos como polimorfismo e interface não são abordados por este 75 autor, por isto houve a necessidade de consultar outras referências para que o processo pudesse ser apresentado de forma mais completa. Todos os exemplos mostrados durante a explicação do processo foram estudados e compilados usando a IDE Netbeans para que houvesse coerência entre a teoria e prática. Com isto, foi possível compreender melhor os conceitos de orientação a objetos vistos durante o curso, bem como suas relações com os conceitos existentes em um diagrama de classes. Elaborou-se um tutorial simples sobre o EA, apresentando um conjunto de passos a ser seguido para que a geração de código ocorra de forma correta. Esta etapa foi importante, pois possibilitou que a última atividade prevista no trabalho, geração e análise dos códigos, pudesse ser concluída. Para analisar os códigos gerados, foram elaborados dois exemplos envolvendo um laboratório de exames clínicos para pessoas ou animais. Com base neste contexto, desenvolveu-se diagramas de classes usando as ferramentas CASE EA e UML Modeling para NetBeans. A partir desses diagramas foi gerado o código e o mesmo foi colocado no Netbeans para sua verificação e ajustes necessários. Como o diagrama de classes foi elaborado primeiro no EA, foram encontradas dificuldades no momento de exportá-lo para o UML Modeling para NetBeans, pois o NetBeans não possui suporte a XMI. A solução encontrada, foi a utilização de engenharia reversa, a partir do código que já havia sido compilado no NetBeans. Com a utilização deste recurso, o diagrama foi criado no UML Modeling para NetBeans, mas algumas associações foram geradas de forma incorreta e outras não foram geradas, o que teve que ser arrumado. Outra dificuldade foi a elaboração do diagrama, já que torna-se complicado inserir os conceitos estudados em algo do mundo real. Para que os exemplos refletissem uma situação real, algumas pessoas tiveram que ser consultadas para que os conceitos pudessem ser melhor aplicados. Todos os objetivos específicos propostos foram cumpridos, alcançando assim, o objetivo principal do trabalho. O trabalho como um todo, contribuiu para um melhor esclarecimento das 76 funcionalidades de algumas ferramentas CASE, melhor entendimento de orientação a objetos e dos códigos gerados pelas duas ferramentas CASE. As duas ferramentas utilizadas para a elaboração do diagrama e, consequentemente, a geração do seu código (EA e UML Modeling para NetBeans) apresentaram falhas, sendo necessária a intervenção do desenvolvedor para que o código compile corretamente. Por fim, como trabalhos futuros, sugere-se propor um padrão para a geração de códigos automática pelas ferramentas CASE independente de tecnologias. Existe uma falta de integração entre programadores e analistas no que diz respeito a alguns conceitos de orientação a objetos, passando a impressão de que cada um está focado apenas na sua especialidade, não se preocupando com o trabalho como um todo. 77 REFERÊNCIAS BIBLIOGRÁFICAS ALBUQUERQUE, F. Programação Orientada a Objetos usando Java e UML. Brasília: MSD, 1999. 218 p. BARRÉRE, T. S.; PRADO, A. F.; BONAFE, V. C. CASE Orientada a Objetos com Múltiplas Visões e Implementação Automática de Sistemas – MVCASE. In: SIMPÓSIO BRASILEIRO DE ENGENHARIA DE SOFTWARE - SBES, 13., 1999. Florianópolis, Santa Catarina, Brasil. Anais... Florianópolis: UFSC/SBC, 1999. Disponível em: <http://www.inf.ufsc.br/~sbes99/anais/SBES-Completo>. Acessado em: 22 fev. 2008. BARNES, D. J.; KÖLLING, M. Programação Orientada a Objetos com Java – Uma Introdução Prática Usando o BlueJ. São Paulo: Pearson Prentice Hall, 2004. 368 p. BARTH, C. Interfaces – Trabalhando com Interfaces. GUJ – Fórum Brasileiro sobre Java. Disponível em: <http://www.guj.com.br/java.tutorial.artigo.123.1.guj>. Acessado em: 22 set. 2008. BLANCO, M. Z. Introdução Orientação Objetos. Site que apresenta apostilas que mostram alguns conceitos para a criação de softwares. Disponível em: <http://pinga.eep.br/~mblanco/oo.doc>. Acessado em: 27 maio. 2008. BOGGS, W.; BOGGS, M. UML Com Rational Rose 2002 - A Bíblia. Rio de Janeiro: Alta Books, 2002. 627 p. ESRI. CASE Tools MXI Update. ESRI – Support Center. Site que disponibiliza download para ferramenta Rational Rose. Disponível em: <http://support.esri.com/index.cfm?fa=downloads.patchesServicePacks.viewPatch&PI D=43&MetaID=164>. Acessado em: 05 abr. 2008. GOMES, H. F. ArgoUML. Dicas Sou Java. Texto que apresenta características da ferramenta CASE ArgoUML . Disponível em: <http://www.mundooo.com.br/php/modules.php?name=News&file=article&sid=340>. Acessado em: 04 abr. 2008. GUSTAFSON, D. A. Engenharia de Software. Porto Alegre: Bookman, 2003. 207 p. IBM. UML Modeling - Rational Rose Enterprise. Site oficial da ferramenta CASE Rational Rose. Disponível em: 78 <http://www.306.ibm.com/software/awdtools/developer/rose/enterprise/features/index. html?S_CMP=wspace>. Acessado em: 05 abr. 2008. JUDE. Jude System Design Tool. Site oficial da ferramenta CASE JUDE. Disponível em: <http://jude.change-vision.com>. Acessado em: 20 out. 2007. KATÁLOGO. Enterprise Architect. Texto que apresenta características da ferramenta CASE EA. Disponível em: <http://www.katalogo.com.br/Produtos/?IdProduto=CAT4260001-0>. Acessado em: 28 mar. 2008. MOMBACH, D. A. Enterprise Architect. In: ENCONTRO DA CIÊNCIA E TECNOLOGIA - ECTEC, 4., 2005, Lages, Santa Catarina, Brasil. Anais... Lages: UNIPLAC, 2005. NETBEANS. IDE Java. Site com as principais características e download do NetBeans. Disponível em: < http://www.netbeans.org > Acessado em: 23 out. 2008. NOVATEC. Capítulo 1 – As Origens. Capítulo que cita algumas características da programação estruturada, modular e orientada a objetos. Disponível em: <http://novatec.com.br/livros/poa/capitulo857522087X.pdf>. Acessado em: 11 jun. 2008. OMG. Catalog of OMG Modeling and Metadata Specifications. Object Management Group. Site que contém um catálogo de especificações de algumas ferramentas de modelagem. Disponível em: <http://www.omg.org/technology/documents/modeling_spec_catalog.htm#XMI>. Acessado em: 05 abr. 2008. PELOSO, V. Ferramentas CASE: Implementação de um Protótipo para Manutenção de Banco de Dados. Monografia defendida na Universidade São Francisco, Itatiba, São Paulo, 2004. PORTAL JAVA. Jude Community – Ferramenta Case. Site do portal Java. Disponível em: <http://www.portaljava.com.br/home/modules.php?name=News&file=print&sid=1337 >. Acessado em: 17 mar. 2008. PRESSMAN, R. S. Software Engineering: A Practitioner’s Approach. 5th ed. Nova York: Mc Graw–Hill, 2001. 860 p. SANTOS, R. Introdução à Programação Orientada a Objetos Usando Java. Rio de Janeiro: Campus, 2003. 319 p. SILVA, E. L.; MENEZES, E. M. Metodologia da Pesquisa e Elaboração de Dissertação. 4. ed. Florianópolis: UFSC, 2005. 79 SILVA, M.; ROCHA, T. Projeto de uma Ferramenta CASE Utilizando a Notação da UML e a Metodologia de COAD & YOURDON. Belém do Pará, CESUPA, 1998. SPARX SYSTEMS. Sparx Systems Enterprise Architect. Site oficial da ferramenta CASE Enterprise Architect. Disponível em: <http://www.sparxsystems.com>. Acessado em: 04 abr. 2008. TIGRIS.ORG. Open Source Software Engineering Tools. Site oficial da ferramenta CASE ArgoUML. Disponível em: <http://www.tigris.org/>. Acessado em: 05 abr. 2008. UMBRELLO UML MODELLER. Umbrello UML Modeller. Site oficial da ferramenta CASE Umbrello UML Modeller. Disponível em: <http://uml.sourceforge.net/index.php>. Acessado em: 05 abr. 2008. VIEIRA, M. J. Umbrello UML Modeller. Texto com características da ferramenta CASE Umbrello UML Modeller. Disponível em: <http://www.ambientelivre.com.br/index.php?option=com_content&task=view&id=3 9>. Acessado em: 29 mar. 2008. WAZLAWICK, R. S. Análise e Projeto de Sistemas de Informação Orientados a Objetos. Rio de Janeiro: Elsevier, 2004. 298 p. 80 BIBLIOGRAFIA COMPLEMENTAR BARROS, J. P. Um Pouco de Diagrama de Classes. Notas de aula. Instituto Politécnico de Beja. Beja: Escola Superior de Tecnologia e Gestão, Portugal. Disponível em: <http://www.estig.ipbeja.pt/~jpb/textos/diagramasDeClasses.pdf>. Acessado em: 03 mar. 2008. BOAGLIO. Configurando o Oracle Designer 10g. Tutorial sobre como configurar o Oracle Designer. Disponível em: <http://www.boaglio.com/index.php/configurando-ooracle-designer-10g>. Acessado em: 17 mar. 2008. BOING, H. Bases Metodológicas para Construção de Ferramentas Computacionais para Programas Educacionais de Caráter Social. 2003. 204 f. Tese (Doutorado em Engenharia de Produção) - Programa de Pós-Graduação em Engenharia de Produção, Universidade Federal de Santa Catarina, Florianópolis. ISSA, L. Desenvolvimento de Interface com Usuário Dirigida por Modelos com Geração Automática de Código. 2006. 104 f. Dissertação (Mestrado em Ciência da Computação) - Programa de Pós-Graduação em Ciência da Computação, Universidade Federal de Minas Gerais, Belo Horizonte. MIYASHIRO, M. A. S. Introdução ao Rational Rose. São Paulo: Ciência Moderna, 2006. 128 p. MORAES, J. L.C.; PRADO, A. F. Geração Automática de Código Delphi a partir de Especificações em Catalysis. In: CONFERÊNCIA LATINO AMERICANA DE INFORMÁTICA (CLEI), 27., 2001, Mérida, Venezuela. Proceedings... Mérida: CLEI, 2001. Disponível em: <http://www.recope.dc.ufscar.br/ engenhariadesoftware/publicacoes/correctpaperclei.zip>. Acessado em: 03 mar. 08. PFLEEGER, S. L. Engenharia de Software Teoria e Prática. São Paulo: Prentice Hall, 2004. 535 p. SOUZA, A. P. Engenharia de Sistemas Computacionais: Uma Proposta de Mapeamento de Modelos UML para Linguagem Java. 2000. 114 f. Dissertação (Mestrado em Ciência da Computação) – Programa de Pós-Graduação em Ciência da Computação, Universidade Federal de Santa Catarina, Florianópolis. STEINMACHER, I. et al. GeCA: Uma Ferramenta de Engenharia Reversa e Geração Automática de Código. In: SIMPÓSIO BRASILEIRO DE SISTEMAS DE INFORMAÇÃO, 3., 2006, Curitiba, Paraná, Brasil. Anais... Curitiba: SBC, 2006. 81 Disponível em: <http://igor.pro.br/publica/papers/SBSI06.pdf>. Acessado em: 19 fev. 2008. VERONESE, G. et al. ARES: Uma Ferramenta de Engenharia Reversa Java -UML. In: SIMPÓSIO BRASILEIRO DE ENGENHARIA DE SOFTWARE - SBES, 16., 2002, Gramado, Rio Grande do Sul, Brasil. Anais... Gramado: SBC, 2002. Disponível em: <http://www.lbd.dcc.ufmg.br/dbdcomp/servlet/Trabalho?id=5265>. Acessado em: 03 mar. 2008. APÊNDICES APÊNDICE A - ARTIGO ...........................................................................................83 APÊNDICE A - ARTIGO Processo de Geração de Código em Java a partir de um Diagrama de Classes Mariana C. de Bem C. Branco1, Alexandre Perin de Souza1 1 Sistemas de Informação - Departamento de Ciências Exatas e Tecnológicas Universidade do Planalto Catarinense (UNIPLAC) – Lages, SC – Brasil {nanacbcb,perin}@uniplac.net Abstract. This paper deals with the code generation in Java, based on class diagrams. It presents a brief study about CASE tools and shows details about how Java code must be written based on such diagrams. It also presents a class diagram about a laboratory of clinic exams, which is used to generate the code by means of Enterprise Architect and UML Modeling para NetBeans. The codes generated were compiled and analyzed aiming at verifying if the codes were correct and complet or not. The generated code`s analysis showed some problems, because both tools don’t work correctly in code generation process. So, the conclusion is that CASE tools are important to speed up the implementation job, although they are not able to accomplish completely the generation code without the human intervention. Resumo. Este artigo trata da geração de código orientado a objetos em Java a partir de um diagrama de classes. Ele apresenta um estudo sobre ferramentas CASE e detalha como deve ser desenvolvido o código em Java a partir de um diagrama de classes. Também apresenta um diagrama sobre um laboratório de exames clínicos, a partir do qual os códigos foram gerados no Enterprise Architect e no UML Modeling para NetBeans. Estes códigos foram compilados e analisados, com o intuito de verificar se estavam corretos e completos. Com a análise verificou-se a existência de problemas, pois as duas ferramentas falharam em alguns pontos, o que leva à conclusão que as ferramentas CASE são úteis para agilizar o trabalho de codificação, mas ainda não são capazes de realizar integralmente o trabalho. 1. Introdução A Engenharia de Software é uma disciplina que integra processos, métodos e ferramentas para o desenvolvimento de software [PRESSMAN 2001], buscando resolver os problemas com eficácia para criar softwares com qualidade. Ela foi dividida em várias áreas para melhor atingir seus objetivos. Uma destas áreas é a de Ferramentas e Ambientes de Desenvolvimento de Software, a qual tem recebido especial atenção nos últimos anos, devido a sua natural evolução. Sua finalidade está em agilizar e organizar a produção e manutenção dos diversos artefatos envolvidos na elaboração de um software. Para que o desenvolvimento do sistema ocorra com maior eficiência, existem diversas ferramentas que auxiliam neste processo, chamadas de ferramentas CASE (Computer-Aided Software Engineering). Uma atividade possível de ser feita através do uso de ferramenta CASE é a criação de diagramas com base na notação UML (Unified Modeling Language). Dentro da UML, que é uma linguagem de modelagem para visualizar, especificar, documentar e desenvolver sistemas, existem diversos diagramas. Dentre eles, está o diagrama de classes que, segundo Barnes e Kölling (2004), mostra as classes de uma aplicação e os relacionamentos entre elas, fornece as informações sobre o código-fonte e apresenta a visualização estática de um programa. Uma vez definido o diagrama de classes, pode-se realizar a geração de código automática para uma determinada linguagem de programação usando uma ferramenta CASE. Em alguns casos o resultado deste processo é insatisfatório, pois nem sempre há consistência entre ambos. Diante do exposto, este artigo visa apresentar os problemas existentes na geração automática de código realizada por ferramentas CASE. Sendo assim, o principal objetivo é analisar a geração de código a partir de diagrama de classes através de ferramenta CASE para a linguagem de programação Java. Para realizar esta tarefa, foram seguidas algumas etapas como: explorar as principais ferramentas CASE do mercado, de forma a apresentar suas principais características e, após selecionar algumas ferramentas, gerar código automaticamente em Java para verificar sua consistência. Para que estas etapas fossem concluídas, primeiro foi feito um estudo sobre algumas ferramentas CASE em livros e materiais disponíveis na Internet. O objetivo deste estudo foi compreender as principais características das mesmas e selecionar duas ferramentas para realizar os testes sobre a geração de código. Em seguida, foi estudado o processo de tradução de um diagrama de classes para Java com o intuito de compreender de forma mais aprofundada este processo, para que fosse possível fazer a análise dos códigos gerados pelas ferramentas CASE. A execução deste passo foi baseada na proposta de geração de código descrita por Wazlawick (2004). O passo seguinte foi a elaboração de um diagrama de classes sobre um laboratório de exames clínicos fictício, abordando conceitos como: classes, atributos, métodos, associações, herança, polimorfismo, interface, entre outros. A geração de código automática foi realizada usando duas ferramentas CASE, Enterprise Architect [SPARX SYSTEMS 2008] e UML Modeling para NetBeans. Os códigos gerados foram compilados no Netbeans para a verificação da sua sintaxe e a análise de sua lógica foi realizada identificando se os códigos gerados estavam de acordo com o estudo realizado sobre o processo de tradução de um diagrama de classes em código, apresentado por Wazlawick (2004). Além desta apresentação, este artigo está organizado da seguinte maneira: na seção 2 apresenta-se um estudo sobre ferramentas CASE; a seção 3 trata da consistência dos códigos gerados pelas ferramentas Enterprise Architect e UML Modeling para NetBeans, mostrando soluções para os códigos inconsistentes. Por fim, a seção 4 mostra as considerações finais. 2. Ferramentas CASE Juntamente com a evolução da Engenharia de Software surgiram as ferramentas CASE, que auxiliam os desenvolvedores no processo de criação de software, melhorando, assim, a qualidade dos mesmos. As ferramentas CASE dão suporte computacional ao desenvolvedor ao longo do ciclo de vida da criação de sistemas, reduzindo o tempo total de desenvolvimento [SILVA e ROCHA 1998]. Elas são de suma importância também para a manutenção do software, auxiliando, assim, em todo o processo de desenvolvimento (Gerência, Análise, Projeto, Implementação, Teste e Manutenção) [PELOSO 2004]. Através das ferramentas CASE é possível modelar o sistema antes de escrever o seu código, o que possibilita a detecção de falhas de projeto no seu início, sendo este o período mais fácil para corrigi-las [BOGGS e BOGGS, 2002] Existem diversas ferramentas CASE no mercado, cada uma com características próprias, como a linguagem de modelagem utilizada, linguagem para a geração de código e diagramas que podem ser criados. Após a instalação e uso de seis ferramentas CASE, JUDE, Enterprise Architect, Rational Rose, Umbrello UML Modeler, Argo UML e UML Modeling para NetBeans, identificou-se suas principais características, como tipo de distribuição, utilização de engenharia reversa, quais diagramas gera, as quais são apresentadas na tabela 1. Tal estudo tem como objetivo compreender melhor os recursos das ferramentas e escolher duas delas para serem utilizadas na seção 3, de forma a criar o diagrama de classes e, a partir dele, fazer a geração de código automática. Tabela 1. Resumo de características das ferramentas CASE Características JUDE Distribuição Proprietária e Livre Proprietária Proprietária Livre Livre Livre Engenharia Reversa Sistema Operacional Sim Sim Sim Sim Sim Sim Todos Windows (9x, NT, ME, 2000, XP), Linux Caso de Uso, Classe, de Seqüência, Atividade, Objeto, Componente, Distribuição e Estado Windows (9x, NT, ME, 2000, XP) Casos de Uso, Classe, Componente, Desenvolvimento, Objetos, Seqüência, Colaboração, Estado e Atividades C++, C#, Ada, CORBA, Java, PHP, Visual Basic, XML, .Net Linux, Unix, FreeBSD, e Solaris Caso de Uso, Classe, Seqüência, Colaboração, Atividade, Componente, Estado e Distribuição Windows 95, 98, 2000, NT ActionScript, Ada, C++, IDL (Corba), Java, SQL, JavaScript, Perl, PHP, Python, Ruby, TCL, XML Schema C++, C#, Java, PHP Windows, Linux, Mac OS e Solaris Caso de Uso, Seqüência,Atividade,Classe, Colaboração, Componente,Implantação e Estado Java Diagramas UML Suportados Gera Código em quais Linguagens de Programação Caso de Uso, Classe, Seqüência, Colaboração, Atividade, Componente, Desenvolvimento e Estado. Java Enterprise Architect C++, Java, C#, Visual Basic, PHP, VB .Net, Delphi Rational Rose Umbrello ArgoUML Caso de Uso, Seqüência, Atividade, Classe, Colaboração, Distribuição e Estado UML Modeling para NetBeans Suporte a XMI Versão Trial Sim2 Sim Sim, na versão Professional Sim Sim, com o uso de ferramentas complementares Sim Sim Sim Não Não se aplica Não se aplica Não se aplica Através do estudo realizado sobre ferramentas CASE, as escolhidas para criação do diagrama de classes e geração do código foram o EA, que é uma ferramenta proprietária e o UML Modeling para NetBeans, que é livre. Outra diferença significativa entre elas é que a primeira é uma ferramenta destinada apenas para modelagem e a segunda é uma ferramenta integrada a um ambiente de desenvolvimento. Como ambas são ferramentas bastante utilizadas e com características bem distintas, optou-se por realizar os testes com elas para verificar se as diferenças entre os resultados gerados são significativas. 3. Análise de código gerado a partir de diagrama de classes Esta seção apresenta um diagrama de classes desenvolvido nas ferramentas CASE EA e UML Modeling para NetBeans, contendo diversos conceitos de orientação a objetos, como classes, atributos, métodos, herança, polimorfismo, interface, e outros, como mostra a figura 1. A partir deste diagrama, é gerado o código de forma automática pelas duas ferramentas já citadas e algumas sugestões para corrigir os códigos gerados de forma inconsistente são apresentadas, com base no estudo feito sobre geração de código orientada a objetos a partir de um diagrama de classes. É proposto o desenvolvimento de um sistema para o controle de um laboratório de exames clínicos, que informatizará as funções de cadastros de funcionário, paciente, sala, banheiro, fornecedor, o controle de equipamentos e tipos de exames que cada paciente pode realizar. O objetivo do sistema é agilizar o processo de cadastros, garantindo assim um melhor controle de todas as informações manipuladas no âmbito do laboratório. O código da classe Sala gerado pelo EA é mostrado na tabela 2. Esta é uma classe abstrata e sua definição foi feita de forma correta, como mostra a linha 1. O EA também gerou de forma correta os atributos, associações, método construtor, métodos get e set e a declaração do método RetorneSigla. Alguns atributos e associações existentes no diagrama, como Número e Banheiro, foram omitidos devido ao espaço, mas a geração destes códigos ocorreu de forma igual aos apresentados na tabela. Tabela 2. Código da classe Sala gerado no EA 1 2 3 4 5 6 7 8 9 10 2 public abstract class Sala { private String Descricao; public Set _Equipamento; public Sala(){} public String getDescricao(){ return Descricao;} public abstract String RetorneSigla(); public void setDescricao(String newVal){ Descricao = newVal;} } Apenas na versão JUDEProfessional. A tabela 3 mostra o código da classe Sala corrigido para compilar no NetBeans. Algumas alterações foram feitas, como a inclusão do nome do pacote ao qual a classe pertence (linha 1), a importação da classe Set (linha 2), que é uma classe que faz parte da Collection do Java, e a inclusão dos métodos de associação adiciona, remove e getEquipamento (linhas 12 a 17), que fazem a manipulação da associação existente entre as classes Sala e Equipamento. Figura 1. Diagrama de classe de um laboratório de exames clínicos para pessoa/animal Tabela 3. Código da classe Sala corrigido para compilar no Netbeans 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package exemplo2a; import java.util.Set; public abstract class Sala { private String Descricao; public Set _Equipamento; public Sala(){} public String getDescricao(){ return Descricao;} public abstract String RetorneSigla(); public void setDescricao(String newVal){ Descricao = newVal;} public void adicionaEquipamento(Equipamento e){ this._Equipamento.add(e);} public void removeEquipamento(Equipamento e){ this._Equipamento.remove(e);} 16 17 18 public Set getEquipamento(){ return this._Equipamento;} } A tabela 4 mostra o código da classe Sala gerado no UML Modeling para NetBeans. Neste código, é gerado de forma correta o nome do projeto, as importações, a classe abstrata, definições de atributos, associações, método construtor e método RetorneSigla. Os métodos get dos atributos e das associações estão incorretos, retornando valor null no lugar do valor do atributo. Além disto, os métodos set dos mesmos atributos não fazem atribuição do parâmetro ao atributo da classe, como mostra a linha 10. Tabela 4. Código da classe Sala gerado no Uml Modeling para NetBeans 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package exemplo2a; import java.util.Set; public abstract class Sala { private String Descricao; private Set<Equipamento> Equipamentos; public Sala () {} public String getDescricao () { return null;} public abstract String RetorneSigla (); public void setDescricao (String val) {} public Set<Equipamento> getEquipamentos () { return Equipamentos;} public void setEquipamentos (Set<Equipamento> val) { this.Equipamentos = val;} } Percebe-se que o UML Modeling para NetBeans por estar incorporado no ambiente de desenvolvimento possui algumas vantagens como definir o projeto ao qual a classe está vinculada, bem como as classes a serem importadas no projeto. Entretanto, ele peca em alguns aspectos básicos como a geração dos códigos dos métodos get e set que são feitos corretamente pelo EA. Sobre os métodos para manipulação das associações, percebe-se que nenhuma das ferramentas geram corretamente. O código da classe Espera, derivada da classe Sala, corrigido para compilar no NetBeans é mostrado na tabela 5. Os códigos gerados pelo EA e pelo UML Modeling para NetBeans não foram apresentados nesta seção devido ao fato das duas ferramentas gerarem o código quase da mesma forma, definindo a classe e sua herança corretamente, mas possuindo os erros já citados anteriormente em relação aos métodos get e set e os métodos das associações. Tabela 5. Código da classe Espera corrigido para compilar no Netbeans 1 2 3 4 5 6 package exemplo2a; public class Espera extends Sala { ... public String RetorneSigla(){ return "ESP" + this.getNumero();} } Entre as classes Sala, Espera e Recuperação, além da herança, existe polimorfismo, pois o método RetorneSigla é um método abstrato na classe Sala que deve ser implementado nas outras duas classes, com o mesmo nome, mas de formas diferentes. É importante ressaltar que neste contexto, o polimorfimo pode ser verificado através da capacidade da classe Sala assumir a forma de uma das classes mais especializadas e assim invocar o método de acordo com a classe especializada através de sobreposição de método. A implementação do método RetorneSigla é mostrada nas linhas 4 e 5. A tabela 6 mostra o código da interface Paciente gerado pelo EA. Tanto o EA quanto o UML Modeling para NetBeans geraram o código da interface de forma correta. Tabela 6. Código da interface Paciente gerado no EA. 1 2 Public interface Paciente { public int CalculeIdade();} O código da classe PacienteAnimal, que implementa a interface, gerado pelo EA é mostrado na tabela 7. Percebe-se que o cabeçalho da classe foi definido corretamente, mas os mesmos erros anteriores ocorreram em relação ao nome do pacote, importação da classe Set e implementação dos métodos de associação. Da mesma forma, o UML Modeling para NetBeans gerou o cabeçalho da classe de forma correta, mas com os mesmos erros em relação a não criação dos métodos para manipulação das associações. Tabela 7. Código da classe PacienteAnimal gerado no EA 1 2 3 4 5 public class PacienteAnimal implements Paciente { public Set _Exame; public PacienteAnimal(){} public int CalculeIdade(){} } 4. Conclusão O principal objetivo deste trabalho foi estudar a geração de código orientado a objetos em Java a partir de um diagrama de classes. O estudo realizado sobre ferramentas CASE foi de fundamental importância para conhecer melhor as principais características de cada uma delas, dando ao usuário uma noção das atividades possíveis de serem realizadas de acordo com sua necessidade em cada ferramenta. O estudo de tradução de diagramas de classe para Java foi baseado quase que completamente em Wazlawick (2004), que explica de forma simples e objetiva esse processo. Alguns conceitos como polimorfismo e interface não são abordados por este autor, por isto houve a necessidade de consultar outras referências para que o processo pudesse ser apresentado de forma mais completa. Todos os exemplos mostrados durante a explicação do processo foram estudados e compilados no Netbeans para que houvesse coerência entre a teoria e prática. Com isto, foi possível compreender melhor os conceitos de orientação a objetos vistos durante o curso, bem como suas relações com os conceitos existentes em um diagrama de classes. Para analisar os códigos, foi elaborado um contexto fictício de um laboratório de exames clínicos para pessoas ou animais. Com base neste contexto, foi elaborado um diagrama de classes e gerado o código tanto no EA quanto no UML Modeling para NetBeans, abordando alguns conceitos de orientação a objetos como classe, atributos, associações, herança, polimorfismo, interface e outros. Sobre o EA, percebe-se que os principais problemas são a não definição da importação de classes que fazem parte da Collection do Java, como Set e Date e, embora crie associações, não cria os métodos para manipular associações entre as classes (associa, desassocia). No UML Modeling para NetBeans, os métodos get dos atributos retornam sempre valor null ao invés do valor do atributo. Os métodos set destes mesmos atributos não fazem atribuição do parâmetro ao atributo da classe. Os métodos adiciona e remove das associações também não foram criados por esta ferramenta. Por fim, conclui-se que as duas ferramentas utilizadas para a elaboração do diagrama e, consequentemente, a geração do seu código (EA e UML Modeling para NetBeans) apresentaram falhas na geração dos mesmos, não se demonstrando totalmente confiáveis, pois o usuário precisa fazer alguns ajustes para que o código compile corretamente. Referências Barnes, D. J. e Kölling, M. (2004) “Programação Orientada a Objetos com Java – Uma Introdução Prática Usando o BlueJ”. São Paulo: Pearson Prentice Hall, 368 p. Boggs, W.e Boggs, M. (2002) “UML Com Rational Rose 2002 - A Bíblia”. Rio de Janeiro: Alta Books 627 p. Pressman, R. S. (2001) “Software Engineering: A Practitioner’s Approach”. 5th ed. Nova York: Mc Graw–Hill 860 p. Silva, M. e Rocha, T. (1998) “Projeto de uma Ferramenta CASE Utilizando a Notação da UML e a Metodologia de COAD & YOURDON”. Belém do Pará, CESUPA. Sparx Systems (2008) “Sparx Systems Enterprise Architect”. http://www.sparxsystems.com, Abril. Peloso, V. (2004) “Ferramentas CASE: Implementação de um Protótipo para Manutenção de Banco de Dados”. Universidade São Francisco, Itatiba, São Paulo. Wazlawick, R. S. (2004) “Análise e Projeto de Sistemas de Informação Orientados a Objetos”. Rio de Janeiro: Elsevier, 298 p.