quinta-feira, 19 de abril de 2012

Engenharia de Software Para Concursos - Parte 2 - Sommerville - Processos e Modelos de Processos de Software


Processo de Software

Processo de software é um conjunto de atividades que levam à produção de um produto de software. Essas atividades podem envolver a criação de novo software do zero ou extensão e modificação de sistemas existentes. Podem envolver ainda a configuração e integração de softwares de prateleira ou componentes prontos com os sistemas em desenvolvimento.

Todos os processos de software possuem 4 atividades fundamentais:

Especificação do software, design (projeto) e implementação, validação e evolução

Quando se fala em processos, discute-se as atividades que serão feitas e em que ordem elas serão feitas. Além de atividades, as descrições dos processos de software também incluem: produtos, papéis, pré e pós-condiçòes.

1) Produtos: são as saídas produzidas pelas atividades dos processos.
2) Papeis (roles): refletem as responsabilidades das pessoas envolvidas
3) Pré e Pós-condições: são "declarações / questões / condições" que devem ser verdadeiras antes e depois da realização do produto. Exemplo: antes da elaboração da arquitetura, uma pré-condição seria ter todos os requisitos aprovados pelo cliente. Uma pós-condição poderia ser ter todos os modelos UML que drescrevem a arquitetura revisados.

As vezes os processos de software são classificados de duas formas: Orientados a planos (estratégias) e os ágeis. Os primeiros são aqueles onde todas as atividades são planejadas antecipadamente e o progresso é comparado ao plano.  Nos ágeis o planejamento é incremental (ou evolucionário) e é fácil de mudar o processo para refletir as necessidades de mudança do cliente. Cada abordagem é apropriada para um tipo de software. Normalmente é recomendado um equilíbrio entre os dois casos.

Embora não exista processo de software ideal, existem pontos que podem ser melhorados. Os processos podem estar usando técnicas ultrapassadas ou não utilizar as melhores praticas da ESW. O processo de software também pode ser aprimorado através de pradronização. Isso melhora a comunicação e reduz o tempo de treinamento. Os processos automatizados se tornam mais econômicos.

Modelos de Processo de Software

São representações simplificadas do processo de software. Util para abordar o processo de uma determinada perspectiva focando no que é necessário para a abordagem em questão.

Os modelos genéricos são abstrações usadas para explicar diferentes abordagens para o desenvolvimento de software. Podem ser pensados como frameworks para criação de processos de ESW mais específicos.

Vamos falar de 3 modelos diferentes que NÃO são mutuamente exclusivos e as vezes são utilizados em conjunto:

1) Modelo em Cascata - coloca as atividades dos processos fundamentais de especificação, desenvolvimento, validação e evolução em fases sequênciais separadas.

2) Desenvolvimento Incremental (ou evolucionário) - essa abordagem intercala as atividades dos processos de especificação, desenvolvimento e validação. Cada nova versão trás um incremento em relação a versão anterior.

3) Engenharia de Software Orientada a Reuso - essa abordagem é baseada na existência de grande número de componentes prontos. O desenvolvimento do sistema é focado na integração destes componentes em um sistema.
 
Modelo em Cascata
O modelo em cascata é um exemplo de processo orientado a plano (estratégia). A princípio deve-se planejar e agendar todas as atividades do processo antes de começar a trabalhar com elas de fato. Abaixo, as etapas:

1) Análise de requisitos e definição: Os serviços do sistema, restrições e objetivos são estabelecidos em conjunto com os usuários. São definidos em detalhes e servem como especificação do sistema.

2) Design do software e do sistema: O processo de design (projeto) de sistemas define uma arquitetura para o sistema de forma a contemplar todos os requisitos de hardware e software. O design  (projeto) de software envolve definir as abstrações fundamentais do software do sistema e seus relacionamentos

3) Implementação e teste unitário: O projeto é implementado como um conjunto de programas ou unidades de programas. Teste unitário é a verificação de cada unidade de acordo com as especificações.

4) Integração e teste de sistema: As unidades individuais ou programas são integrados e testados como um sistema completo. Depois de assegurado que tudo funciona conforme requisitos, o sistema é entregue ao cliente.

5) Operação e manutenção: Normalmente esta é a maior fase do ciclo de vida. O sistema é colocado em produção. Envolve a correção de erros não descobertos anteriormente, melhorias na implementação das unidades do sistema e evolução do sistema através de novos requisitos.

Em pincípio, uma nova fase não deve começar antes do fim da fase anterior. Na prática essas fases ficam em sobreposição. O processo de software não é linear e depende do feedback de uma fase para a outra.

Normalmente os requisitos são congelados em determinado momento para evitar os custos de mudanças. Por isso, muitas vezes os sistemas não fazem o que o usuário quer ou possuem problemas de projeto que são resolvidos com gambiarras durante implementação (programação).

O processo em cascata é fácil de ser utilizado, gera documentos em cada fase e por isso é visível e controlável pelos gerentes. Por outro lado, a divisão das fases é inflexível e compromissos precisam ser assumidos prematuramente no processo. Isso dificulta mudanças de acordo com a vontade do cliente. Só deveria ser usado quando os requisitos fossem bem conhecidos e não tiverem tendência de mudanças (PS: ou seja, nunca!)

O modelo formal de desenvolvimento é uma variação do modelo em cascata e usa uma abordagem matemática para demonstrar aos clientes que o sistema é seguro e está de acordo com os requisitos. Usado apenas para sistemas críticos.

Desenvolvimento Incremental ou Evolucionário
Desenvolve-se uma implementação inicial, mostra-se ao cliente e através do feedback o sistema é evoluído em diversas versões até se tornar um sistema adequado. Especificação, desenvolvimento e testes são atividades intercaladas.

O modelo incremental (ou evolucionário) é a base das metodologias ágeis e é melhor que o modelo em cascata para a maioria dos sistemas negociais e pessoais. É mais barato e mais fácil fazer as alterações no software enquanto ele está sendo desenvolvido.

A cada nova versão o sistema incorpora novas funcionalidades desejadas pelo cliente. As funcionalidades mais importantes e urgentes do sistema costumam ser desenvolvidas primeiro, assim o cliente já pode avaliar o funcionamento do software no início e mudar se quiser.


Abaixo, três importantes benefícios do Modelo Incremental:

1) O custo de mudanças é reduzido. A quantidade de documentação e analise a ser refeita é muito menor que no modelo em cascata.

2) É mais fácil obter feedback do cliente porque ele pode ver como o software funciona e o quanto já foi implementado.

3) É possível entregar software funcionando mais rápidamente gerando valor para o cliente mais cedo.

O desenvolvimento evolucionário possui seus problemas: empresas grandes possuem possuem procedimentos burocráticos que evoluíram com o tempo e estes existem por motivos fortes. As vezes, até mesmo procedimentos definidos em leis. Assim, processos menos formais podem ser difíceis de ser implementados.

Essa é a abordagem mais comum no desenvolvimento de software atualmente, seja de forma ágil ou  dirigida a planos. No último caso, as iterações são definidas com antecedência.

Os Gerentes (sempre eles) enxergam dois tipos de problemas:

1) O processo não é visível. Para medir o progresso é necessário entregas regulares. Com entregas muito regulares o custo de atualização de documentação não é viável.

2)  Quando não existe refactoring de código - o que gera custos e gasta tempo - a estrutura do sistema tende a se degradar. Neste caso, incorporar novo software ao que já existe custa mais caro com o passar do tempo.

Os problemas do desenvolvimento incremental são acentuados em sistemas grandes e longos, principalmente quando equipes diferentes desenvolvem o sistema.

Engenharia de Software orientado a reúso
A abordagem orientada a reuso conta com uma larga base de componentes de software reutilizáveis e um framework de integração para fazer a composição destes componentes. Na maioria dos projetos de software acontece o reuso, mas normalmente de modo informal.

Os estágios de requisitos e de validação são semelhantes aos estágios dos outros modelos, mas as outras frases são diferentes.

1) Análise de Componentes - procura-se componentes que atendam os requisitos especificados. Normalmente, os componentes não atendem a necessidade completamente e são usados parcialmente.

2) Modificação de requisitos - Os requisitos são analisados de acordo com os componentes e modificados de acordo com as possibilidades dos componentes encontrados. Se a modificação for impossível deve-se retornar para Análise de Componentes para busca de soluções alternativas.

3) Design (projeto) do sistema com reuso - O framework é projetado para o sistema ou um framework é reutilizado. Os projetistas levam em consideração os componentes e organizam o framework de forma compatível. Alguns programas pode ser escritos caso não exista componentes disponíveis.

4) Desenvolvimento e integração - Softwares que não podem ser obtidos são desenvolvidos e os componentes ou softwares de prateleira (COTS) são integrados para criar um novo sistema. Nesse caso, a integração faz parte do desenvolvimento.

Existem 3 tipos de componentes que podem ser reutilizados:

1) Web services
2) Coleção de objetos desenvolvidos como pacotes para ser integrados a um framework de componentes (.NET or JEE são exemplos de frameworks deste tipo)
3) Sistemas de softwares stand-alone

Esse modelo de processo reduz a quantidade de software a ser desenvolvido, reduzindo assim custos e riscos, levando a um desenvolvimento teóricamente mais rápido. Por outro lado, os requisitos sempre ficam prejudicados de alguma forma, o que pode levar a um sistema que não supre as necessidades reais do cliente. Também não se tem pleno controle a respeito da evolução do sistema, já que novas versões dos componentes não estão sob controle.