Desenvolvimento - Java
Engenharia de Componentes - Parte 2
Este estudo descreve assuntos relacionados à componentização, que devem ser analisados antes de um estudo mais aprofundado neste universo da componentização de software. Os conceitos tratados serão a Engenharia de software, engenharia web e engenharia de componentes.
por Jean Wagner Kleemann2.4 Processo de desenvolvimento de software
O processo de desenvolvimento de software, basicamente determina uma estrutura para cada área ou etapa no período de desenvolvimento, relacionando as tecnologias e procedimentos a serem utilizados.
Estas áreas dentro do processo de desenvolvimento serão usadas como alicerce para controlar o desenvolvimento do projeto, determinando em que fase as técnicas devem ser aplicadas. Em síntese o processo de desenvolvimento de software determina uma forma para executar as fases de criação, implantação e manutenção.
O processo unificado PU é resultado de três processos de desenvolvimento e notações, reunindo as vantagens de cada um. Este processo unificado estabeleceu uma notação conhecida como UML (Unified Modeling Language).
O processo unificado é direcionado a casos de uso, centrado na arquitetura e usa os ciclos iterativo e incremental para a construção de softwares, baseado na construção de artefatos de software através da UML, e não apenas em documentação, é também baseado em componentes.
Como os artefatos são produzidos em fases distintas, e refinados ao longo do tempo, eles ajudam a organizar as iterações e a direcionar o projeto, uma vez que o PU é baseado em casos de uso durante praticamente todas as fases. Portanto estes artefatos são primordiais para orientar a condução do projeto.
2.4.2 Rational Unified Process (RUP)
O Rational Unified Process (RUP) foi desenvolvido pela IBM, sendo uma ramificação mais detalhada do PU, possuindo um grande conjunto de manuais e modelos de artefatos a serem produzidos ao longo do processo, além de tutoriais da ferramenta Rational Suite (conjunto de ferramentas construídas em torno do RUP).
O processo do RUP disponibiliza uma abordagem baseada em disciplinas para atribuir tarefas e responsabilidades dentro de uma organização de desenvolvimento, assim como o PU. Também é baseado em casos de uso, orientado pela arquitetura, iterativo e incremental, apresentando uma gama de papéis, disciplinas, tarefas e artefatos.
Integrado ao RUP estão algumas práticas de desenvolvimento de software, sendo elas:
· Desenvolvimento de software de forma iterativa.
· Gerenciamento de requisitos.
· Arquitetura baseada em componentes.
· Modelagem de software por meio de diagramas.
· Analise da qualidade de software.
· Gerenciamento de mudanças de software.
2.4.2.1 Fases
O RUP herda quatro fases do PU, sendo elas:
· Concepção: É definida a viabilidade do projeto como negócio, através da delimitação de seu escopo, e de estimativas de custo, cronograma e retorno sobre o investimento (ROI). Riscos são identificados e gerenciados, são definidos os requisitos funcionais e não funcionais, e é traçado um esboço da arquitetura do sistema, que servirá como alicerce para sua construção. São definidas as primeiras versões do modelo de negócio, do modelo de casos de uso, da lista de riscos e suas prioridades, do plano de projeto, da arquitetura do sistema.
· Elaboração: Refinamento do sistema, com a identificação de quase todos os casos de uso, com o detalhamento da arquitetura traçada na fase anterior e com o gerenciamento contínuo dos riscos envolvidos. Estimativas realistas feitas nesta fase permitem preparar um plano para orientar a construção do sistema nas fases posteriores. É possível que se tenha uma versão completa do modelo de negócios.
· Construção: Nesta fase o sistema é efetivamente desenvolvido e, em geral, tem condições de ser operado, mesmo que em ambiente de teste, pelos clientes. Ao final da fase de construção tem-se um software executável, a atualização de artefatos do sistema refletindo o estado atual do sistema, e um manual do usuário detalhado.
· Transição: O sistema é entregue ao cliente para o uso em produção. Nesta fase testes são realizados, um ou mais incrementos do sistema são implantados e, se necessário, defeitos podem ser corrigidos. É também nessa fase que os usuários recebem treinamento para a operação do sistema.
2.5 Plataforma tecnológica
2.5.1 Java
O Java é uma plataforma de desenvolvimento que chama a atenção de analistas, projetistas e programadores, pois é resultante de um grande trabalho de pesquisa científica e tecnológica que será descrito nos tópicos seguintes.
2.5.1.1 Histórico
Segundo Peter Jandl Junior (2007), em 1991 um pequeno grupo de projeto da Sun Microsystems denominado Green, pretendia criar uma nova geração de computadores portáteis inteligentes, capazes de se comunicar de muitas formas, ampliando suas potencialidades de uso. Para tanto se decidiu criar também uma nova plataforma para o desenvolvimento destes equipamentos de modo que seu software pudesse ser portado para os mais diferentes tipos de equipamentos. A primeira escolha de uma linguagem de programação para tal desenvolvimento foi C++, aproveitando suas características e a experiência dos integrantes do grupo no desenvolvimento de produtos. Mas mesmo o C++ não permitia realizar com facilidade tudo aquilo que o grupo visionava.
James Gosling, um dos líderes do projeto, decidiu pela criação de uma nova linguagem de programação que pudesse conter tudo aquilo considerado importante e que ainda fosse simples, portátil e fácil de programar. Surgiu então a linguagem interpretada Oak (carvalho em inglês), batizada assim em razão da existência de uma destas árvores em frente ao escritório de Gosling. Para dar suporte à linguagem também surgiram o Green OS e uma interface gráfica padronizada.
Devido a problemas de direitos autorais, o Oak recebe o novo nome Java, mas continua sem uso definido até 1994, quando, estimulados pelo grande crescimento da internet, Patrick Naughton e Jonathan Payne desenvolveram o programa navegador WebRunner, capaz de efetuar o download e a execução de código Java via internet. Este navegador, sob o nome HotJava, e a linguagem Java foram apresentados formalmente pela Sun em maio de 1995 no SunWorld"95, então o interesse pela solução se mostrou explosivo. Logo no início de 1996 a Netscape Corp. lança a versão 2.0 de seu navegador, o qual incorpora as capacidades de efetuar o download e realizar a execução de pequenas aplicações Java denominadas applets.
Numa iniciativa inédita, a Sun decide disponibilizar um conjunto de ferramentas de desenvolvimento Java gratuitamente para a comunidade de software, embora detenha todos os direitos relativos à linguagem e às ferramentas de sua autoria. Surge assim, em meados de 1996, o JDK 1.02 (Kit de Desenvolvimento Java). As plataformas inicialmente atendidas foram: Sun Solaris e Microsoft Windows 95/NT. Uma vez que a especificação da linguagem e do ambiente de execução também foram disponibilizados publicamente, progressivamente foram aparecendo kits para outras plataformas, tais como IBM OS/2, Linux e Apple Mac.
Um ano após seu anúncio, ocorre o primeiro grande evento da linguagem Java, o JavaOne Conference, que, desde então, vem sendo usado para apresentar as novas características, casos de sucesso, produtos e tecnologias associadas. Foi assim que se iniciou a história de sucesso do Java.
2.5.1.2 A linguagem de programação Java
A linguagem Java possui algumas características que, em conjunto, diferenciam-na das demais linguagens de programação. Dentre os diversos autores da literatura Java como Horstmann (2000), Newman (1996), entre outros, destacam características que são alguns pontos-chave da Linguagem:
· Orientada a Objetos – Tudo em Java são classes ou instancias de classes, por isso Java é totalmente orientada a objetos, pois, possui mecanismos para abstração de dados (através das classes), encapsulamento (ocultar do usuário o funcionamento interno de uma classe), herança (criar uma nova classe a partir de outra) e polimorfismo (diferentes classes podem definir métodos de mesmo nome).
· Independente de Plataforma – Os programas em Java utilizam uma forma de compilação intermediária que resulta em uma codificação denominada bytecode, um tipo de linguagem de máquina (baixo nível) que é destinado a JVM (Maquina Virtual Java). Dessa forma a JVM interpreta os bytecodes, independente da plataforma, permitindo assim, que um programa Java seja executado da mesma forma em qualquer arquitetura.
· Gerenciamento Automático de Memória - A JVM possui um mecanismo chamado de Garbage Collector (Coletores) que é responsável por alocar e liberar os dados da memória automaticamente. Com isso não é necessário que o desenvolvedor realize tais procedimentos manualmente, eliminando algumas falhas comuns como: tentar acessar um objeto que já foi liberado da memória ou esquecer-se de liberar um objeto.
· Desempenho – Nas primeiras versões, o Java apresentava certa limitação quanto a performance, mas isto foi superado com algumas adaptações na JVM. Um compilador JIT (Just In Time) foi incorporado na JVM que passou a interpretar os bytecodes durante a execução do programa. Conforme as novas gerações de compiladores como, por exemplo, o HotSpot da Sun combinado com a JVM, a performance vem melhorando de forma muito significativa, podendo concorrer até mesmo com o C++ (Carmine Mangione, on-line).
· Tratamento de exceções: Em alguns casos, a ocorrência de algum erro durante a execução de um programa pode fazer com que o computador “trave” sendo necessário reinicia-lo. Com a utilização do Java este tipo de evento não acontece, pois, a JVM verifica em tempo de execução um conjunto de eventos (acesso a memória, abertura de arquivos, etc.) e ao encontrar algum impedimento ou inconsistência gera uma exceção (uma espécie de mensagem com a descrição do erro).
· Segurança: Diferente das demais linguagens, em Java a aplicação não se comunica com o Sistema Operacional, e sim com a JVM que por sua vez interage com o Sistema. O bytecode gerado pela aplicação deve passar primeiro por alguns requisitos de segurança da JVM, que caso encontre alguma irregularidade impede a execução do código.
· Multithread: Capaz de executar várias tarefas (conjunto de instruções) ao mesmo tempo dentro da aplicação. Cada uma destas tarefas é conhecida como thread.
Vale destacar que para desenvolver programas em Java, primeiramente é necessário um editor que permita salvar o programa fonte com a extensão “.java”, como por exemplo o JEdit, JCreator ou até mesmo o bloco de notas do Microsoft Windows. Uma alternativa mais interessante é o uso de uma IDE (Integrated Development Environment) própria para Java, como o NetBeans ou Eclipse. Posteriormente com base no arquivo “.java”, o compilador Java é responsável por gerar o arquivo de extensão “.class”, que é o bytecode propriamente dito. Então a JVM interpreta e executa os arquivos de classe fazendo o uso do código nativo (usado para comunicar-se com o hardware) do Sistema Operacional.
Dessa forma o código Java é o mesmo para diferentes arquiteturas, pois o que muda são as distribuições da JVM, livrando o desenvolvedor de ajustar o código conforme a plataforma.
2.5.1.3 A plataforma tecnológica Java
Os ambientes de desenvolvimento ou plataformas Java (ALECRIM, 2007, on-line):
· JSE (Java Standard Edition): Pode-se dizer que é o ambiente principal, pois o JEE e o JME são aprimorados do JSE. Desenvolvido para aplicações baseadas em cliente/servidor.
· JEE (Java Enterprise Edition): As aplicações WEB são fundamentadas nesta plataforma. As implementações neste padrão são muito complexas, contém bibliotecas exclusivas para o acesso a servidores, banco de dados, sistema de e-mails, entre outros.
· JME (Java Micro Edition): Corresponde ao JSE reduzido, para dispositivos móveis (telefones celulares, palmtops,...).
2.5.2 Sistema Gerenciador de Banco de Dados
Segundo Abraham Silberschatz, um sistema gerenciador de banco de dados (SGBD) é constituído por um conjunto de dados associados a um conjunto de programas para acesso a esses dados.
Um SGBD possui estruturas de dados otimizadas, que permitem a manipulação de grandes quantidades de informação, e apresentam um modelo que define o esquema dos dados armazenados no sistema. Os quatro modelos mais conhecidos são:
· Hierárquico.
· Em Rede.
· Relacional.
· Orientado a Objetos.
Existem também outros modelos, variando com o autor:
· O modelo relacional estendido é uma adição de características do modelo orientado a objetos ao relacional.
· O semi-estruturado é dedicado a documentos em formatos semi-estruturados, normalmente em XML.
Um SGBD deve apresentar algumas características e responsabilidades, tais como:
· Integridade semântica (garantia de dados sempre corretos com relação ao domínio de aplicação)
· Segurança (evitar violação de consistência dos dados, segurança de acesso por usuários e aplicações, segurança contra falhas).
· Gerenciamento de Concorrência (evitar conflitos de acesso simultâneo a dados por transações).
2.5.2.2 Uma breve história do PostgreSQL
O PostgreSQL é um dos resultados de uma ampla evolução que se iniciou com o projeto Ingres, desenvolvido na Universidade de Berkeley, Califórnia. O líder do projeto, Michael Stonebraker, um dos pioneiros dos bancos de dados relacionais, deixou a universidade em 1982 para comercializar o Ingres, porém retornou a ela logo em seguida. Após seu retorno a Berkeley, em 1985, Stonebraker começou um projeto pós-Ingres com o objetivo de resolver problemas com o modelo de banco de dados relacional. O principal problema era a incapacidade do modelo relacional compreender “tipos” (atualmente, chamados de objetos), ou seja, combinações de dados simples que formam uma única unidade.
O projeto resultante, chamado Postgres, era orientado a introduzir a menor quantidade possível de funcionalidades para completar o suporte a tipos. Estas funcionalidades incluíam a habilidade de definir tipos, mas também a habilidade de descrever relações - as quais até este momento eram amplamente utilizadas, mas completamente mantidas pelo usuário. No Postgres, o banco de dados "compreendia" as relações e podia obter informações de tabelas relacionadas utilizando regras.
Iniciando em 1986, a equipe divulgou uma série de documentos descrevendo a base do sistema e em 1988 o projeto possuía um protótipo funcional. A versão 1 foi liberada para um grupo pequeno de usuários em junho de 1989, seguida pela versão 2 com um sistema de regras reescrito em junho de 1990. Para a versão 3, liberada em 1991, o sistema de regras foi reescrito novamente, mas também foram adicionados suporte para múltiplos gerenciadores de armazenamento e um melhorado motor de consultas. Já em 1993, Postgres havia crescido imensamente em popularidade e possuía uma grande demanda por suporte e por novas funcionalidades. Após a liberação da versão 4, a qual era uma simples versão de limpeza, o projeto foi oficialmente abandonado pela Universidade de Berkeley.
Entretanto, devido ao fato do seu código fonte estar sob uma licença BSD, o seu desenvolvimento foi continuado. Em 1994, dois estudantes de Berkeley, Andrew Yu e Jolly Chen, adicionaram um interpretador SQL para substituir a linguagem QUEL (desenvolvida para o Ingres) e o projeto foi renomeado para Postgres95. Com a divulgação de seu código pela Internet, Postgres95 iniciou uma nova vida como software open source.
Em agosto de 1996, Marc Fournier, Bruce Momjian e Vadim B. Mikheev lançaram a primeira versão externa da Universidade de Berkeley e deram início à tarefa de estabilizar o código herdado. Também em 1996, o projeto foi renomeado para PostgreSQL a fim de refletir a nova linguagem de consulta ao banco de dados: SQL. A primeira versão de PostgreSQL, a 6.0, foi liberada em janeiro de 1997. Desde então, um grupo de desenvolvedores e de voluntários de todo o mundo, coordenados pela Internet, têm mantido o software e desenvolvido novas funcionalidades.
As principais características acrescentadas nas versões 6.x são o en:MVCC (Multiversion Concurrency Control – Controle de Concorrência Multiversões), melhorias no SQL e novos tipos de dados nativos (novos tipos de datas e hora e tipos geométricos).
Em maio de 2000 foi liberada a versão 7.0. As versões 7.x trouxeram as seguintes novas funcionalidades: Write-Ahead Log (WAL), esquemas SQL, outer joins, suporte a IPv6, indexação por texto, suporte melhorado a SSL e informações estatísticas do banco de dados.
A versão 8.0 foi lançada em janeiro de 2005 e entre outras novidades, foi a primeira a ter suporte nativo para Microsoft Windows (tradicionalmente, o PostgreSQL só rodava de forma nativa em sistemas Unix e, em sistemas Windows - através da biblioteca Cygwin). Dentre as muitas novidades da versão 8.x, pode-se destacar o suporte a tablespaces, savepoints, point-in-time recovery, roles e Two-Phase Commit (2PC). Em Julho de 2009 foi lançada a versão mais recente: 8.4.
2.5.2.3 Características técnicas do PostgreSQL
· Licença BSD (Berkeley Software Distribution). Portanto pode ser utilizado, modificado e distribuído por qualquer pessoa ou empresa para qualquer finalidade, sem encargo, em quaisquer dos sistemas operacionais suportados.
· Grande número de recursos, tais como: Comandos complexos, Chaves estrangeiras, Gatilhos, Visões, Integridade de Transações, Controle de Simultaneidade Multi-versão, (MVCC), Suporta múltiplas transações online concorrentes entre usuários, Suporte a Rules (sistema de regras que reescreve diretivas SQL), Suporte ao modelo híbrido objeto-relacional, Linguagem Procedural em várias linguagens (PL/pgSQL, PL/Python, PL/Java, PL/Perl), Indexação por texto, Estrutura para guardar dados Georeferenciados PostGIS, entre outros.
· Opções de extensão através do usuário: Tipos de dados, Funções, Operadores, Funções de Agregação (Agrupamento), Métodos de Índice por texto, Linguagens Procedurais (Stored Procedures).
· Capacidade de lidar com grandes volumes de dados.
2.6 Sistema Distribuído
Segundo Tanenbaum (1995), um sistema distribuído é um conjunto de computadores independentes que aparentam aos usuários um sistema único. Outra definição também é apresentada por Coulouris (2005), que defende a idéia de um sistema distribuído ser componentes de hardware e software conectados em rede que comunicam suas ações somente através de trocas de mensagens.
Um sistema distribuído pode possuir diversos elementos de hardware e software de forma distribuída, mas a distribuição de apenas um dos elementos já o caracteriza como sistema distribuído.
Neste capítulo serão descritas algumas características de sistemas distribuídos e aspectos importantes sobre segurança e telecomunicações.
2.6.1 Conceito de Sistemas Distribuídos, Segurança e Telecomunicações.
Apesar de um sistema apresentar conceitos relacionados à distribuição, nem todos podem ser considerados como sistemas realmente distribuídos. É o caso de terminais inteligentes, por exemplo.
Os terminais inteligentes possuem baixa capacidade de armazenamento e processamento e executam tarefas limitadas e pouco flexíveis transferindo dados para um sistema principal. Por não possuírem autonomia operacional suficiente, estes não podem ser caracterizados como sistemas distribuídos.
Os sistemas realmente distribuídos devem apresentar a distribuição de controle, processamento e dados. Dessa forma um sistema que utiliza das vias de tele processamento, não é necessariamente um sistema distribuído de fato.
A distribuição do processamento quer dizer que em cada nodo da rede deve existir capacidade de processamento independente. Em outras palavras, deve ser capaz de executar um processo em cada nodo e de gerenciar os recursos locais de forma autônoma. Este processamento pode ser constituído desde um mainframe até por uma estação de trabalho, e é o componente de mais fácil de ser identificado, sendo necessário a existência de múltiplos processadores.
A distribuição de dados é a possibilidade de localizar os arquivos ou banco de dados próximos aos locais onde são mais acessados. Para isto deve existir um gerenciador de arquivos ou de banco de dados local e um mecanismo que permita o acesso remoto a estes recursos. Um sistema distribuído permite que os dados armazenados sejam compartilhados pelos diversos nodos onde existe capacidade de processamento. Este compartilhamento pode ser obtido pela transferência de arquivos ou pelo acesso remoto aos dados.
A distribuição do controle significa que os processos executados nos diferentes nodos interagem de forma cooperativa para satisfazerem um determinado objetivo. Esta cooperação é definida por um protocolo que especifica completamente os serviços a serem executados.
O controle é o de mais difícil domínio e, ao mesmo tempo, o de maior importância para o funcionamento de um sistema distribuído. Os diferentes computadores do sistema distribuído podem ser heterogêneos e possuir, cada um, o seu próprio sistema operacional. Porém o conjunto deve operar como um todo integrado e apresentando um comportamento homogêneo. A integração destes sistemas locais heterogêneos em um único sistema homogêneo não é uma tarefa trivial.
O controle distribuído de uma aplicação é, por natureza, diferente e mais complexo do que o controle de um sistema centralizado. Em um local único todos os dados necessários ao controle estão imediatamente disponíveis e o sistema operacional local tem completa autonomia para gerenciar os recursos. A sincronização dos processos que operam simultaneamente em um sistema centralizado é realizada por meio do compartilhamento de áreas de memória.
A característica essencial do controle de um sistema distribuído é a coordenação entre os diferentes processos por meio de mensagens. Esta característica implica na impossibilidade da manutenção de informação completa e atualizada sobre cada processo de um sistema distribuído. Os algoritmos utilizados para a sincronização das atividades distribuídas possuem, por este motivo, uma complexidade maior que a apresentada por algoritmos centralizados (LAMPORT, 1978).
O processamento distribuído, assim como foi caracterizado, é mais do que uma tecnologia é, também, uma metodologia para a concepção e implantação de sistemas de informação. Sua principal característica é possibilitar o particionamento das atividades (e dos dados associados) de acordo com a localização geográfica das aplicações mantendo, ao mesmo tempo, a integração dos diversos componentes.
As características mais importantes dos sistemas distribuídos podem ser resumidas em: Diminuir o tráfego de mensagens, processar localmente; Manter a integração do sistema e atender às necessidades locais.
Dessa forma, é possível otimizar o desempenho e o custo global e aumentar a confiabilidade das aplicações. Um sistema distribuído possui, entretanto, uma maior complexidade que um sistema centralizado e apresenta características funcionais que podem influir nos procedimentos operacionais e de decisão das empresas.
Podem ser citadas três alternativas básicas para a escolha de critérios de distribuição: a distribuição por áreas geográficas por grupos funcionais e por funções de processamento de dados.
A distribuição geográfica dos dados é um dos critérios fundamentais para o projeto de sistemas distribuídos. Deve haver uma grande parcela de atividade local (dados locais) e pequena atividade entre regiões. Em grande parte dos sistemas reais os dados apresentam a propriedade dos acessos serem geograficamente agrupados. A idéia básica para o particionamento dos dados consiste em agrupá-los de acordo com as taxas de acesso para a identificação dos possíveis computadores regionais. Desta forma é minimizado o tráfego interno.
A característica determinante desta forma de distribuição é a relação entre atividade local e a remota. Caso a taxa de atividade remota seja alta a distribuição não é a solução mais adequada. Este critério leva à minimização do fluxo de dados interno e é empregado em métodos de alocação ótima de arquivos em sistemas distribuídos. Com exceção de sistemas muito especializados (defesa, alta segurança de operação) a maioria dos sistemas distribuídos reflete a agregação geográfica natural das organizações.
O desenvolvimento de computadores levou aos sistemas departamentais. O conceito administrativo utilizado, neste caso, consiste em alocar capacidade de processamento em cada departamento, isto é: distribuição por grupo de funções. Esta é uma alternativa à utilização compartilhada de um grande sistema central. Apenas os dados corporativos (e os muito volumosos) são mantidos no sistema central. A integração do sistema de informações automatizado é assegurada pela interligação dos diversos computadores departamentais e do computador central.
Outra forma de distribuição consiste na distribuição por funções. Neste caso estão classificados os servidores especializados, tais como: servidores de impressão, servidores de arquivos, processadores vetoriais ou processadores de uso geral especializados por software. Este tipo de distribuição atribui a cada tarefa um nodo adequado a função específica. Tais categorias de distribuição não são exclusivas sendo que um sistema pode conter partes dessas por se encaixarem em categorias distintas.