Baixe o app para aproveitar ainda mais
Prévia do material em texto
Engenharia de Software Baseada em Componentes Responsável pelo Conteúdo: Prof. Me. Eduardo Kerr Revisão Textual: Prof.ª Esp. Kelciane da Rocha Campos Técnicas de Reuso Técnicas de Reuso • Estudar as técnicas de reuso de componentes; • Composição de componentes; • Ferramentas para integração de componentes; • Componentes como serviço; • Estudar como verificar e validar componentes e as aplicações construídas com componentes. OBJETIVOS DE APRENDIZADO • Introdução; • Construção de Componentes – Componentes para Reuso; • Composição com Componentes; • Componentes como Serviços; • Teste e Controle. UNIDADE Técnicas de Reuso Introdução No desenvolvimento de projeto de sistemas ou aplicações, podemos aplicar o reuso de software em vários momentos e em diferentes tipos de projetos, como estudado em outra Unidade. Mostramos também que o conceito de reusabilidade é amplo, com abor- dagens que não se restringem somente à reutilização de código-fonte de uma biblioteca de objetos simples ou de componentes com funcionalidades mais elaboradas. Temos outros paradigmas de reuso que utilizam padrões de projeto, especificações de uma família de produtos, sistemas configuráveis e outras combinações de metodologias durante o pro- cesso de desenvolvimento. Nesta unidade, vamos estudar algumas técnicas que são utilizadas para facilitar a construção de software usando princípios de reuso, como conectar os componentes, integrar módulos e sistemas e como os conceitos de componentes foram estendidos para serviços. Além desses tópicos, dependendo do tipo de projeto, caixa preta, caixa branca ou a combinação das duas formas, o uso de ferramentas de integração precisa ser incorporado na metodologia: os Frameworks e Middlewares. A construção de software não é uma atividade simples e independente das caracterís- ticas e dimensões do sistema a ser criado, as etapas de testes não podem ser eliminadas. Uma das vantagens de aplicar construção baseada em componentes é que utilizamos elementos que foram previamente testados. Contudo, como a maioria das atividades de engenharia, a construção de software depende basicamente da habilidade, da interpre- tação e da execução das pessoas que o constroem; desta forma, erros acabam surgindo, mesmo com a utilização de métodos e ferramentas de Engenharia de Software. Vamos abordar como aplicar as metodologias de testes nesses casos. Construção de Componentes – Componentes para Reuso A construção de componentes de software para reuso, de forma bem simplificada, já existia na década de 1960, embora ocorrendo em grupos restritos de pesquisadores que compartilhavam algoritmos e funções matemáticas. Essa forma de reuso permitia economia de tempo em alguns desenvolvimentos, mas estava muito distante das pro- postas da engenharia de software baseada em componentes, que, como já estudamos, começa a ser realmente utilizada vinte anos mais tarde. As principais deficiências dessas primeiras iniciativas eram: • Utilização de código-fonte: O reuso era dependente da linguagem de progra- mação utilizada; • Domínio: Praticamente restrito ao campo de funções matemáticas; • Ausência de padrão: Não havia um modelo específico de compartilhamento. A busca por uma reusabilidade mais efetiva resultou em diferentes abordagens na construção de componentes para reuso. 8 9 • Desenvolvimento de objetos: componentes menores com funcionalidade de uso comum a vários domínios, como, por exemplo, elementos de interface gráfica . Texto Botão Caixa de Texto Caixa de Senha Caixa de Seleção Figura 1 – Tela de Interface Fonte: Acervo do Conteudista Por exemplo: na Figura 1, utilizamos componentes de interface gráficos, como texto, caixa de entrada de texto, caixa de entrada de senha, caixa de seleção de item e botão que executa uma ação quando acionado. Esses elementos podem ser usados para criação de telas e interfaces com usuário em vários domínios de aplicação. A constru- ção desses componentes, normalmente, é feita pelos desenvolvedores de Framework. Esses componentes oferecem um razoável nível de customização. Além da praticidade com que alguns ambientes oferecem esses elementos, de forma plug-and-play, alguns ambientes disponibilizam o código-fonte, com chamadas das funções primitivas da linguagem de programação e se o desenvolvedor tiver conhecimento necessário, pode modificar o código, indo além da customização oferecida. No entanto, nesse caso, o componente deixa de ser o padrão; Vamos entender o conceito de Framework. Abrindo o dicionário de Cambridge, encontramos como possíveis traduções de framework para o português: estrutura, alicerce. No contexto da engenharia de software, a definição não é unanimidade, e a que vamos usar é mais longa. Framework: é um ambiente de desenvolvimento de software com recursos de bibliotecas de componentes reutilizáveis, código-fonte de objetos, uma linguagem de script e outros módulos que auxiliam o desenvolvimento de programas. Fazendo analogia ao conceito de estrutura, é a fundação para construir sistemas, aplicativos, componentes e objetos, ajudando a desenvolver, integrar, testar as diferentes etapas de um projeto de software. Veja a Figura 2 Framework Banco Dados Sistema 1 Sistema 2 Objetos Módulos Aplicação Figura 2 – Construindo sistemas com Framework 9 UNIDADE Técnicas de Reuso Frameworks dedicados na integração de sistemas são conhecidos como Middleware. O con- ceito de middleware diz respeito a uma ferramenta projetada especificamente para ajudar sistemas isolados, ou separados, a interagir. Um sistema padrão (frameworks incluídos) é construído com muitas camadas empilhadas umas sobre as outras, assim como nos sistemas operacionais e nas bibliotecas. O middleware funciona pegando fatias dessas camadas, verticalmente! Atuando como integrador, ele fornece uma solução, completa ou parcial, para qualquer área dentro do aplicativo e pode fornecer uma conexão muito mais robusta entre os sistemas. Veja a Figura 3. Aplicações Aplicações Sistema Operacional Hardware e Rede M id dl ew ar e Figura 3 – Middleware atuando de forma vertical na integração de sistemas • Integração de sistemas: onde um sistema é considerado um componente que pode se conectar a outros sistemas, executando funções integradas, de forma transparente aos usuários. Nesses casos específicos, o desenvolvimento de componentes reutilizá- veis está concentrado nos conjuntos de conectores que possam realizar a integração. Por exemplo, uma aplicação de internet banking, embora transmita a impressão para o usuário de que ele está conectando um único sistema, certamente ele está conectando diferentes sistemas de serviços bancários, construídos com tecnologias distintas. A Figura 4 ilustra um exemplo de integração de sistemas e componentes. Figura 4 – Sistema de controle de paciente Fonte: Reprodução 10 11 Na Figura 4, temos um sistema de agendamento e cadastro de paciente, conectado a um módulo de seleção de data, conectado em um sistema na internet para marcação de consulta. A conectividade e reusabilidade desses componentes são possíveis usando conectores de integração (middleware) e podem ser aplicadas para sistemas distintos, que atendam médicos, dentistas, fisioterapeutas, etc.; • Reengenharia de componentes: quando precisamos estender, adaptar ou atualizar componentes (módulos complexos) que não oferecem uma reusabilidade desejada, por serem específicos para uma única funcionalidade, ou quando desejamos substi- tuir um sistema legado, aplicamos a reengenharia. O s desenvolvedores devem rea- lizar um trabalho de análise, custos, benefícios e estratégia para criar versões mais genéricas e, portanto, mais reutilizáveis. Entre as alterações possíveis, destacamos: » remoção de métodos específicos de aplicação; » adicionar métodos para orna-los mais genéricos; » adicionar uma interface “configuração”. É a solução mais rápida, que permite ao componente ser adaptadopara diferentes situações de uso. Modelo de Componentes Para construir componentes reutilizáveis, é necessário adotar um conjunto de normas para implementação, documentação dos componentes. Chamamos esse conjunto de re- gras de Modelo de Componentes, e este é essencial para que os desenvolvedores possam garantir a interoperação dos componentes. Vários modelos já foram propostos, atualmente os mais importantes são o modelo .NET da Microsoft e o modelo EJB (Enterprise Java Beans) da Oracle. Heineman (2001) destaca os seguintes elementos para um modelo: Quadro 1 Interfaces Especificação do comportamento e propriedades. Nomeação Convenção usada para nomes globais e únicos para interfaces e componentes. Metadados Informações sobre os componentes e seus atributos. Interoperabilidade Comunicação e troca de dados entre componentes. Customização Interfaces que possibilitam a customização. Composição Interfaces e regras para combinar ou substituir componentes. Suporte a evolução Regras e serviços necessários para instalar e configurar. Empacotamento Definição para implementar, empacotar e configurar componentes. Sommervile (2011) resume o modelo de componentes em três categorias, de acordo com o diagrama no seu livro “Engenharia de Software”. 11 UNIDADE Técnicas de Reuso De�nição de interface Composição Interfaces especí�cas Convenção de nomes Acesso a metadados Personalização Empacotamento Apoio à evolução Documentação Interfaces Informações de uso Implantação e uso Modelo de componente Figura 5 Fonte: Adaptada de SOMMERVILLE, 2011, p. 319 Se o componente for de código aberto, o destino pode ser um dos vários repositórios públicos; no entanto, na maioria das vezes o modelo de componente não vai conter os elementos citados por Sommerville. Um forte obstáculo à maior utilização do paradigma de desenvolvimento baseado em componentes é o fato de, até os dias atuais, não existir padrão para modelo de com- ponente. O mercado de desenvolvedores de componentes para reuso é constituído, na grande maioria, por empresas que possuem linha de produtos ou que prestam serviços de desenvolvimento, mais comumente conhecidas como Fábricas de Software. Fábrica de Software: é semelhante às indústrias tradicionais, mas voltada ao desenvolvi- mento de sistemas de software. Em geral COTS, utilizando as melhores práticas criadas para o processo de desenvolvimento, testes e manutenções dos softwares. As fábricas aplicam indicadores de qualidade e produtividade em cada etapa do ciclo de desenvolvimento, bem como buscam maximizar a reutilização de componentes. Composição com Componentes Existem três maneiras básicas de reutilizar software. Você pode usar o componente em sua forma original em vários sistemas, pode estender a funcionalidade do compo- nente conforme necessário para sistemas individuais ou pode restringir a funcionalidade do componente conforme necessário para sistemas individuais. Um componente de software reutilizável em nível de código é independente, o que significa acoplamento fraco, e tem limites claramente definidos com respeito ao que faz e não faz. Precisa ter, obrigatoriamente, pontos de interface claramente definidos. Essas características facilitam a integração com os outros componentes. Nos projetos conhecidos como caixa preta, a documentação da interface será sufi- ciente para permitir a reutilização dos componentes, ou seja, não há necessidade de acesso ao código binário. Havendo necessidade de eliminar conflitos de interface, a implementação feita por meio do encapsulamento é uma possível solução. 12 13 Para os projetos que precisam modificar a parte interna/funcionalidade do compo- nente, além de acesso ao código-fonte, é desejável ter a especificação clara, inequívoca e documentação do modelo do componente – por exemplo, para adicionar um recurso, adaptar a evolução tecnológica ou corrigir um defeito anteriormente não descoberto. Reuso vertical é o que ocorre dentro de um mesmo domínio de aplicação. Os desen- volvedores fazem uso de um modelo genérico aplicado em um único domínio, para criar sistemas. Este tipo de reuso é o que ocorre em fábricas de software. O reuso horizontal tem como meta a utilização de um componente em diferentes domínios de aplicação. Como exemplo, temos bibliotecas de funções matemáticas, de manipulação de string e bibliotecas para construção de interfaces gráficas, entre outras. A característica principal é que a sua utilização ocorre em diferentes domínios. O reuso composicional é a utilização de componentes existentes como blocos para a construção de um novo sistema. O novo sistema é construído a partir da composição de componentes existentes – por exemplo: utilizando um conjunto de componentes do framework Java Server Faces, construir aplicativos para web com tecnologia de compo- nentes EJB para sistemas distribuídos. Componentes como Serviços A engenharia baseada em componentes é um meio eficaz de dividir um sistema (monolítico) complexo em módulos funcionais ou componentes lógicos, visando à reu- sabilidade. Com o crescimento de sistemas conectados em rede e uma crescente busca para melhorar o desempenho, disponibilidade e escalabilidade, as aplicações passaram a considerar a execução em mais de um servidor. O conceito de componente precisava evoluir para componentes distribuídos em rede. A partir dessa necessidade, componentes se transformaram em serviços, que são acio- nados a partir da aplicação . Os serviços nada mais são do que componentes com uma interface pública instalados, fisicamente, em alguma máquina na rede. Nesses casos, os conceitos de uma arquitetura baseada em componentes são utilizados no desenvolvimento de uma nova metodologia, Arquitetura Orientada a Serviços (SOA). Thomas Erl (2008), no seu livro SOA: princípios do design de serviços , descreve os 8 princípios básicos da Arquitetura Orientada a Serviços: • Serviços são reutilizáveis; • Serviços compartilham um contrato formal; • Serviços possuem baixo acoplamento; • Serviços abstraem a lógica; • Serviços são capazes de se compor; • Serviços são autônomos; • Serviços evitam alocação de recursos por longos períodos; • Serviços devem possuir a capacidade de serem descobertos. 13 UNIDADE Técnicas de Reuso Os serviços implementados com SOA são classificados em 4 grupos: • Business Services: serviços de “granulação grossa” que coordenam as principais operações de negócios (serviços de orquestração); • Enterprise Services: implementam a funcionalidade definida pelos serviços de negócios (serviços compartilhados e reutilizáveis); • Application Services: os serviços são restritos a um contexto de aplicativo específico; • Infrastructure Services: implementam tarefas não funcionais, como autenticação, auditoria, segurança, registro, etc. Os serviços se comunicam por meio de um Enterprise Service Bus (ESB). ESB é uma arquitetura de software integrada por um conjunto numeroso de regras e princí- pios que permite integrar uma série de aplicativos diferentes em uma única infraestrutura. Em palavras mais simples, um ESB é uma arquitetura de software que é responsável por conec- tar uma série de outros softwares ou aplicativos em uma infraestrutura do tipo barramento. Apesar da popularização da arquitetura orientada a serviços, a partir de 2005, alguns pontos de atenção dessa tecnologia motivaram novas pesquisas: • ESB representa um único ponto de falha no sistema, se ocorresse um problema de comunicação criava-se um problema de disponibilidade; • O gerenciamento dos serviços da arquitetura é de grande complexidade; • O desempenho, escalabilidade, robutez e segurança dos serviços são fatores preocu- pantes, uma vez que dependem de um servidor, onde os serviços estão instalados. Chegamos, afinal, na evolução da arquitetura SOA, com o desenvolvimento de Mircros- serviços. As diferenças para arquitetura de serviço são: • Os serviços são decompostos em funções básicas e transformadosem microsserviços; • Microsserviços podem ser distribuídos em servidores diferentes; • Microsserviços podem se comunicar por meio de interfaces de programação de aplicações (API); • Microsserviços podem ser escritos em diferentes linguagens de programação. Sistema (monolítico) Componentes Serviços (SOA) Microserviços Figura 6 – Comparação de Sistema x Baseado em Componentes x Orientado a Serviços e Utilizando Microsserviços Na comparação ilustrada na Figura 5, começamos com um sistema tradicional, mono- lítico, que significa com partes indivisíveis. Esse sistema é transformado em um conjunto de componentes, executados em um mesmo hardware. Para permitir o processamento distribuído e mais de um servidor, alguns componentes são transformados em serviços e utilizam a arquitetura de ESB para comunicação. Na evolução para microsserviços, 14 15 componentes são transformados em funções, os microsserviços se comunicam com API, não ficando dependentes da arquitetura de ESB. Teste e Controle Conforme o paradigma que for utilizado para desenvolvimento dos produtos, preci- samos de metodologias que detectem erros. Segundo Pressman (2007), o destaque crescente do software como elemento de siste- mas e os “custos” envolvidos associados às falhas de software são forças propulsoras para que a atividade de teste seja cuidadosa e bem planejada. Os valores gastos nas etapas de testes, associados aos custos de manutenção, e as estatísticas de probabilidade de encon- trar erros ao longo do ciclo de vida de um sistema refletem a preocupação com esse tema. Como objetivo secundário, a atividade de teste de software demonstrará que as fun- cionalidades do software, aparentemente, estão trabalhando de acordo com as especifi- cações e que os requisitos foram cumpridos. Além, é claro, de servir como uma boa indi- cação de confiabilidade de software e indicação de qualidade do sistema como um todo. A facilidade de criar componentes e eventualmente atualizar um ou mais compo- nentes de uma aplicação gerou uma preocupação quanto ao gerenciamento dos compo- nentes. Os componentes podiam ser atualizados devido a melhorias tecnológicas ou elimi nação de defeitos e os gestores dos repositórios enfrentavam um dilema: qual siste- ma utiliza qual versão de um componente? Nem sempre as necessidades eram as mesmas para clientes diferentes; algumas vezes, principalmente nos repositórios de domínio horizontal, os sistemas não supor- tavam atualizações tecnológicas. Isso obrigava os gestores de repositórios a exercer um controle preciso de qual versão de componente cada sistema utilizava. Formulados ao longo de 40 anos, os sete princípios do teste de software representam as regras básicas para o processo e são: • Testes mostram a presença de erros : Testes procuram a detecção de defeitos den- tro de um pedaço do software. Mas não importa quanto um produto é exaustivamen- te testado, nunca é possível afirmar 100% que um produto não tem falhas. Podemos apenas usar os testes para reduzir o número de defeitos não encontrados; • Testes exaustivos são impossíveis: Não é possível testar todas as combinações de inputs de dados, cenários e pré-condições dentro de uma aplicação. Por exemplo, se uma única tela de aplicação contém 8 campos para acrescentar dados com 3 possíveis opções de valores cada, isto significa que para cobrir todas as possíveis combinações, engenheiros de teste deveriam criar 6.561 (3**8) cenários de teste. Se a Aplicação contiver 5 ou mais de tais telas? Melhor pensar em um conjunto de teste mais restrito!! • Teste antes : O custo de um erro cresce exponencialmente ao longo do processo. Se vamos combinar componentes, melhor realizar teste de integração e, depen- dendo da origem do componente, testes unitários; • Aglutinação de defeitos : Este princípio é frequentemente referido como uma aplica- ção do princípio de Pareto no Teste de Software. Isto significa que aproximadamente 80% dos erros são usualmente encontrados em 20% dos módulos do sistema. Assim, se um defeito é encontrado em um módulo do programa de software, as chances de haver outros defeitos no mesmo módulo são grandes; 15 UNIDADE Técnicas de Reuso • Paradoxo pesticida: Rodar o mesmo conjunto de testes de novo e de novo não contribui para encontrar mais falhas. Assim que os defeitos detectados são corrigidos, estes cenários de teste se tornam inúteis. É importante revisar e atualizar regularmente os testes para adaptá-los e potencialmente encontrar mais falhas. Com exceção da ocasião de ocorrer subs- tituição de componente, nesse caso, precisamos refazer os cenários de testes já aprovados; • Teste depende do contexto: Dependendo do propósito ou da indústria, diferentes aplicações devem ser testadas diferentemente. Em alguns casos, o acesso segmentado é importante; em outros, o fator crítico talvez seja o tempo de resposta; • Falácia da ausência de erros: A completa ausência de defeitos no seu produto não significa necessariamente que ele será um sucesso. Se o sistema construído não atender às necessidades e expectativas do usuário, o fato de os testes não detectarem defeitos não atesta qualidade de desenvolvimento. Conclusão: • Um bom caso de teste é aquele que tem uma elevada probabilidade de revelar um erro ainda não descoberto; • Um teste bem-sucedido é aquele que revela um erro ainda não descoberto; • Casos de teste que descubram, de forma sistemática, diferentes classes de erros, com o menor esforço e no menor tempo, devem ser projetados. Testes – Verificação e Validação De forma que estes erros sejam descobertos antes de o software ser liberado para utilização, existe uma série de atividades, chamadas de Validação, Verificação e Teste (VV&T), que têm por finalidade garantir que tanto o modelo pelo qual o software está sendo construído, quanto o produto estejam em conformidade com a especificação. Definimos a atividade de VV&T como um elemento crítico de garantia de quali- dade de software, representando a última revisão de especificações de um projeto e código desenvolvido. Importante! Para nosso estudo, vamos aplicar uma parte dos conceitos tradicionais de teste de software, apresentados por Pressman no livro “Engenharia de software”, 7ª edição, 2011. • Teste Unitário: verificação na menor unidade de projeto do software, o compo- nente ou módulo de software; • Teste de Integração: é uma técnica sistemática para construir a arquitetura de software ao mesmo tempo que conduz testes para descobrir erros associados com as interfaces; • Teste de Regressão: é a reexecução do mesmo subconjunto de testes que já foram executados para assegurar que as alterações não tenham propagado efeitos colate- rais indesejados; • Teste de Disponibilização: não aplicamos esse tipo de teste, uma vez que o com- ponente, por definição, é independente de plataforma; • Teste de Desempenho, Esforço e Recuperação: considerado como teste de sistema, que é feito antes da homologação. 16 17 As necessidades de testes são específicas, em função da atividade: • Para os desenvolvimentos de aplicações com componentes: se o projeto estiver usando componentes de fonte confiável, podemos optar por não fazer o teste unitário. Caso o componente tenha origem em repositório público, devemos efetuar os testes antes de incluir o componente no sistema. Teste de integração precisa ser feito, com esse teste é possível detectar incompatibilidade de interfaces. Os testes de regressão, no caso de substituição de algum componente, precisam seguir os mesmos cenários de teste a que a versão anterior foi submetida. Os testes de sistemas devem ser feitos observando- -se o documento de projeto de sistema, que foi produzido na engenharia de aplicação; • Para o desenvolvimento de componentes para reuso: devem ser feitos os testes unitários, validando o modelo do componente e de acordo com documento de pro- jeto de domínio, produzido no processo de Engenharia de Domínio . No caso de ser uma atualização ou correção,devem ser aplicados também os testes de regressão. A empresa que desenvolveu o componente pode ainda realizar a certificação. A certi- ficação, em geral, é um serviço externo contratado, que atesta que o software atingiu um padrão de qualidade aceitável. Controle de Componentes “A arte do progresso é preservar a ordem nas alterações e preservar as alterações na ordem.” Alfred North Whitehead. Com a necessidade de controlar o as alterações dos componentes de software nos repositórios comerciais e identificar em quais aplicações os artefatos estavam sendo utili- zados, surgem os sistemas do tipo SCM (do inglês Software Configuration Management), a Gestão de Configuração de Software. Segundo Pressman (2007), gestão de configuração é “a arte de identificar, organizar e controlar modificações no software que está sendo criado por uma equipe de progra- mação. O objetivo é maximizar a produtividade minimizando os erros”. Os sistemas de SCM vêm sendo aprimorados desde a década de 1980 e atualmente oferecem inúmeras funcionalidades. Vamos destacar três funções importantes para boa gestão de um repositório: • Gerenciamento de componente: responsável por manter o controle das várias ver- sões dos componentes e garantir que as alterações feitas por diferentes desenvolvedores não interfiram umas nas outras; • Construção de sistema: controla o uso dos componentes, documentação e biblio- tecas que compõem um sistema; • Gerenciamento de mudanças: acompanha as solicitações de mudanças no software de clientes e desenvolvedores; identifica data, solicitante da mudança; documenta resul- tado da análise do pedido e impacto da decisão. “Não há nada permanente, exceto as mudanças.” HERÁCLITO, 500 a.C. 17 UNIDADE Técnicas de Reuso Material Complementar Indicações para saber mais sobre os assuntos abordados nesta Unidade: Sites OHUB https://bit.ly/3gaLvIg Vídeos Gerencia de Configuracao no Tech Day Introdução ao Gerenciamento de Configuração de Software. https://youtu.be/1UUC_EuNKHo Leitura Gerência de configuração de software https://bit.ly/3uQRG8I Comparison of open-source configuration management software Lista comparativa de sistemas SCM. https://bit.ly/3ti9B7R 18 19 Referências ERL, T. SOA: princípios de design de serviços. 1ª edição. Rio de Janeiro: Prantice Hall Brasil, 2008. HEINEMAN, G.; COUNCIL, W. Component-based software engineering: putting pieces together. Boston: Addison-Wesley, 2001. PRESSMAN, R. MAXIM, B. Engenharia de Software, uma abordagem profissional. 7ª edição. Porto Alegre: AMGH, 2007. SOMMERVILLE, I. Engenharia de Software. 9ª edição. São Paulo: Pearson, 2011. 19
Compartilhar