Engenharia de Software #01 - Os processos por trás da Engenharia
Published: 2023-08-13 18:05:56

Primeiro artigo da série de artigos "Engenharia de Software", no qual eu pretendo trazer uma série de artigos relacionados a Engenharia de software como um todo, nesse eu trago os conceitos por trás dos modelos que utilizamos hoje em dia para o ciclo de vida do software.

## O que é Engenharia de Software
Engenharia de Software se dedica à aplicação de princípios, métodos e técnicas para o desenvolvimento de software de forma sistemática e controlada. O objetivo é criar sistemas de software de alta qualidade, confiáveis, eficientes e que atendam às necessidades dos usuários.

Essa área abrange todo o ciclo de vida do desenvolvimento de software, desde a concepção e especificação dos requisitos até a manutenção e evolução do sistema após a sua implantação. Algumas das principais atividades da engenharia de software incluem:

1. Análise de requisitos: Entender as necessidades e expectativas dos usuários para definir os recursos e funcionalidades que o software deve ter

2. Projeto de software: Definir a arquitetura e a estrutura do sistema, bem como o detalhamento dos componentes e módulos que serão desenvolvidos.

3. Codificação: Implementar o software com base no projeto e nas especificações definidas anteriormente.

4. Testes de software: Verificar se o software funciona corretamente, identificar e corrigir falhas e garantir que ele atenda aos requisitos estabelecidos.

5. Implantação: Colocar o software em funcionamento no ambiente em que será utilizado pelos usuários.

6. Manutenção: Realizar ajustes, correções e melhorias no software após sua implantação para garantir seu bom funcionamento ao longo do tempo.

## Processos de Software

É um conjunto de atividades relacionadas que levam à produção um produto de software.

Um processo de software bem definido proporciona uma abordagem sistemática para a criação de software de qualidade, controlando riscos e custos, melhorando a produtividade e facilitando a comunicação e colaboração entre os membros da equipe de desenvolvimento.

## Modelos de Processo de Software

1. Modelo Cascata: É um processo linear e sequencial, no qual cada fase deve ser concluída antes de avançar para a próxima. As etapas incluem: requisitos, projeto, implementação, testes e manutenção.

2. Modelo Incremental: Divide o desenvolvimento do software em incrementos menores, permitindo que cada incremento adicione funcionalidades e seja integrado aos incrementos anteriores de forma iterativa.

3. Modelo em Espiral: Combina elementos do modelo cascata com a abordagem iterativa, incluindo ciclos de avaliação de riscos e planejamento de atividades.

4. Modelo Ágil: É uma abordagem colaborativa e iterativa que valoriza a entrega contínua de software funcional e a adaptação às mudanças dos requisitos ao longo do projeto.

## Rational Unified Process RUP

O IBM Rational Unified Process (RUP) é um processo de desenvolvimento de software baseado em um modelo iterativo e incremental. Ele é uma das metodologias mais conhecidas e utilizadas no âmbito da Engenharia de Software. O RUP foi criado pela Rational Software Corporation, que foi adquirida pela IBM em 2003, e desde então, passou a ser conhecido como IBM RUP.

O RUP é caracterizado por sua abordagem iterativa, ou seja, o desenvolvimento do software é dividido em várias iterações, e em cada iteração, uma parte do software é projetada, implementada, testada e entregue. Essas iterações são períodos de tempo relativamente curtos, geralmente de 2 a 6 semanas, e permitem que os resultados intermediários sejam obtidos e revisados periodicamente, garantindo maior controle e adaptação às mudanças durante o processo.

Os princípios fundamentais do IBM RUP incluem:

1. Foco nos Casos de Uso: O RUP baseia o desenvolvimento no entendimento das necessidades dos usuários através de Casos de Uso, que descrevem as interações entre o sistema e seus usuários, permitindo uma abordagem centrada no usuário.

2. Arquitetura Centrada: O RUP coloca uma forte ênfase na definição e no desenvolvimento de uma arquitetura sólida e bem estruturada para o software, o que facilita a compreensão do sistema como um todo e reduz riscos e problemas futuros.

3. Gestão de Mudanças: O processo RUP reconhece a natureza dinâmica do desenvolvimento de software e oferece uma abordagem para gerir mudanças de requisitos, prioridades e outras variáveis que possam surgir durante o projeto.

4. Componentização: O RUP promove a reutilização de componentes de software sempre que possível, facilitando a manutenção e evolução do sistema.

O IBM RUP é composto por fases, disciplinas e papéis que fornecem uma estrutura para orientar o desenvolvimento do software. As principais fases do RUP são:

1. Concepção (Inception): Nesta fase, os requisitos são analisados, os objetivos do projeto são definidos e a viabilidade técnica e financeira é avaliada.

2. Elaboração (Elaboration): Fase na qual a arquitetura é projetada, os riscos são identificados e a base para o desenvolvimento é estabelecida.

3. Construção (Construction): É a fase de implementação do software, onde as funcionalidades são desenvolvidas iterativamente.

4. Transição (Transition): Nesta fase, o software é testado, implantado e entregue aos usuários.

O RUP também define disciplinas, que são conjuntos de atividades relacionadas que abordam aspectos específicos do desenvolvimento do software, como requisitos, análise e design, implementação, testes, entre outros.

Os papéis no RUP incluem o Gerente de Projeto, o Analista de Requisitos, o Arquiteto, o Desenvolvedor, o Testador, entre outros, cada um com suas responsabilidades bem definidas no processo.

É importante notar que o RUP pode ser adaptado para atender às necessidades específicas de um projeto e de uma organização, tornando-o uma metodologia flexível e amplamente aplicável em diferentes contextos de desenvolvimento de software.

## Métodos e Desenvolvimento Ágil
Em meados de 1970 quando a engenharia de software era quase inexistente, houve a chamada "Crise do software" na qual as equipes de Software tinham problemas como Orçamento, prazo, qualidade, requisitos, manutenabiliade dentre outras coisas e daí surgiu a necessidade de evolução para sanar esses problemas e daí surgiiu a Engenharia de software Tradicional no qual trata com mais cautela o planejamento, qualidade, uso de métodos de análise e design e o processo de desenvolvimento se tornou mais rigoroso e controlado.

E em meados de 2000 surge a engenharia de software ágil.

Métodos ágeis e Desenvolvimento Ágil são termos relacionados que se referem a uma abordagem de desenvolvimento de software que prioriza a flexibilidade, a colaboração e a entrega contínua de valor aos clientes. Os Métodos Ágeis são uma resposta às limitações de abordagens tradicionais de desenvolvimento, como o modelo cascata, que muitas vezes se mostraram rígidas e pouco adaptáveis às mudanças frequentes nos requisitos e no ambiente de negócios.

## Manifesto Ágil 2001:

"Estamos descobrindo maneiras melhores de desenvovler software, fazendo-os nós mesmos e ajudando os outros a fazerem o mesmo. Atrave´s deste trabalho, passamos a valorizar:

<ul> 
<li>Individios e Interações mais do que processos e Ferramentas</li>

<li>Software em funcionamento mais que documentação pesada</li>

<li>Colaboração com o cliente e menos contratos e negociações</li>

<li>Rápida resposta a mudança mais que seguir planos já definidos</li>

</ul>

Ou seja, mesmo havendo valor nos itens à direnta, valorizamos mais os itens a esquerda"

## Engenharia de Software ágil:

1. Valorização das Pessoas e da Interação: Reconhecem que indivíduos talentosos e colaborativos são a chave para o sucesso do projeto, incentivando a comunicação face a face entre os membros da equipe.

2. Entrega Contínua de Software Funcional: Priorizam a entrega de incrementos de software funcional em curtos períodos de tempo, geralmente em algumas semanas, permitindo que o cliente comece a obter valor rapidamente.

3. Colaboração com o Cliente: Envolvem os clientes e usuários finais durante todo o processo de desenvolvimento para garantir que o software atenda às suas necessidades e expectativas.

4. Resposta a Mudanças: Aceitam que os requisitos e prioridades podem mudar ao longo do projeto e estão preparados para se adaptar a essas mudanças de forma eficiente.

5. Auto-organização da Equipe: Permitem que as equipes de desenvolvimento se auto-organizem e tomem decisões relacionadas ao trabalho que realizam.

Alguns dos métodos ágeis mais conhecidos incluem Scrum, Kanban, Extreme Programming (XP) e Lean Software Development, entre outros. Cada um possui suas próprias práticas específicas, mas todos compartilham a ênfase na colaboração, comunicação frequente, feedback contínuo e entrega incremental de software.

O Desenvolvimento Ágil é o processo de aplicar os princípios e práticas dos Métodos Ágeis em um projeto de desenvolvimento de software específico. Nesse contexto, a equipe trabalha em iterações curtas e focadas, geralmente chamadas de sprints (no caso do Scrum), onde planejam, desenvolvem, testam e entregam funcionalidades incrementais em intervalos regulares.

Ao adotar o Desenvolvimento Ágil, as equipes podem responder rapidamente a mudanças nos requisitos, identificar e resolver problemas com mais agilidade e garantir que o software entregue seja mais alinhado às necessidades dos clientes e do mercado.

Essa abordagem é particularmente eficaz em projetos complexos e dinâmicos, onde os requisitos podem evoluir à medida que o projeto avança. O Desenvolvimento Ágil promove um ambiente de trabalho colaborativo, transparente e focado no cliente, permitindo que a equipe de desenvolvimento alcance resultados com mais eficiência e qualidade.

## Engenharia de Requisitos
A Engenharia de Requisitos é uma disciplina fundamental dentro da Engenharia de Software, responsável por identificar, analisar, documentar e gerenciar os requisitos de um sistema de software. Os requisitos são as funcionalidades, características e restrições que o software deve atender para satisfazer as necessidades dos usuários e das partes interessadas.

O processo de Engenharia de Requisitos envolve várias atividades importantes:

1. Elicitação de Requisitos: Nesta fase, os engenheiros de requisitos interagem com os stakeholders (clientes, usuários finais, gerentes de projeto, etc.) para entender suas necessidades e expectativas em relação ao sistema. Isso pode ser feito por meio de entrevistas, workshops, questionários ou outras técnicas de comunicação.

2. Análise e Documentação de Requisitos: Após a elicitação, os requisitos são analisados, refinados e documentados de forma clara e precisa. A documentação inclui descrições detalhadas dos requisitos, casos de uso, diagramas de fluxo e outras técnicas para facilitar a compreensão do que o sistema deve fazer.

3. Gerenciamento de Requisitos: Os requisitos estão sujeitos a mudanças ao longo do ciclo de vida do projeto. O gerenciamento de requisitos envolve o controle de alterações, rastreamento de versões e garantia de que todos os requisitos sejam rastreáveis e consistentes ao longo do projeto.

4. Validação e Verificação de Requisitos: Antes de prosseguir para a próxima fase do projeto, os requisitos são revisados e validados para garantir que eles sejam compreensíveis, completos, consistentes e atendam às expectativas dos stakeholders. A verificação visa confirmar que os requisitos estão bem escritos e são tecnicamente viáveis.

5. Negociação de Requisitos: Em alguns casos, os stakeholders podem ter requisitos conflitantes ou difíceis de atender devido a restrições de recursos ou tecnológicas. A negociação de requisitos envolve encontrar soluções equilibradas que satisfaçam a maioria das partes interessadas.

6. Rastreabilidade de Requisitos: É importante rastrear a origem e o destino de cada requisito ao longo do projeto. A rastreabilidade ajuda a garantir que todos os requisitos sejam atendidos e que as mudanças tenham um impacto controlado em todo o sistema.

A Engenharia de Requisitos é um processo contínuo e iterativo que acompanha o ciclo de vida completo do desenvolvimento de software. Uma boa engenharia de requisitos é fundamental para o sucesso do projeto, pois estabelece as bases para o projeto e desenvolvimento do software, garantindo que o sistema entregue atenda às necessidades dos usuários e clientes.

## Casos de Uso

"Um caso de uso especifica o comportamento de um sistema (ou parte), e é uma descrição de um conjunto de sequências de ações para produzir um resultado observável ao valor de um ator"

Usamos casos de uso para captar o comportamento pretendido de um sistema, sem especificar como esse comportamento é implementado

Aqui está um diagrama de caso de uso simples para o sistema de gerenciamento de tarefas (to-do list) com dois casos de uso: "Adicionar Tarefa" e "Visualizar Tarefas".

```
            +----------------+
            |     Usuário    |
            +-------+--------+
                    |
                    v
            +----------------+
            | Gerenciar      |
            | Tarefas        |
            +-------+--------+
                    |
           +--------+---------+
           |                  |
  +-----------------+  +------------------+
  | Adicionar Tarefa|  | Visualizar Tarefas|
  +-----------------+  +------------------+
```

Neste diagrama, temos dois atores principais: "Usuário" e "Gerenciar Tarefas". O ator "Usuário" representa qualquer usuário do sistema que interage com as funcionalidades do sistema. O ator "Gerenciar Tarefas" é um ator fictício que representa o sistema em si, pois não é uma pessoa, mas sim a parte do sistema responsável por gerenciar as tarefas.

Os dois casos de uso principais são representados como elipses retangulares no diagrama: "Adicionar Tarefa" e "Visualizar Tarefas". O caso de uso "Adicionar Tarefa" é uma funcionalidade que permite ao usuário adicionar uma nova tarefa ao sistema. O caso de uso "Visualizar Tarefas" permite ao usuário visualizar todas as tarefas existentes no sistema.

O ator "Usuário" interage com o caso de uso "Adicionar Tarefa" e "Visualizar Tarefas" através do ator "Gerenciar Tarefas". Isso significa que o caso de uso "Gerenciar Tarefas" é responsável por coordenar as interações do usuário com os casos de uso "Adicionar Tarefa" e "Visualizar Tarefas".

Esse é apenas um exemplo simplificado de um diagrama de caso de uso. Em sistemas reais, o diagrama de caso de uso pode ser mais complexo, com vários atores e casos de uso, além de relações adicionais entre eles. O diagrama de caso de uso é uma ferramenta poderosa para visualizar e comunicar as funcionalidades do sistema e as interações com os usuários.

## Diagrama de Sequência

Vamos criar um diagrama de sequência simples para ilustrar a interação entre o ator "Usuário" e o caso de uso "Adicionar Tarefa" no sistema de gerenciamento de tarefas (to-do list). O diagrama de sequência mostra a ordem das mensagens trocadas entre os objetos envolvidos na execução do caso de uso.

```
+-------------------+         +-----------------+       +-------------------+
|     Usuário       |         | Gerenciar       |       |     Tarefa        |
|                   |         | Tarefas         |       |                   |
+-------------------+         +-----------------+       +-------------------+
        |                            |                          |
        |   Seleciona a opção        |                          |
        |   "Adicionar Tarefa"      |                          |
        |-------------------------->|                          |
        |                            |                          |
        |                            | Exibe formulário        |
        |                            | de criação de tarefa   |
        |                            |------------------------>|
        |                            |                          |
        |                            |                          |
        | Preenche os campos        |                          |
        | obrigatórios (título e    |                          |
        | data de vencimento)       |                          |
        |-------------------------->|                          |
        |                            |                          |
        |                            |    Valida os campos     |
        |                            |    preenchidos         |
        |                            |<------------------------|
        |                            |                          |
        |                            |    Cria a tarefa       |
        |                            |    com as informações  |
        |                            |    fornecidas          |
        |                            |    pelo usuário        |
        |                            |------------------------>|
        |                            |                          |
        |                            | Exibe mensagem de      |
        |                            | confirmação           |
        |                            |<------------------------|
        |                            |                          |
```
Neste diagrama de sequência, temos três objetos envolvidos na interação: "Usuário", "Gerenciar Tarefas" e "Tarefa". A seta "->" indica a direção das mensagens trocadas entre os objetos.

O diagrama começa com o "Usuário" selecionando a opção "Adicionar Tarefa". Em seguida, o "Gerenciar Tarefas" exibe o formulário de criação de tarefa para o "Usuário". O "Usuário" preenche os campos obrigatórios, e o sistema valida os campos preenchidos. Após a validação, o "Gerenciar Tarefas" cria a tarefa com as informações fornecidas e exibe uma mensagem de confirmação para o "Usuário".

Esse é apenas um exemplo simplificado de um diagrama de sequência. Em sistemas reais, o diagrama de sequência pode ser mais complexo, com mais objetos envolvidos e interações mais detalhadas. O diagrama de sequência é uma ferramenta valiosa para entender a ordem das interações entre os objetos e a troca de mensagens durante a execução de um caso de uso.

## Requisitos Funcionais
Os requisitos funcionais descrevem as funcionalidades específicas que o sistema deve oferecer, ou seja, o que o software deve fazer para satisfazer as necessidades dos usuários. Eles detalham as principais ações, tarefas e operações que o sistema deve ser capaz de executar. Os requisitos funcionais geralmente são descritos através de ações verbais, como "adicionar", "editar", "excluir", "visualizar", "calcular", entre outros.

Vamos pensar em alguns requisitos funcionais para o sistema de gerenciamento de tarefas (to-do list):

Requisitos Funcionais:

RF001 - Adicionar Tarefa: O sistema deve permitir que o usuário adicione uma nova tarefa, fornecendo um título, uma descrição (opcional) e uma data de vencimento.

RF002 - Visualizar Tarefas: O sistema deve permitir que o usuário visualize todas as tarefas existentes, exibindo o título, descrição, data de vencimento e status (concluída ou pendente).

RF003 - Editar Tarefa: O sistema deve permitir que o usuário edite os dados de uma tarefa existente, incluindo título, descrição e data de vencimento.

RF004 - Excluir Tarefa: O sistema deve permitir que o usuário exclua uma tarefa existente.

RF005 - Marcar Tarefa como Concluída: O sistema deve permitir que o usuário marque uma tarefa como concluída, alterando o status da tarefa para "concluída".

## Requisitos Não Funcionais
Os requisitos não funcionais definem características e atributos do sistema que não estão diretamente relacionados com as funcionalidades específicas, mas são igualmente importantes para o seu desempenho, qualidade e usabilidade. Eles se concentram em aspectos como desempenho, segurança, usabilidade, confiabilidade e portabilidade do sistema.

Vamos pensar em alguns requisitos Não Funcionais para o sistema de gerenciamento de tarefas (to-do list):

Requisitos Não Funcionais:
RNF001 - Usabilidade: O sistema deve possuir uma interface intuitiva e fácil de usar, permitindo que usuários com diferentes níveis de habilidade possam interagir com o sistema de forma eficiente.

RNF002 - Desempenho: O sistema deve ser responsivo e rápido na execução das operações, garantindo tempos de resposta adequados mesmo em períodos de alta carga de usuários.

RNF003 - Segurança: O sistema deve garantir a proteção dos dados dos usuários e das tarefas, evitando acesso não autorizado e mantendo a confidencialidade e integridade das informações.

RNF004 - Confiabilidade: O sistema deve ser confiável, minimizando a ocorrência de erros e falhas, e garantindo que as tarefas adicionadas pelos usuários sejam devidamente armazenadas e recuperadas.

RNF005 - Portabilidade: O sistema deve ser projetado para ser executado em diferentes plataformas e dispositivos, como computadores, tablets e smartphones, suportando diversos sistemas operacionais e navegadores.

Esses requisitos são apenas um exemplo simplificado para ilustrar a ideia de requisitos funcionais e não funcionais. Em projetos reais, a lista de requisitos geralmente é mais extensa e detalhada, sendo definidos com base nas necessidades e expectativas dos usuários e nas restrições do ambiente em que o sistema será implantado.

## Devops

DevOps é uma cultura, conjunto de práticas e abordagem para a integração e colaboração entre as equipes de desenvolvimento de software (Dev) e operações de TI (Ops). A palavra "DevOps" é uma junção dos termos "Development" (Desenvolvimento) e "Operations" (Operações).

O objetivo principal do DevOps é eliminar barreiras e melhorar a comunicação entre desenvolvedores e profissionais de operações, de modo a criar um ambiente de trabalho colaborativo e ágil. Essa colaboração entre as equipes permite a entrega mais rápida e frequente de software, além de garantir maior estabilidade e confiabilidade nos ambientes de produção.

Algumas das principais características e práticas associadas ao DevOps incluem:

1. Automação: O uso extensivo de automação de processos, como compilação, testes, implantação e provisionamento de infraestrutura, para eliminar tarefas manuais repetitivas e reduzir erros humanos.

2. Integração Contínua (CI): A prática de integrar o código produzido por diferentes desenvolvedores em um repositório compartilhado várias vezes ao dia. Isso permite detectar e corrigir problemas de integração mais cedo no ciclo de desenvolvimento.

3. Entrega Contínua (CD): A extensão da Integração Contínua, onde o objetivo é automatizar o processo de implantação do software em ambientes de produção a qualquer momento que seja necessário, tornando as implantações mais frequentes e confiáveis.

4. Monitoramento e Feedback: A coleta de métricas e monitoramento constante do desempenho do sistema em produção para identificar problemas, garantir a qualidade e responder rapidamente a falhas.

5. Cultura de Colaboração: Fomentar uma cultura de colaboração, responsabilidade compartilhada e comunicação aberta entre desenvolvedores, operadores e outras partes interessadas.

6. Infraestrutura como Código (IaC): A prática de gerenciar a infraestrutura de TI (servidores, redes, etc.) através de código, permitindo provisionamento rápido, consistente e automatizado de ambientes.

Ao adotar a cultura e as práticas do DevOps, as organizações podem acelerar o desenvolvimento de software, melhorar a qualidade do produto final, aumentar a eficiência operacional e responder com mais rapidez às demandas do mercado e dos usuários. O DevOps se tornou uma abordagem essencial para empresas que buscam agilidade e competitividade em seus processos de desenvolvimento e entrega de software.