Buscar

Resumo Engenharia de Software Sommerville

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 21 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 21 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 21 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

EE2 - Engenharia de Software e Sistemas
Resumo baseado no Livro Engenharia de Software Sommerville e Slides do Professor
Verificação e Validação (V & V)
Validação: estamos construindo o produto correto? Se atende as expectativas do cliente.
Verificação: estamos construindo o produto corretamente? Verifica se o software está de acordo com a especificação.
Fatores que influenciam para analise da confiança adequada no software, de acordo com a sua funcionalidade:
Função do Software: O nível de confiabilidade necessário depende de quão critico é o software.
Expectativas do usuário: se o software com falhas ainda é aceitável
Ambiente de mercado: o quão vale um maior custo de verificação e validação. É mais importante um software mais barato ou com menos erros.
Abordagens complementares para a verificação e análise de sistema:
Inspeções de software ou revisão em pares: analisam e verificam documento de requisitos, diagramas de projeto e código-fonte de programa. É uma técnica estática, pois não é preciso executar o software. Não pode verificar se o software é útil operacionalmente.
Teste de software: Técnica dinâmica e principal na V & V. Executar a implementação e analisar resultados. Podem revelar presença de erros, não a sua ausência.
Teste de Validação: é o que o cliente deseja, atende aos requisitos. Podem ser feitos testes estatísticos para verificar desempenho.
Teste de defeitos: destinado a revelar problemas na implementação: inconsistência entre programa e especificação.
Inspeções podem ser feitas em todas as etapas de desenvolvimento do software, teste apenas quando um protótipo ou versão executável.
V & V e debugging são processos feitos de forma intercalada, ao encontrar um erro ele é prontamente corrigido.
V & V: estabelece a existência de defeitos.
Debugging: localiza e corrige os defeitos.
Planejamento de verificação e validação:
Processo de Teste: descrição das fases principais do processo de teste.
Rastreabilidade de requisitos: Cada requisito é testado individualmente
Itens testados: os produtos do processo de software a serem testados devem ser especificados.
Cronograma de Testes: quando devem ser realizados os testes, alocação de recursos para os mesmos.
Procedimento de registro de testes: resultados dos testes devem ser registrados
Requisitos de hardware e de software: quais as ferramentas utilizadas e qual o uso de hardware
Restrições: o que afeta o processo de teste.
Inspeções de software:
Geralmente focado no código-fonte, mas a inspeção dos requisitos também ocorre. Conhecimento sobre o domínio e sobre programação aumentam a eficácia.
Vantagens ta inspeção sobre o teste:
Durante testes, erros podem mascarar outros erros. Testes detectam erros não sua ausência. Em uma única sessão de inspeção você pode localizar vários erros.
Em inspeções versão incompletas podem ser inspecionadas, enquanto que para testes você precisaria desenvolver testes especializados, que aumentariam o custo.
Em inspeções você pode encontrar mais detalhadamente erros do programa como algoritmos ineficientes ou inadequados.
Estudos comprovam que inspeções são mais eficientes para a detecção de erros. Mas não exclui a necessidade de testes.
Inspeções de Programa: revisões cujo objetivo é detecção de defeitos de programa.
A diferença básica entre outras revisões de qualidade é que o objetivo especifico das inspeções é encontrar os defeitos do programa, mais do que considerar questões mais amplas do projeto. Voltada explicitamente para detecção e não correção de erros.
 Para uma inspeção é necessário: a equipe de inspeção disponha de uma especificação precisa, os membros devem esta familiarizados com todos os aspectos projeto.
Uma visão geral do sistema é apresentado à equipe, então ocorre a inspeção, os erros descobertos são anotados. Modificações são feitas por quem desenvolveu o software (autor/proprietário). Uma nova inspeção pode ou não ser necessária.
Checklists de inspeção: usada para direcionar a inspeção, refletem os erros mais comuns de uma determinada linguagem de programação.
Inspeções podem executar o sistema através de passo-a-passo de seu código.
Análise estática automatizada: varre o texto do programa e tenta descobrir condições potencialmente errôneas.
Um complemento, mas não um substituto
Estágios na analise: 
Análise de fluxo de controle: Verifica loops, múltiplos pontos de saída ou de entrada e códigos inacessíveis.
Análise de uso de dados: detecta variáveis não inicializada ou não usadas. E condições redundantes: sempre verdadeiras ou sempre falcas. 
Análise de interfase: verifica a consistência das declarações de rotina e procedimento e seus usos. Verifica procedimentos nunca usados.
Análise de fluxo de informações: detecta a dependência entre variáveis, logo detecta valores que foram erroneamente computados. 
Análise de caminho: identifica todos os caminhos possíveis de um programa. 
São muitos os tipos de analises possíveis, mas elas são limitadas: escalabilidade, completude, precisão, excesso de informações.
Esse tipo de análise é mais comum em linguagens como C, que tem tipagem fraca.
Linguagens como Java tem tipo forte, mas analises mais sofisticada podem ser úteis. 
Teste de Software
Falha: incapacidade do software de realizar a função requisitada. Ex: terminação anormal
Falta: causa de uma falha. Ex: código incorreto ou faltando
Erro: estado intermediário, provém de uma falta, pode resultar em falha
Falta Erro Falha
Confiabilidade de software: estimativa probabilística que mede com qual freqüência o software irá executar sem erros.
Dados de testes: entradas selecionadas para testar o software
Casos de teste: dados de teste, saídas esperadas e cenários específicos da execução.
Eficácia de testes: um bom caso de teste é aquele com mais probabilidade de revelar um erro e que simula bem o ambiente do usuário final.
Testes de componentes: teste de componentes individuais de programa
Teste de sistema: teste de grupo de componentes integrados
Teste de defeitos: tem como meta descobrir defeitos em programas. Os testes podem ser extremos, acima da necessidade de como o sistema será usado.
Teste de sistemas: envolve a integração de dois ou mais componentes.
Teste de integração: teste para detecção de erros decorridos de interações falhas entre componentes. Para facilitar a detecção uma integração incremental é recomendada.
Teste de regressão: ao realizar mais um incremento na integração, testes passados podem ser refeitos.
Teste de releases ou teste de aceitação: teste de uma versão do sistema que será distribuída a clientes. Tem como meta aumentar a confiança de que o software atende aos requisitos. É um teste de caixa-preta. As diretrizes, recomendações, para escolha de testes são: 
Entradas que forcem o sistema a gerar erros (mensagens, overflow) e saídas invalidas
Forçar a cálculos muito grande e muito pequenos.
Repetir a mesma entrada ou uma serie de entradas varias vezes.
Teste de desempenho ou teste de estresse: serie de testes onde a carga é constantemente aumentada até que o desempenho do sistema se torne inaceitável. Causa o surgimento de defeitos. Leva o sistema ao extremo, altamente útil para testar falhas em grande número de acessos a rede ou banco de dados.
Tipos de Teste:
Teste de Segurança e controle de acesso: verifica se todos os mecanismos de proteção estão funcionando e forma satisfatória.
Teste de integridade de dados: verifica a corretude dos métodos de acesso ao banco de dados, verifica a garantia de das informações.
Teste de configuração ou portabilidade: Verifica se o sistema funciona nas diversas plataformas (tipos de conexão com a internet, software/hardware, browser, configuração do servidor)
Teste de instalação e desinstalação: funcionalidade do instalador e desinstalador sob as múltiplas condições de instalação.
Teste de Documentação: verifica se a documentação corresponde à informação correta e apropriada.
Teste de ciclo de negócios: garante que o sistema funciona corretamentedurante o ciclo de negócio.
Teste de Componentes ou teste de unidade:
Tipos de componentes que podem ser testados:
Funções ou métodos
Classes de um objeto
Componentes compostos que constituem diferentes objetos ou funções. Esses componentes compostos têm uma interface definida usada para acessar sua funcionalidade.
Ao testar uma classe de objetos, os testes devem abranger todas as características do objeto:
Teste de todas as operações associadas ao objeto
Atribuir e interrogar todos os atributos associados ao objeto.
Simular todos os eventos que provocam mudança de estados do objeto.
Teste de interfaces: existem vários tipos de interface, logo diferentes tipo de erros possíveis:
Interface de parâmetros: dados são passados de um procedimento para outro
Interfaces de memória compartilhada: um bloco de memória é compartilhado entre funções ou procedimentos.
Interfaces de procedimentos: um subsistema engloba um conjunto de procedimentos para serem chamados por outros subsistemas.
Interfaces de passagem de mensagem: um componente solicita serviço a outro componente passando uma mensagem para ele. E recebe como resposta uma mensagem.
Erros de interface: 
Mau uso de interface: um componente chama um outro componente e comete um erro no uso de sua interface, passando, por exemplo, atributos fora de ordem.
Mau entendimento da interface: falso entendimento sobre comportamento de um componente.
Erros de timing: componentes chamados funcionam em velocidade diferente da esperada, como resultado informações desatualizadas são acessadas.
Projeto de casos de teste: a meta é criar um conjunto de testes que sejam eficazes em validação de testes de defeitos.
Teste baseado em requisitos: todos os requisitos são testados e vários testes são gerados para um mesmo requisito
Teste de partição: o conjunto de testes possíveis é dividido em “classes” equivalentes (partições de equivalência), ou seja, quando um teste dessa classe retornar um valor esperado todos dessa classe iram, isso reduz o número de casos testados. Ex: números positivos, entradas validas, entradas invalidas, etc. Usar seqüência de tamanhos diferentes em testes diferentes
Teste estrutural ou teste caixa-de-vidro: derivação de casos de teste de acordo com a estrutura do programa. Exercitar todas as declarações do programa, não todos os caminhos.
Teste de caminho: testar se cada caminho independente do programa é executado pelo menos uma vez. Se todos os caminhos forem executados, pode-se assegurar que cada declaração no método foi executada pelo menos uma vez e cada ramo foi exercitado às condições verdadeiras e falsas.
Complexidade ciclomática: numero de caminhos possíveis de um código. Poucas evidencias de que é uma ferramenta de previsão de esforço de teste mais confiável do que linhas de código. 
(e-n +2) | e = arestas do grafo | n = nº nos do grafo
Baixa à moderada: < 20
Alta: > 20
Muito alta: > 50
Automação de testes: os workbenches de testes fornecem uma variedade de ferramentas que executam testes automaticamente, como o conjunto de classe de Java JUnit. Eles podem simular parte do projeto que não foi implementado a fim de gerar dados de teste. Os workbenches podem ser adaptados para o sistema. Saídas de teste podem ser preparadas manualmente para comparação.
Gerenciamento de Configuração
Um gerenciamento de sistema de software em desenvolvimento tem que ser feito, pois requisitos mudam durante o desenvolvimento e uso. Logo um gerenciamento tem de ser feito, pois é fácil perder a rastreabilidade de quais mudanças foram incorporadas. Envolve o desenvolvimento e a aplicação de procedimentos e padrões para gerenciar um produto de software em evolução.
Novas versão são criadas quando:
Mudam para maquinas SO diferentes
Oferecem funcionalidade diferente
São configuradas para requisitos de usuários particulares
O processo de gerenciamento de mudança precisa alcançar equilíbrio entre burocracia e rastreabilidade. 
Planejamento de gerenciamento de configuração: 
Todos os produtos do processo de software podem ser gerenciados: especificação, projetos, programas, dados de teste, manuais do usuário.
Principais atividades do gerenciamento de configuração:
Controle de versão
Gerenciamento e registro de mudanças
Organização e geração dos Builds do sistema.
Gerenciamento de mudanças: os softwares estão sujeitos as mudanças continuas por parte dos usuários, desenvolvedores ou forças do mercado. O gerenciamento de mudanças visa rastrear essas mudanças para que os reparos corrijam falhas e as falhas em decorrência desses reparos sejam facilmente detectável. 
Acompanhamento de mudanças: o maior problema no gerenciamento de mudanças é acompanhar o seu status, mas ferramentas de gerenciamento fornecem meios de acompanhar esse processo, existe uma possibilidade de envio de e-mails automáticos de solicitação de mudanças.
Comitê de controle de mudanças (CCB): mudanças pode ser revisadas por um grupo que decide se são adequadas em vários aspectos. Pode conter representantes tanto do cliente quanto do pessoal fornecedor.
Procedência histórica: um tipo de “linha do tempo” das mudanças. Registra as mudanças (por quem foi feita, quando e a razão)
Gerenciamento de versões e releases: elabora um esquema de identificação de versões de forma a identificá-las de forma única, bem como planejamento de nova versão. Assegura que procedimentos e ferramentas de gerenciamento das versões sejam adequadamente aplicados. 
Versões: apresenta funcionalidades distintas, de alguma forma, de outras instâncias do sistema.
Variante: apenas pequenas diferenças em relação a outras instâncias.
Release: instâncias do sistema distribuído pra alguém que não faz parte da equipe de desenvolvimento.
Técnicas para identificação de componentes: 
Numeração de versões
Identificação baseada em atributos: Os atributos podem ser associados a uma versão com a combinação de atributos que a identificam.
Consulta baseada em atributos: Ex. ‘a mais recente versão em Java’, etc.
Identificação orientada a mudanças: cada componente é denominado como na identificação de baseada em atributos, mas é também associado a algumas solicitações de mudanças.
Branching e Merging: elemento fundamental no gerenciamento de configurações. Compromisso entre produtividade e risco.
Branching: usar diferentes “ramos” de desenvolvimento para aumentar o paralelismo. Branchs são uteis para implementar mudanças ou funcionalidade pontual, com eles é possível atribuir tarefas a todos da equipe.
Branch = um ramo
Código não é compartilhado entre branches
Merging: a combinação de uma desses ramos com o ramo principal. Diferenças entre os branches combinados precisam ser resolvidas
Funcionalidades de um Sistema de Controle de Versões: 
Manutenção de um repositório de itens de configuração com suporte ao checkin e ao checkout distribuídos 
Criação e manutenção de informações de múltiplas versões 
 Criação e merging de branches 
Capacidade de realizar consultas sobre versões dos sistemas, com base em seus atributos
Construção (build) de sistemas: É o processo de compilação e ligação de componentes de software em um sistema executável, varias combinações podem ser feitas, e logo diversos sistemas. Esse processo é apoiado por ferramentas automatizadas que são dirigidas por ‘scripts de construção’.
Construção de sistemas: A construção de um sistemas é algo altamente dispendioso. Ferramentas de construção de sistemas podem fornecer:
Uma linguagem de especificação de dependência e um interpretador associado
Seleção de ferramentas e apoio à instanciação
Compilação distribuída
Gerenciamento de objetos derivados.
Reuso de Software
Na maioria das disciplinas de engenharia, os sistemas são projetados por meio de composição de componentes existentes, porém em engenharia de software, grande parte de um novo sistema é construída do zero. Essa situação vem mudando.
Modalidades de reuso:
Reuso do sistema da aplicação: um sistema inteiro pode ser reusado por incorporação a outrossistemas sem mudanças.
Reuso de componentes: componentes de uma aplicação como subsistemas ou objetos simples.
Reuso de bibliotecas
Reuso de conhecimento: princípios e padrões
Benefícios:
Confiança aumentada: software reusado já foi testado mais vezes, erros já foram encontrados e corrigidos.
Risco de processo reduzido: custo de software existente é conhecido, enquanto que os custos de desenvolvimento são altamente variantes.
Uso eficiente de especialistas: em vez de fazer o mesmo trabalho repetidamente, eles podem desenvolver software reusável englobando os seus conhecimentos.
Conformidade com padrões: interfaces padronizadas fazem reuso, o que poupa tempo, gera mais facilidade no uso por parte do usuário leigo.
Desenvolvimento acelerado: apresentação de uma versão rapidamente ao mercado vale mais do que custos. O reuso faz com que essa rapidez ocorra, pois tempo de desenvolvimento e validação são reduzidos.
Problemas: 
Custos de manutenção aumentados: se o código-fonte do componente não estiver disponível os custos de manutenção poderão ser aumentados.
Falta de apoio de ferramenta: o conjunto de ferramentas CASE podem não apoiar o desenvolvimento com reuso.
Síndrome de não-inventado-aqui: Alguns engenheiros de software preferem reescrever componentes porque acreditam que podem aprimorá-los. E porque escrever um software original é mais desafiador do que reusar.
Criação e manutenção de uma biblioteca de componentes: preencher uma biblioteca de componentes reusáveis e assegurar aos desenvolvedores que podem usar essa biblioteca é algo caro.
Procura, compreensão e adaptação de componentes reusáveis
Panorama do reuso: Existem muitas abordagens diferentes para reuso, em uma variedade de níveis, desde funções simples até sistemas completos de aplicação. 
Reuso Acidental vs. Reuso Sistemático 
Desenvolvimento com Reuso vs. Desenvolvimento para Reuso
Fatores de planejamento de reuso:
O cronograma de desenvolvimento para o software: se o software tem que ser desenvolvido rapidamente 
O ciclo de vida previsto do software: software de vida longa deve ter fácil manutenção
O conhecimento, habilidades e experiência da equipe de desenvolvimento: uma equipe experiente tem mais facilidade de trabalhar com tecnologias de reuso complexas.
A importância do software e seus requisitos não funcionais: para sistemas críticos é necessário criar um caso de confiança para o sistema. 
O domínio da aplicação: em alguns domínios de aplicação, tal como sistemas de informações industriais e médicos, há vários produtos genéricos que podem ser reusados por meio de configuração par uma situação específica.
A plataforma de execução para o software: alguns componentes são específicos para uma determinada plataforma, então seu sistema só poderá reusá-lo caso seja para essa plataforma.
A abordagem de reuso empregada
Frameworks: um projeto de sistema ou subsistema feito de uma coleção de classes e as interfaces entre elas. É instanciado através da implementação de classes concretas que estendem certas partes abstratas do framework. Frameworks são entidades genéricas e moderadamente complexas que geram um esforço para compreendê-los, mas podem promover grande economia de esforço
Classes abstratas e interfaces Hotspots 
Classes de framworks: 
Frameworks de infra-estrutura de sistema: Apóiam o desenvolvimento de partes fundamentais de um sistemas, tais como comunicações, interfaces de usuário e compiladores. 
Frameworks de integração/middleware: Padrões e classes que apóiam a comunicação e a troca de informações de componentes. 
Frameworks de domínio específico: Apóiam o desenvolvimento de tipos específicos de aplicações, tais como sistemas médicos, de telecomunicações e financeiros
Reuso de sistemas: 
Reuso de aplicações inteiras: integração de vários sistemas para criar uma nova aplicação, ou pela configuração de um sistema para um ambiente.
Reuso de componentes COTS (Commercial Off-The-Shelf systems): geralmente são sistemas de aplicação completos que oferecem uma API.
É uma estratégia viável de desenvolvimento para alguns tipos de sistemas tais como os de e-commerce. 
O benefício-chave é o desenvolvimento mais rápido da aplicação. Geralmente com um custo menor 
Há duvidas quanto:
Ao produto COTS oferece a funcionalidade mais apropriada. Já que pode haver diversos produtos similares que podem ser usados. 
Como os dados serão trocados. Produtos individuais usam estruturas únicas de dados e formatos. 
Quais características do produto serão realmente usadas? A maioria dos produtos tem mais funcionalidade do que é necessário
Problemas de integração de sistemas COTS
Falta de controle sobre funcionalidades e características de qualidade
Problemas com a interoperabilidade, pois sistemas COTS diferentes podem fazer suposições diferentes 
Nenhum controle sobre a evolução do sistema 
Evolução de Software de Refatoração
As organizações fazem grandes investimentos em seus sistemas de software – eles são ativos críticos de negócios. Para manter o valor desses ativos de negócio, eles devem ser mudados e atualizados. A maior parte do orçamento de software nas grandes organizações é voltada para evolução, ao invés do desenvolvimento de sistemas novos
Dinâmica de evolução de programas: é o estudo de mudança de sistema. 
Lehman e Belady propuseram que havia uma série de ‘leis’ (hipóteses) que se aplicavam a todos os sistemas quando eles evoluíam. Na prática, são observáveis, de fato, em sua grande maioria em sistemas de grande porte
Lei de Lehman: 
Mudança contínua: Manutenção é um processo inevitável. 
Complexidade crescente: Alteração do sistema degrada sua estrutura 
Evolução de programa de grande porte: Sistemas de grande porte possuem dinâmica própria (estágios iniciais de desenvolvimento) 
Estabilidade organizacional: Estado saturado. Mudanças de recursos e pessoal não têm efeito. 	
Novas funcionalidades introduzem novos defeitos, logo não orçar grandes incrementos sem pensar nas correções de defeitos 
Qualidade em declínio: Declínio da qualidade e insatisfação dos usuários 
Aprimoramento a partir de sistemas de feedback 
Manutenção de software: É a modificação de um programa após ter sido colocado em uso. Normalmente não envolve mudanças consideráveis na arquitetura do sistema. Ocorrem pela modificação de componentes existentes e pela adição de novos componentes ao sistema.
Tipos de manutenção:
Manutenção para reparar defeitos de software 
Manutenção para adaptar o software a um ambiente operacional diferente 
Manutenção para adicionar funcionalidade ao sistema ou modificá-lo 
Custos de manutenção: Geralmente, são maiores que os custos de desenvolvimento (de 2 a 100 vezes, dependendo da aplicação). 
A manutenção corrompe a estrutura do software, tornando a manutenção posterior mais difícil e cara.
Fatores de custo de manutenção:
Estabilidade da equipe: custos são reduzidos se o mesmo pessoal estiver envolvido por algum tempo. 
Responsabilidade contratual: Os desenvolvedores podem não ter responsabilidade pela manutenção, portanto, não há incentivo para projetar para mudanças futuras. 
Habilidade do pessoal: O pessoal da manutenção geralmente é inexperiente e tem conhecimento limitado de domínio. 
Idade e estrutura do programa: À medida que os programas envelhecem, sua estrutura é degradada e se torna mais difícil de ser compreendida e modificada.
Previsão de manutenção: Avaliação de quais partes do sistema pode causar problemas e ter altos custos de manutenção. 
Processos de evolução: dependem do tipo de software que está sendo mantido, dos processos de desenvolvimento usados, das habilidades e das experiências do pessoal envolvido.
Propostas para mudança são os direcionadores para a evolução do sistema. 
Metodologias mais novas não costumam ter um processo separado
Previsão de mudanças: A previsão do número de mudanças requer o entendimento dos relacionamentos entre um sistema e seu ambiente. 
Sistemas fortemente acoplados requerem mudanças sempre que o ambienteé mudado. 
Medidas de processo podem ser usadas para avaliar a facilidade de manutenção. Se qualquer uma ou todas essas estão aumentando, isso pode indicar um declínio na facilidade de manutenção:
Número de solicitações para manutenção corretiva; 
Tempo médio necessário para análise de impacto; 
Tempo médio para implementar uma solicitação de mudança; 
Número de solicitações de mudança pendentes. 
Solicitação de mudanças urgentes pode ter de ser executadas sem passar por todos os estágios do processo de desenvolvimento de software.
Se um defeito sério de sistema tem de ser reparado
Se mudanças no ambiente do sistema têm efeitos inesperados; 
Se existem mudanças de negócio que necessitam de uma resposta muito rápida (e.g. mudança de lei) 
POP (Patch-Oriented Programming) Podem resultar em problemas ainda piores
Reengenharia de sistema: É a reestruturação ou reescrita de parte ou de todo um sistema sem mudar sua funcionalidade. Aplicável onde partes de um sistema de grande porte necessitam de manutenção freqüente. Simplicidade é um objetivo complexo. Atividades:
Conversão de código-fonte: Converter o código para uma nova linguagem. 
Engenharia reversa: Analisar o programa para compreendê-lo. 
Aprimoramento da estrutura de programa: Analisar e modificar a estrutura para facilidade de entendimento. 
Modularização de programa: Reorganizar a estrutura do programa. 
Reengenharia de dados: Limpar e reestruturar os dados do sistema.
Fatores de custo da reengenharia: 
A qualidade do software que deve passar pela reengenharia. 
O apoio de ferramentas disponíveis para reengenharia. 
Extensão da conversão de dados. 
A disponibilidade do pessoal especializado: principalmente em sistemas antigos.
Refatoração: Uma pequena modificação no sistema que não altera o seu comportamento funcional final, mas que melhora alguma qualidade não-funcional: simplicidade, flexibilidade e clareza. Cada passo da refatoração é trivial, rápido, sistemático, obvio. Geralmente é automatizada por ferramentas. É importante para desenvolvimento e evolução
Exemplos:
Mudança do nome de variáveis 
Mudanças nas interfaces dos objetos 
Pequenas mudanças arquiteturais 
Encapsular código repetido em um novo método 
Generalização de métodos
Refatoração pode adicionar erros, mesmo em casos automatizados, então antes de começá-la casos de teste devem ser estruturados para a ajudar a detectar os erros.
Formato da estrada de refatoração:
Nome da refatoração. 
Resumo da situação na qual ela é necessária e o que ela faz. 
Motivação para usá-la (e quando não usá-la). 
Mecânica, i.e., descrição passo a passo. 
Exemplos para ilustrar o uso.
Qualidade de Software
Dedica-se a assegurar que o nível requerido de qualidade seja atingido. Envolve a definição de padrões e procedimentos apropriados de qualidade e a garantia de que sejam seguidos. Deve visar o desenvolvimento de uma ‘cultura de qualidade’ 
Qualidade deve atender às sua especificação
Problemas:
Tensão entre os requisitos de qualidade do cliente (eficiência, confiabilidade, etc.) e requisitos de qualidade do desenvolvedor (facilidade de manutenção, reusabilidade, etc.) 
Alguns requisitos de qualidade são difíceis de especificar de uma maneira não-ambígua 
As especificações de software são, geralmente, incompletas e freqüentemente inconsistentes
Gerenciamento de qualidade é particularmente importante para sistemas grandes e complexos 
A documentação de qualidade é um registro do progresso 
Equipes menores menos documentos de gerenciamento de qualidade
Atividades de gerenciamento de qualidade: 
Garantia de qualidade: Estabelece procedimentos e padrões organizacionais para qualidade 
Planejamento de qualidade: Seleciona procedimentos e padrões aplicáveis para um projeto específico e o modifica quando necessário. 
Controle de qualidade: Assegura que os procedimentos e os padrões sejam seguidos pela equipe de desenvolvimento de software. 
O gerenciamento de qualidade deve ser separado do gerenciamento de projeto para assegurar independência Objetivos potencialmente conflitantes
Qualidade de processo e de produto: segundo alguns modelos a qualidade do processo influencia no produto. Contudo, existe uma relação complexa e pouco compreendida entre processos de software e qualidade de produto.
Qualidade baseada em processo:
 A aplicação de habilidades individuais e a experiência são muito importantes no desenvolvimento de software. 
Fatores externos, como a novidade de uma aplicação ou a necessidade de um cronograma de desenvolvimento acelerado, podem piorar a qualidade do produto. 
Deve-se tomar cuidado para não impor padrões de processo inadequados 
Padrões de processo:
Definir padrões de processo, tais como o modo como as revisões devem ser conduzidas, o gerenciamento da configuração.
Monitorar o processo de desenvolvimento para assegurar que os padrões estejam sendo seguidos 
Relatar sobre o processo para a gerência de projeto e para o comprador do software 
Não usar práticas inadequadas simplesmente porque padrões foram estabelecidos
Padrões de produto definem características que todos os componentes devem exibir Ex. um estilo de programação comum. 
Padrões de processo definem características relativas aos processos de software
Importância dos Padrões: 
Englobam as melhores práticas
São um arcabouço para os processos de garantia de qualidade
Padrões fornecem continuidade: Novos funcionários podem compreender a organização pela compreensão dos padrões que são adotados
Problemas com padrões:
Podem não ser vistos como relevantes ou atualizados pelos engenheiros de software 
Envolvem, freqüentemente, muita burocracia
Difícil manter a documentação associada 
Desenvolvimento de Padrões: 
Envolver os engenheiros na elaboração desenvolvimento: Eles devem compreender as razões de um padrão 
Revisar padrões e seu uso regularmente: Padrões podem se tornar rapidamente desatualizados e isso reduz sua credibilidade. Incorporar novas “melhores práticas” 
Padrões devem ter ferramentas de apoio
Medições métricas de software: A medição de software se dedica a derivar um valor numérico para algum atributo de um produto ou de processo de software. Permite comparações objetivas entre técnicas e processos.
Métricas de Software: Contagem de determinados elementos de um sistema de software, processo ou documento 
Permitem que o software e o processo de software sejam quantificados 
Podem ser usadas para prever atributos de produto e para controlar o processo de software. 
As métricas de produto podem ser usadas para previsões gerais ou para identificar componentes anômalos
Suposições de métricas:
Uma propriedade do software pode ser medida 
Existe um relacionamento entre o que podemos medir e o que queremos conhecer: Podemos somente medir atributos internos, mas estamos, muitas vezes, mais interessados em atributos externos de software 
Esse relacionamento foi formalizado e validado. 
O processo de medição: Um processo de medição de software pode ser parte do controle de qualidade 
Algumas métricas são difíceis de coletar de forma automatizada.   Ex. Separação de interesses
Os dados coletados durante este processo devem ser mantidos como um recurso da organização. Torna possíveis comparações entre projetos 
Recomendações: 
Não colete dados desnecessários: As questões a ser respondidas devem ser decididas previamente e os dados necessários identificados 
Conte às pessoas porque os dados estão sendo coletados: 
Não dependa da memória: Colete dados quando são gerados, e não depois que um projeto foi finalizado
Métricas de Produto: Uma métrica deve ser um previsor de qualidade de produto. 
Classes de métrica de produto 
Dinâmicas: coletadas em tempo de execução. Ajudam a avaliar a eficiência e a confiabilidade. São diretamente relacionadas aos atribuitos de qualidade de software É relativamente fácil medir o tempo de resposta de um sistema (atributo de desempenho) ou a frequência com que ele falha (atributo de confiabilidade).Estáticas: coletadas em tempo de compilação. Ajudam a avaliar a confiabilidade, a facilidade de compreensão e a facilidade de manutenção. Têm um relacionamento indireto com atributos de qualidade É necessário estabelecer um relacionamento entre essas métricas e as propriedades, tais como complexidade, facilidade de compreensão e de manutenção.
Algumas métricas são coletadas a partir de informações sobre o produto. Ex. Número de bugs conhecidos
Analise de medições: Nem sempre é óbvio o que os dados significam.
É muito importante usar métricas experimentalmente validadas
Desenvolvimento de sistemas tolerantes a falhas
Todos os usuários desejam que um sistema seja confiável, mas alguns sistemas, como os críticos demandam uma necessidade maior de confiabilidade, e então exigem técnicas especificas de engenharia de software
Para atingir a confiança medidas são tomadas:
Prevenção de falhas: O sistema é desenvolvido de modo que provadamente atenda sua especificação 
Remoção de falhas: Técnicas de verificação e de validação são usadas para descobrir e remover falhas em um sistema antes que seja entregue. 
Tolerância a falhas: O sistema é projetado de forma que as falhas no software entregue não resultem em defeitos em tempo de execução
Redundância: Parte do sistema ou de suas ações que não seria necessária se falhas não existissem. Ex: componente duplicado, reinicialização
Diversidade: Prover a mesma funcionalidade de maneiras diferentes para que eles não falhem de forma análoga
A adição de diversidade e de redundância aumenta a complexidade. Simplicidade e V & V extensivas podem ser uma rota mais eficiente para a confiança de software
Software livre de falhas: Os métodos atuais de engenharia de software permitem a produção de software livre de defeitos, sistemas relativamente pequenos. Significa que o software atende à especificação, não significa que sempre executará corretamente. 
Processos confiáveis: 	Para assegurar um número mínimo de defeitos de software, é importante ter um processo de software bem definido e repetível, que não depende inteiramente de habilidades individuais, isto é, podem ser realizados por pessoas diferentes. Para detecção de defeitos, é claro que as atividades de processo devem incluir um esforço significativo dedicado à verificação e à validação.
Atividades que ajudam na remoção de falhas: 
Inspeções de requisitos: Descoberta de problemas com a especificação 
Gerenciamento de requisitos: Acompanhamento de mudanças no projeto e implementação 
Verificação de modelos: Análise automática de modelos 
Inspeções de projeto e de codificação: Listas de defeitos comuns para descoberta e remoção deles
Análise estática: Análise de programas 
Planejamento e gerenciamento de teste: Cobertura e rastreabilidade entre testes e requisitos 
Gerenciamento de configuração: Inclusão correta de componentes no sistema 
Arquiteturas adequadas: Remoção localizada de erros. 
Tolerância a falhas: Sistemas críticos devem ser tolerantes a falhas, significa que o sistema pode continuar em operação apesar da falha do software 
Complementar a técnicas para remover falhas
Um sistema é tolerante a falhas com relação a um dado modelo de falhas 
 Falha, erro, defeito
Etapas de tolerância a defeitos, feito em tempo de execução: 
Detecção de erros: O sistema deve detectar se um erro ocorreu (um estado incorreto de sistema). Envolve a definição de restrições que devem ser mantidas em todos os estados legais, e a verificação do estado contra essas restrições
Avaliação de danos: As partes do estado de sistema afetadas pelo erro devem ser detectadas 
Recuperação de erros: O sistema deve ir para um estado ‘seguro’ estável 
Reparação de erros: O sistema pode ser modificado para evitar recorrência da falha 
Avaliação de Danos: Analisa o estado do sistema para estimar a extensão da corrupção causada por um erro. Deve verificar quais partes do estado do sistema foram afetadas pelo erro. Geralmente, é baseada em ‘funções validadas’, que podem ser aplicada aos elementos de estado para avaliar se seu valor está dentro de uma faixa permitida.
Recuperação de erros: 
Recuperação por avanço (forward error recovery): Levar o estado do sistema para um novo estado livre de erros. A recuperação por avanço é específica de aplicação 
Corrupção de dados codificados: Adicionam redundância aos dados codificados -- dados redundantes podem ser usados para reparação de dados corrompidos 
Ponteiros redundantes: Quando ponteiros redundantes são incluídos em estruturas de dados uma lista ou repositório de arquivos corrompido pode ser reconstruída se um número suficiente de ponteiros não estão corrompidos. 
Tratamento de exceções: Ênfase na estruturação
Recuperação por retrocesso (backward error recovery): Restaurar um estado anterior, livre de erros, do sistema. A recuperação por retrocesso de erros é mais simples e genérica. Não se aplica a todos os casos.
Transações são um método popular: Mudanças não são aplicadas até que a 
computação seja completada. Se um erro ocorre, o sistema é deixado no estado anterior ao da transação. 
Checkpoints locais 
Checkpoints distribuídos periódicos: Baseados em logs
Arquiteturas tolerantes a falhas: 
Técnicas de V & V não são capazes de ajudar a prever interações entre o hardware e o software. 
Mau entendimento dos requisitos pode significar que as verificações são incorretas ou incompletas 
Se requisitos de confiabilidade são críticos, pode ser usada uma arquitetura específica para apoiar tolerância a falhas 
Podem tolerar falhas de hardware e/ou de software.
Tolerância de falhas de hardware: 
Depende da redundância modular tripla (TMR)
Três componentes idênticos replicados recebem a mesma entrada e têm suas saídas comparadas 
Se uma saída é diferente, ela é ignorada e uma falha do componente é simulada. 
Premissas básica: Falhas de hardware decorrem de falhas de componentes (e.g. por desgaste natural) e não de projeto. Falhas são exceções e falhas simultâneas são raras
TMR e Software: As suposições básicas da TMR não valem para sistemas de software. Não é possível simplesmente replicar os mesmos componentes quando eles têm falhas de projeto em comum. Falhas simultâneas de componentes seriam, portanto, virtualmente inevitáveis. 
Diversidade do projeto: 
Versões diferentes do sistema são projetadas e implementadas de maneiras diferentes. Podem apresentar modos de falha diferentes. 
Abordagens diferentes para projeto:
Implementação em linguagens de programação diferentes; 
Uso de ferramentas e ambientes de desenvolvimento diferentes; 
Execução em diferentes sistemas operacionais 
Algoritmos e escolhas de projeto diferentes
Abordagem para diversidade de projeto:
Programação de N-versões: A mesma especificação é implementada em uma série de versões diferentes por equipes diferentes, logo uma baixa probabilidade dessas equipes cometerem os mesmos erros. Todas as versões calculam simultaneamente e a saída da maioria é selecionada usando um sistema de votação. Essa é a abordagem mais comumente usada, por exemplo, em muitos modelos da aeronave comercial Airbus. 
Blocos de recuperação: Uma série de versões explicitamente diferentes da mesma especificação são escritas e executadas em seqüência, reduz a probabilidade de erro comuns. Um teste de aceitação é usado para selecionar a saída a ser transmitida, que é difícil de elaborar de forma independente do algoritmo. Nem sempre é aplicado em sistema de tempo real, pois à sua operação é seqüencial.
Problema para diversidade de projeto: 
Equipes não são culturalmente diversas e tendem a resolver os problemas da mesma maneira. 
Erros característicos: 
Equipes diferentes comentem os mesmos erros. 
Algumas partes de uma implementação são mais difíceis que outras:   Equipes tendem a cometer erros no mesmo lugar; 
Falhas na especificação: são refletidas em todas as implementações; 
Esses problemas podem ser mitigados pelo uso de representações múltiplas da especificação.

Outros materiais