segunda-feira, agosto 28, 2006

A disciplina de Requisitos

O foco desta disciplina do Processo Unificado é trabalhar para construir o sistema certo. No inicio do primeiro ciclo de um projeto, ainda não se sabe exatamente qual o sistema a ser construído. O domínio é obscuro e a descrição dos requisitos pelos clientes pode vir acompanhada de ambigüidades, contradições e redundâncias.

A Engenharia de Requisitos, um dos braços da Engenharia de Software, é uma ciência destinada exclusivamente à compreensão das metas e das necessidades dos clientes em um projeto de desenvolvimento de software. As práticas, técnicas e ferramentas providas por esta ciência são grandes aliadas para um bom trabalho nesta disciplina.

Grupos como “The Requirements Engineering Specialist Group”, conferências internacionais e periódicos acadêmicos nos dão idéia da amplitude da Engenharia de Requisitos. Neste artigo vamos nos reter a discutir as atividades básicas executadas na disciplina. Em artigos futuros poderemos nos aprofundar neste tema tão complexo.

Um ponto interessante é perceber que ciências sociais, ciência cognitiva e relacionamento interpessoal são características importantes em um Engenheiro de Requisitos. Neste momento do processo, existe uma forte interação deste profissional com o cliente e é preciso preparo para identificar as ambigüidades, as contradições e as redundâncias que eventualmente aparecem.

Quatro artefatos são produzidos durante esta disciplina. São eles:

  • Modelo de Domínio:


  • Este modelo é responsável por exibir os conceitos principais do domínio em que o software está inserido e como estes se relacionam.

    É frequentemente representado por diagramas de classes conceituais da UML, ou seja, não são classes de projeto. Alguns conceitos são mantidos e tornam-se classes de projeto na elaboração da arquitetura em iterações futuras, porém, é comum que algumas classes sejam apenas conceituais e não participem do software efetivamente.

    Este modelo nos permite compreender com mais clareza o cenário em que os clientes estão envolvidos. Também é utilizado como fonte de inspiração para a nomenclatura de classes em iterações futuras.

  • Modelo de Casos de Uso:


  • Deve ser visto como uma guia para todo o processo de desenvolvimento, representa a força condutora. A idéia principal é identificar os requisitos funcionais do sistema.

    Uma vez que um dos princípios fundamentais do Processo Unificado é ser dirigido por casos de uso, temos idéia do quão fundamental é este modelo.

    É formado por pacotes de casos de uso, representando, cada um deles, um agrupamento lógico de diagramas de casos de uso da UML. Complementando o modelo, existem descrições textuais estruturadas para cada caso de uso. As descrições devem possuir, pelo menos, as seguintes informações: nome do caso de uso, ator principal, pré-condições, pós-condições, fluxo básico e fluxos alternativos de execução.

  • Requisitos Não-Funcionais:


  • Em 1992, Robert Grady listou cinco grupos de categorização de requisitos. A lista foi denominada FURPS, acrônimo com o seguinte significado, conforme o original em inglês:

    • Functionality: Requisitos funcionais.

    • Usability: Requisitos de usabilidade, como recursos de ajuda e acessibilidade.

    • Reliability: Requisitos de confiabilidade, como capacidade de recuperação após falha.

    • Performance: Requisitos de desempenho, como tempo de resposta e disponibilidade.

    • Supportability: Requisitos de suporte, como facilidade de manutenção/configuração e internacionalização.


    Como os requisitos funcionais já são cobertos pelo Modelo de Casos de Uso, o documento de requisitos não-funcionais deve conter apenas os quatro grupos restantes, ou seja, uma lista URPS.

  • Referências:


  • Este documento é apenas uma sugestão e pode ser formado por três seções: Glossário, Premissas e Referências bibliográficas e eletrônicas.

    O Glossário descreve os principais termos a serem utilizados no sistema. Cria um padrão de nomenclatura a ser utilizado pela equipe de desenvolvimento nos diálogos e na elaboração dos diversos artefatos durante o projeto. Frequentemente é uma derivação do Modelo de Domínio.

    As Premissas são considerações que justificam algumas características do sistema. A idéia é fornecer um histórico dos pensamentos e das discussões ocorridas durante o desenvolvimento. Esta seção deve auxiliar na manutenção do sistema.

    As Referências biográficas apontam quais os livros que auxiliaram no desenvolvimento pela sua teoria. Analogamente, as Referências eletrônicas apontam as páginas da Internet que foram utilizadas em eventuais pesquisas.

terça-feira, agosto 15, 2006

A estrutura do Processo Unificado

Em artigos anteriores, apresentei o conceito que define o paradigma do Processo Iterativo e os princípios fundamentais que definem uma de suas realizações mais evidentes, o Processo Unificado.

Mas como o UP (do original, em inglês, Unified Process) é estruturado?


Figura 1: Intensidade de cada uma das disciplinas no decorrer das fases em um ciclo.



Pois bem, a vida de um sistema de software é composta por uma série de ciclos. Ao final de cada ciclo, uma versão operacional do sistema é entregue aos interessados. Conforme ilustrado pela figura 1, um ciclo ainda é dividido em quatro fases: Concepção, Elaboração, Construção e Transição.

Resumidamente:

  • A Concepção é a fase onde os objetivos do ciclo de vida são identificados. Esta fase diz o que deve ser feito. O domínio é analisado e os requisitos (funcionais e não-funcionais) são compreendidos e selecionados.

  • A Elaboração é responsável pela arquitetura do sistema que será distribuído ao final do clico de vida. Esta fase diz como deve ser feito. É importante reforçar que a arquitetura deve suportar todos os requisitos selecionados. Lembre-se que um dos princípios fundamentais do UP é o fato deste ser Centrado em Arquitetura, ou seja, a Elaboração tende a ser uma fase crucial, recheada de desafios e questões complexas.

  • Na Construção, como o próprio nome sugere, o sistema é implementado de acordo com o que foi elaborado na fase anterior. Questões puramente técnicas como o encapsulamento de classes lógicas em componentes físicos marcam a fase. O sistema deve possuir a capacidade operacional adequada.

  • Por fim, a Transição é marcada pela liberação do produto aos interessados. O projeto deve ser preparado para possíveis ciclos futuros.


Cada fase é composta por uma seqüência de iterações. Tipicamente, a Concepção é composta de uma única iteração e a Transição de no máximo duas. Porém, as fases de Elaboração e de Construção contam com um número maior de iterações.

Uma característica marcante, também ilustrada na figura 1, é o fato de todas as iterações, e conseqüentemente todas as fases, serem atravessadas por todas as disciplinas, com maior ou menor intensidade.

São exatamente as disciplinas que possuem artefatos associados. Artefatos são documentos textuais ou diagramas da UML que facilitam a compreensão do sistema e a comunicação entre os envolvidos. Ou seja, é possível que um artefato de compreensão do domínio seja incrementado em mais de uma fase, mesmo sabendo que o entendimento do domínio é um dos principais objetivos da fase de Concepção.

A maioria dos artefatos produzidos ao longo dos ciclos pertence a um dos seis modelos apresentados na figura 2. Os modelos, contendo todos os seus artefatos, formam a documentação completa do processo de desenvolvimento. Esta documentação deve ser disponibilizada aos envolvidos a cada novo ciclo.

Um modelo por si só também pode ser considerado um artefato, porém, que possui outros artefatos internos, como diagramas completos e textos estruturados. Podemos qualificar um modelo como um agrupamento lógico semanticamente fechado.


Figura 2: Os seis modelos básicos do Processo Unificado.



Mesmo tendo mencionado que uma documentação que compreenda estes seis modelos é tida como completa, podemos adicionar outros documentos que sejam considerados relevantes.

Exemplos de documentos complementares:

  • Modelo de Domínio

  • Documento de requisitos não-funcionais

  • Referências

quinta-feira, agosto 10, 2006

Princípios Fundamentais do Processo Unificado

O Processo Unificado, uma realização do Processo Iterativo de Desenvolvimento de Software, possui três princípios fundamentais.

A estabilização e a consagração deste processo no mercado devem-se, principalmente, a estes princípios. São eles:

Dirigido por Casos de Uso

Para compreender o conceito "Caso de Uso", é importante conhecer o conceito "Ator". Um ator pode ser entendido com uma pessoa ou uma entidade não-humana que interage com o sistema, mas está fora dele. O exemplo mais comum de ator é o próprio usuário, porém, bancos de dados e outros sistemas também podem ser considerados atores.

Pois bem, um caso de uso é uma seqüência de ações executadas por atores e pelo sistema, a fim de satisfazer metas e necessidades destes atores.

Os casos de uso compõem a força condutora de todo o processo de desenvolvimento, desde a captação inicial de requisitos até a aceitação do código-fonte, por várias razões:


  • Primeiramente por serem expressos sob a perspectiva do usuário, em textos descritivos na língua local do cliente. Os textos devem ser intuitivos e óbvios para o leitor.

  • Outro ponto fundamental é que permitem uma compreensão direta dos requisitos do sistema. Os casos de uso não devem apresentar ambigüidades, redundâncias ou contradições. Devem especificar um contrato a ser aceito e seguido pelos integrantes da equipe de desenvolvimento e pelos clientes.

  • Permitem também um alto grau de rastreamento de requisitos nos diversos modelos que são desenvolvidos posteriormente. Manter os casos de uso à mão durante todo o processo por ser decisivo para o aceite da solução.

  • Por fim, os casos de uso facilitam a distribuição de tarefas e a alocação de trabalho.



Centrado em Arquitetura

A arquitetura é a organização fundamental do sistema como um todo. Possui elementos estáticos e dinâmicos que explicitam exatamente como cada componente é construído e como este se relaciona com os demais.

Uma boa arquitetura deve prover um alto grau de manutenibilidade. Este fato é fundamental para que a equipe de desenvolvimento possa atender as demandas que surgem em um intervalo de tempo cada vez menor, principalmente após a adoção da Internet como canal de comunicação primário.

Inúmeras corporações modelam seus negócios de acordo com a tecnologia disponível, inviabilizando a inovação, mutação e, em alguns casos, até o crescimento do negócio. Segundo constatado por Paul Strassmann em 1997, na realidade uma situação inversa deveria ser empregada, onde as seguintes características sustentariam a ideal postura de um departamento de Tecnologia da Informação em uma organização: deveria agregar real valor ao plano de negócios, não deveria resistir às mudanças e deveria combater qualquer tipo de resistência a elas, pois são necessárias.

Partindo deste ponto de vista, é essencial que o software se adapte ao modelo de negócios estipulado em uma corporação. Porém, como modelos de negócios são mutáveis, a arquitetura do software em questão deve ser flexível o suficiente para acompanhar tais mudanças e expansível o suficiente para permitir o crescimento.

Um alto grau de modularidade pode ser um grande aliado no alcance de altos graus de manutenibilidade, flexibilidade e expansibilidade.

Um módulo pode ser entendido como uma porção de código encapsulada, coesa e fracamente acoplada. Já o grau de modularidade estima a coerência de utilização de módulos na arquitetura de um sistema, obedecendo cinco critérios e seis princípios, descritos por Bertrand Meyer em 1988, exibidos nas listagens abaixo:


  • Critérios:


    • Decomposição: Capacidade de dividir o problema inicial em subproblemas, ou módulos, isolados.

    • Composição: Capacidade de reutilização dos módulos na construção de novos sistemas, possivelmente em ambientes ligeiramente diferentes.

    • Entendimento: Capacidade de compreensão dos módulos de forma individual por um leitor humano.

    • Continuidade: Capacidade de alteração dos módulos sem impacto nos demais, mantendo a arquitetura e as relações.

    • Proteção: Capacidade de suporte a condições anormais dos módulos, limitando o escopo de um erro ao próprio módulo e protegendo o restante do sistema.


  • Princípios:


    • Unidade modular sintática: Um módulo deve corresponder a uma unidade sintática da linguagem.

    • Poucas interfaces: Um módulo deve se comunicar com a menor quantidade de módulos possível, evitando recursão.

    • Interfaces pequenas: Um módulo deve trocar a menor quantidade de informações possível com outro.

    • Interfaces explícitas: A comunicação entre dois módulos deve ser explícita e clara.

    • Informações ocultas: Os dados de um módulo devem ser privados, com raras exceções de dados públicos.

    • Aberto e fechado: Aberto para pequenas alterações (sem impacto nas interfaces) e fechado, sugerindo sua completude e disponibilidade de uso.




Ainda tendo em vista o grau de modularidade, uma arquitetura deve ser elaborada considerando diversos níveis de abstração. Quanto menor a abstração de um componente, maior será seu potencial de reuso. Esta característica fundamental pode ser alcançada através da utilização de frameworks, um conjunto de classes abstratas e concretas com alto grau de especialização.

Reunindo todo este conhecimento, somos capazes de minimizar a existência de três propriedades internas indesejáveis na arquitetura:


  • Rigidez: A manutenção em um determinado ponto do sistema obriga ao desenvolvedor ajustar outras localidades diretamente relacionadas, gerando uma cadeia de manutenção. Suas conseqüências são conhecidas como “efeito dominó”.

  • Fragilidade: A manutenção em um determinado ponto do sistema gera problemas em outro ponto não relacionado, muitas vezes distante do local da alteração. Suas conseqüências são conhecidas como “efeito borboleta-maremoto”, nomenclatura extraída da Teoria do Caos. Esta teoria defende que o simples bater de asas de uma borboleta em um extremo do mundo, pode ser o estopim de um tornado no outro extremo.

  • Imobilidade: Ao tentar reutilizar um componente já desenvolvido, classes não pertencentes a este impossibilitam a ação, dado o forte acoplamento existente. Suas conseqüências são conhecidas como “efeito banana-gorila”.



Iterativo e Incremental

Cada projeto é dividido em iterações. Cada iteração pode ser considerada um miniprojeto de curta duração que tem por objetivo oferecer uma melhora incremental ao sistema.

São benefícios desta forma de organização:


  • É um progresso lógico para que uma arquitetura robusta seja alcançada. Durante as iterações iniciais, uma arquitetura candidata é proposta. Sua evolução será uma fundação sólida para o restante do sistema.

  • Em contraste com metodologias que seguem o paradigma do Processo Cascata, onde todos os requisitos são levantados no inicio e nunca mais revisados, o Processo Unificado prevê a negociação progressiva de requisitos, priorizando aqueles que representam riscos mais significativos ao projeto.

  • Possibilita maior flexibilidade para que mudanças ocorram no plano de atuação da equipe de desenvolvimento. Uma avaliação ao final de uma iteração permite isolar um eventual problema identificado e lidar com ele em uma escalada reduzida, sem propagar seus efeitos.

  • Caso o incremento de uma iteração seja um componente ou módulo, este é integrado aos demais existentes. Uma integração muitas vezes representa a conquista de mais um requisito. A evolução do trabalho torna-se mais evidente aos interessados.

  • Por fim, a natureza iterativa permite que novos integrantes da equipe de desenvolvimento iniciem suas atividades sem que sejam submetidos a treinamentos extensos que cubram todo o projeto.

 
> blogblogs.com.br