---
# System prepended metadata

title: Anotações Engenharia de Software

---

### Crise de Software

A **Crise de Software** refere-se a uma série de desafios enfrentados pela indústria de desenvolvimento de software nas décadas de 1960 e 1970. Este termo foi usado para descrever os problemas que surgiram devido à abordagem informal e muitas vezes caótica para o desenvolvimento de software. Abaixo estão os principais aspectos dessa crise:

#### Características Principais
- **Desenvolvimento Informal**: Métodos de desenvolvimento não estruturados e sem padrões rigorosos.
- **Crescente Complexidade**: Softwares se tornando cada vez mais complexos, ultrapassando a capacidade de gerenciamento e manutenção.
- **Atrasos e Custos**: Projetos frequentemente ultrapassavam os orçamentos e prazos previstos.
- **Baixa Qualidade**: Softwares muitas vezes eram entregues com muitos bugs e falhas de segurança.
- **Dificuldade de Manutenção**: Manter e atualizar software antigo se tornava cada vez mais problemático.

#### Consequências
- **Necessidade de Metodologias Melhores**: Levou à criação de metodologias de desenvolvimento mais estruturadas.
- **Evolução de Ferramentas e Técnicas**: Impulsionou a inovação em ferramentas de desenvolvimento e técnicas de programação.
- **Educação em Software**: Aumentou o foco na educação formal e treinamento em engenharia de software.
- **Padrões de Qualidade**: Desenvolvimento de padrões de qualidade e melhores práticas na indústria de software.

### O que é software?
- Um conjunto de instruções que, ao serem executadas, entregam a funcionalidade e desempenho desejados, através de estruturas de dados que permitem a manipulação eficiente da informação e um conjunto de artefatos associados.

#### Tipos de software
- Produto genérico. (Exemplo: Microsoft Office)
- Produto sob encomenda. (Exemplo: Sistemas personalizados para logística)
- Software como ‘produto completo’. (Exemplo: Um jogo ou app onde o usuário final tem acesso total)
- Software como serviço. (Exemplo: Serviços por assinatura)

### O que é engenharia de software?
- Uma disciplina que estuda todos os aspectos relacionados ao desenvolvimento de software.

### Características na qualidade de software 
- Funcionalidade
- Confiabilidade
- Usabilidade
- Eficiência
- Manutenibilidade
- Portabilidade

### Características no processo de software

#### Análise
- **Objetivo**: "O que será desenvolvido?"
  - Definição das necessidades e requisitos do software.

#### Projeto
- **Objetivo**: "Como o produto será desenvolvido?"
  - Desenho da arquitetura e planejamento das soluções técnicas.

#### Codificação
- **Objetivo**: Implementação das especificações.
  - Escrita do código-fonte para atender aos requisitos definidos.

#### Verificação e Validação
- **Objetivo**: Avaliar o produto.
  - Testes para garantir que o software atende aos requisitos e padrões de qualidade.

#### Implantação
- **Objetivo**: Disponibilizar o produto ao cliente/usuários.
  - Lançamento do software e disponibilização para o uso final.

#### Evolução
- **Objetivo**: Alterar o produto.
  - Manutenção e atualizações para melhorar ou modificar o software após o lançamento.

#### Gerenciamento
- **Objetivo**: Coordenar as ações em todas as fases.
  - Gestão de projetos para assegurar que todas as etapas do desenvolvimento sejam realizadas eficientemente e em harmonia.

## Slide 2

### Fases no Processo de Desenvolvimento de Software

#### 1. Análise
- **Objetivo**: Definir o que será implementado.
- **Descrição**: Identificação de requisitos, análise de necessidades do usuário e definição clara do escopo do projeto.

#### 2. Projeto
- **Objetivo**: Especificar como será implementado.
- **Descrição**: Desenho da arquitetura do sistema, modelagem de dados e interfaces, e planejamento da solução técnica.

#### 3. Codificação
- **Objetivo**: Criar um programa executável.
- **Descrição**: Tradução das especificações do projeto em código-fonte, programação de funcionalidades e implementação de componentes do sistema.

#### 4. Verificação e Validação
- **Objetivo**: Checar se o programa corresponde ao esperado.
- **Descrição**: Testes para garantir que o software atende aos requisitos definidos, incluindo testes de funcionalidade, desempenho, segurança e usabilidade.

#### 5. Evolução
- **Objetivo**: Alterar o programa quando necessário.
- **Descrição**: Manutenção e atualização do software para corrigir falhas, melhorar desempenho ou adicionar novas funcionalidades.

### Detalhamento desses processos:

### Análise 
##### 1. Estudo de Viabilidade
- **Objetivo**: Determinar se as necessidades dos usuários podem ser satisfeitas dentro de um custo adequado.
- **Processo**:
  - Avaliação da viabilidade técnica, financeira e operacional.
  - Análise do impacto do projeto e dos recursos necessários.
- **Resultados**:
  - **Viável**: Continua o desenvolvimento. (Exemplo: Delivery de alimentos. Alta demanda, tecnologia disponível, potencial de lucro.)
  - **Inviável**: Projeto é cancelado. (Exemplo: Turismo Espacial. Tecnologia cara, demanda limitada, custos proibitivos.)

##### 2. Elicitação e Análise de Requisitos
- **Objetivo**: Derivação dos requisitos do sistema.
- **Métodos**:
  - Entrevistas com stakeholders.
  - Questionários e pesquisas.
  - Observação de processos e sistemas existentes.
- **Resultados**: Conjunto detalhado de requisitos do usuário e do sistema.

##### 3. Especificação de Requisitos
- **Objetivo**: Descrever detalhadamente os requisitos para guiar o desenvolvimento.
- **Processo**:
  - Documentação clara e precisa dos requisitos.
  - Definição de critérios de aceitação e métricas de sucesso.
- **Resultados**: Documento de especificação de requisitos que serve como um guia para as próximas fases de desenvolvimento.

##### 4. Validação de Requisitos
- **Objetivo**: Garantir que os requisitos são realistas e consistentes.
- **Processo**:
  - Revisão e análise crítica dos requisitos.
  - Testes de consistência e completude.
- **Resultados**: Requisitos finais aprovados, prontos para serem implementados na fase de projeto e codificação.

### Codificação

- **Objetivo**: Transformar modelos de projeto em um programa executável.
- **Abordagens**:
  - **Desenvolvimento Interno**: Escrita direta do código-fonte.
  - **Uso de Componentes**: Integrar componentes de software pré-existentes.
  - **Frameworks**: Aplicar estruturas de software que oferecem suporte e padrões.
  - **Ferramentas de Geração de Código**: Automatizar a escrita de código.

## Verificação e Validação

### Objetivos
- **Verificar e Validar**: Garantir que a solução codificada:
  - Possui todas as características desejadas pelo cliente.
  - Não possui erros (bugs) em sua execução.

### Processo
- **Testes Planejados**: Idealmente, são iniciados nas fases iniciais do desenvolvimento.
- **Casos de Teste**: Descrições de situações e dados que o software deve ser capaz de tratar.

### Importância
- Assegura que o produto final atende aos requisitos e expectativas do cliente.
- Identifica e corrige falhas antes do lançamento do software, contribuindo para a confiabilidade e segurança do produto.

## Evolução

### Conceito
- **Mudança Necessária**: Sistemas devem mudar para permanecer úteis.
- **Duração**: É a fase onde o software passa a maior parte de seu ciclo de vida.

### Razões para Modificações
- **Adicionar ou Modificar Funcionalidades**: Expandir ou alterar as capacidades do software.
- **Reparar Defeitos**: Corrigir falhas ou bugs identificados após o lançamento.
- **Adaptação a Novos Requisitos**: Atualizar o software para atender a mudanças no ambiente, tecnologias ou necessidades dos usuários.

### Importância
- Garante que o software continua a atender às necessidades dos usuários e se mantém competitivo no mercado.
- Permite que o software evolua em resposta às mudanças tecnológicas e às novas demandas do mercado.

## Modelos de Processo de Software

### 1. Cascata
- **Descrição**: Baseado em processos tradicionais de engenharia de sistemas. Também conhecido como modelo sequencial linear ou modelo de desenvolvimento clássico.
- **Características**: 
  - Estrutura linear e sequencial.
  - Cada fase deve ser completada antes de iniciar a próxima.

### 2. Prototipagem
- **Objetivo Inicial**: Definir objetivos gerais; entradas e saídas detalhadas raramente são descritas no início.
- **Produto Final**: Existe após a execução do último ciclo.
- **Abordagens**:
  - **Desenvolvimento Exploratório**: O protótipo é criado e evolui ao longo do tempo.
  - **Prototipação Throwaway**: O protótipo é criado e descartado após o uso.

### 3. Iterativo e Incremental
- **Adaptação à Mudança**: Reconhece que a mudança é inevitável em todos os projetos de software.
- **Combinação**: Une as vantagens dos modelos Cascata e Prototipagem.
- **Entregas**: Partes funcionais do produto são entregues ao cliente ao longo do ciclo.
- **Envolvimento do Cliente**: O cliente prioriza as entregas e define requisitos para o incremento atual.
- **Produto Final**: Completo apenas após a última iteração.

## A Equipe de Desenvolvimento de Software

A equipe de desenvolvimento de software é composta por diversos papéis, cada um com responsabilidades específicas. Um membro da equipe pode desempenhar mais de um papel, e um papel pode ser desempenhado por mais de um membro.

### Papéis Comuns e Suas Responsabilidades

#### Gerente de Projeto
- **Responsabilidades**: Coordenar pessoas e tarefas do processo de desenvolvimento.
- **Foco**: Garantir que o projeto siga o cronograma e atenda aos padrões de qualidade.

#### Analista
- **Responsabilidades**: Capturar as necessidades do cliente e traduzi-las para a equipe.
- **Foco**: Garantir que os requisitos do cliente sejam claramente entendidos e documentados.

#### Projetista
- **Responsabilidades**: Avaliar alternativas e fornecer especificações para partes do software (como interface, banco de dados).
- **Foco**: Desenhar a arquitetura do sistema e garantir sua eficiência e eficácia.

#### Programador
- **Responsabilidades**: Realizar a codificação do sistema de acordo com as especificações e modelos.
- **Foco**: Implementar funcionalidades de forma eficaz e conforme as diretrizes do projeto.

### Importância da Colaboração
- **Colaboração Efetiva**: Crucial para o sucesso do projeto.
- **Flexibilidade de Papéis**: Adaptabilidade e polivalência são valorizadas na equipe.

## Características do Processo Unificado Rational (RUP)

### Desenvolvimento Iterativo
- **Descrição**: O projeto é dividido em iterações, cada uma resultando em uma versão incrementada do software.

### Centrado na Arquitetura e Guiado por Casos de Uso
- **Foco**: Desenvolvimento baseado na arquitetura do sistema e nos casos de uso para definir requisitos.

### Compreensão Crescente
- **Abordagem**: Entendimento progressivo do projeto e de seus requisitos ao longo do tempo.

### Aperfeiçoamentos Sucessivos
- **Flexibilidade para Mudanças**: Capacidade de adaptar-se e incorporar mudanças durante o desenvolvimento.

### Controle de Qualidade
- **Prática**: Implementação de práticas rigorosas de controle de qualidade em todas as iterações.

### Gerenciamento de Riscos
- **Estratégia**: Identificação e gerenciamento proativo de riscos potenciais.

### Ênfase na Criação de Modelos (UML)
- **Preferência**: Uso de Modelagem Unificada de Linguagem (UML) para documentação, em vez de documentos impressos.

## Fases e Fluxos de Trabalho no Processo Unificado Rational (RUP)

### Fases do RUP
1. **Concepção**:
   - Foco inicial no escopo do projeto e definição de baselines.
2. **Elaboração**:
   - Análise de riscos e planejamento mais detalhado.
3. **Construção**:
   - Desenvolvimento e codificação intensivos do software.
4. **Transição**:
   - Implementação do software no ambiente do usuário e resolução de quaisquer problemas.

### Fluxos de Trabalho (Workflow)
1. **Modelagem de Negócio**:
   - Entendimento e modelagem do contexto de negócios.
2. **Requisitos**:
   - Levantamento e documentação dos requisitos do sistema.
3. **Análise e Projeto**:
   - Análise dos requisitos e design da arquitetura do sistema.
4. **Implementação**:
   - Codificação efetiva do software.
5. **Teste**:
   - Verificação e validação do software desenvolvido.
6. **Entrega**:
   - Distribuição do produto final.
7. **Gerenciamento de Configuração**:
   - Controle de versões e mudanças no software.
8. **Gerenciamento de Projeto**:
   - Supervisão e coordenação do progresso do projeto.
9. **Ambiente**:
   - Preparação e manutenção do ambiente de desenvolvimento.

## Artefatos e Papéis no Processo Unificado Rational (RUP)

### Artefatos no RUP
- **Definição**: Um artefato é qualquer documento, relatório ou código executável produzido durante o desenvolvimento.
- **Associação com Atividades**: Cada atividade no RUP tem um conjunto de artefatos associados, que podem ser entradas ou saídas.
- **Importância dos Modelos**: Modelos, especialmente diagramas, são considerados os artefatos mais importantes no RUP.

### Papéis no RUP
- **Definição de Papel**: Uma definição abstrata de um conjunto de atividades e seus artefatos associados.
- **Desempenho de Papéis**: Podem ser desempenhados por uma pessoa ou um grupo de pessoas.
- **Flexibilidade de Papéis**: Um membro da equipe pode assumir vários papéis diferentes.
- **Exemplos de Papéis**: Incluem Analistas, Desenvolvedores, Testadores, Gerentes, entre outros.
- 
## Metodologias Ágeis

As metodologias ágeis são um conjunto de práticas de desenvolvimento de software que enfatizam a flexibilidade, a colaboração e a entrega rápida de valor.

### Características das Metodologias Ágeis
- **Baseadas no Manifesto Ágil**: Inspiradas pelos princípios e valores expressos no Manifesto Ágil.
- **Adaptativas, não Preditivas**: Enfatizam a adaptação a mudanças em vez de seguir rigidamente um plano.
- **Planejamento para Períodos Curtos**: Foco em planejar e entregar em ciclos curtos para resposta rápida às mudanças.
- **Evitam Burocracia**: Priorizam a simplicidade e a eficiência, minimizando processos desnecessários.

### O Manifesto Ágil
- **Origem**: Criado por um grupo de profissionais da área de desenvolvimento que discutiu formas de melhorar o desempenho de seus projetos.
- **Princípios Comuns**: Identificação de um conjunto de princípios comuns aos casos de sucesso.

#### Declaração do Manifesto Ágil
"Estamos descobrindo maneiras melhores de desenvolver software fazendo-o nós mesmos e ajudando outros a fazê-lo. Através desse trabalho, passamos a valorizar:
- Indivíduos e interação entre eles mais que processos e ferramentas;
- Software em funcionamento mais que documentação abrangente;
- Colaboração com o cliente mais que negociação de contratos;
- Responder a mudanças mais que seguir um plano.

## Extreme Programming (XP)

### O que é XP?
- XP é uma metodologia ágil de desenvolvimento de software destinada a times pequenos ou médios, que lidam com requisitos imprecisos e que mudam rapidamente.

### Princípios Básicos
- Baseia-se na ideia de levar à extremidade práticas importantes como codificação, testes, escuta e refatoração.

### Papéis no XP
- **Cliente**: Paga ou irá utilizar o produto.
- **Gerente**: Responsável pela interação entre cliente e desenvolvedores.
- **Testador**: Descreve e codifica os testes.
- **Programador**: Escreve o código necessário para criar o produto.

### Os Quatro Valores do XP
1. **Simplicidade**: Criar o código mais simples que resolve o problema.
2. **Comunicação**: Fomentar a comunicação efetiva entre a equipe e com o cliente.
3. **Feedback**: Obter retorno rápido e contínuo durante o desenvolvimento.
4. **Coragem**: Realizar mudanças quando necessário e ser transparente com o cliente.

### As 12 Práticas do XP
1. **O Jogo do Planejamento**: Planejamento iterativo e adaptativo.
2. **Entregas Frequentes**: Entregar pequenas funcionalidades de forma contínua.
3. **Metáfora**: Usar analogias para descrever o sistema e suas funcionalidades.
4. **Projeto Simples**: Manter o design do sistema o mais simples possível.
5. **Testes**: Desenvolver testes continuamente durante o desenvolvimento.
6. **Refatoração**: Melhorar constantemente a estrutura do código.
7. **Programação em Pares**: Desenvolver código em pares para aumentar a qualidade e reduzir erros.
8. **Propriedade Coletiva**: O código pertence a todos no time, permitindo que qualquer um possa melhorá-lo.
9. **Integração Contínua**: Integrar e testar o trabalho de todos frequentemente.
10. **Semana de 40 Horas**: Manter uma carga de trabalho sustentável para evitar o esgotamento da equipe.
11. **Cliente Presente**: Ter um representante do cliente trabalhando junto com a equipe.
12. **Padrões de Codificação**: Seguir padrões para garantir a legibilidade e qualidade do código.

## Scrum - Framework Ágil

### O que é Scrum?
- **Definição**: Scrum é um framework para desenvolver, entregar e manter produtos em ambientes complexos. É uma metodologia ágil para gestão e planejamento de projetos de software.

### Pilares do Scrum
1. **Transparência**: Todo o processo e trabalho devem ser visíveis a todos os envolvidos.
2. **Inspeção**: Artefatos e progresso do projeto devem ser inspecionados frequentemente.
3. **Adaptação**: Ajustes devem ser feitos sempre que houver desvios significativos nos planos.

### Valores do Scrum
- **Compromisso**
- **Foco**
- **Aceitação**
- **Respeito**
- **Coragem**

### Papéis no Scrum
- **Product Owner**: Representa o cliente e determina as prioridades.
- **Scrum Master**: Capacita a equipe e resolve impedimentos.
- **Team**: Grupo responsável pelo desenvolvimento do produto.

### Artefatos do Scrum
- **Product Backlog**: Lista de tudo o que é desejado para o software.
- **Sprint Backlog**: Itens selecionados do Product Backlog para serem desenvolvidos no Sprint.
- **Incremento/Entrega**: Produto resultante do Sprint.

### Eventos do Scrum
- **Planejamento do Sprint (Sprint Planning)**
- **Sprint**: Período de desenvolvimento.
- **Scrum Diário (Daily Scrum)**
- **Revisão do Sprint (Sprint Review)**
- **Retrospectiva do Sprint (Sprint Retrospective)**

O Scrum é projetado para equipes que trabalham em projetos complexos, proporcionando um framework que promove a colaboração, a eficiência e a adaptabilidade contínua.

## Gráfico de Gantt e Kanban Board

### Gráfico de Gantt
- **Uso**: Uma ferramenta de gerenciamento de projetos usada para representar graficamente o cronograma das atividades.
- **Características**:
  - Mostra o início e o término de cada tarefa dentro de um período.
  - Ajuda a visualizar a duração e a sobreposição das atividades.
  - Útil para planejar, coordenar e rastrear tarefas específicas em um projeto.

### Kanban Board
- **Origem**: Desenvolvido pela Toyota no Japão nos anos 1940 e adaptado para o desenvolvimento de software em 2004.
- **Metodologia Kanban**:
  - Enfoca na visualização do fluxo de trabalho.
  - Utiliza um quadro de tarefas (Kanban Board) com post-its ou marcadores similares.
- **Estrutura**:
  - **TODO**: Tarefas a serem feitas.
  - **DOING**: Tarefas em andamento.
  - **DONE**: Tarefas concluídas.
- **Personalização**:
  - Classes de organização podem ser personalizadas.
  - Limites de tarefas por classe para manter o foco e controle.
  - Cores para indicar prioridades e tipos de tarefas.
- **Flexibilidade**: Novas tarefas podem ser adicionadas a qualquer momento.

### Scrum Board
- **Estrutura Simples**: Geralmente dividido em TODO, Build, Test e Done.
- **Sprint Backlog**: Uma vez definido, novas tarefas geralmente não são adicionadas no meio do Sprint.
- **Medição**: Uso de indicadores como story points para acompanhar o progresso.

### Resumo
- **Gráfico de Gantt**: Ferramenta útil para gerenciar atividades do projeto em relação ao cronograma.
- **Kanban Board**: Ferramenta útil para acompanhar a realização de tarefas do projeto, promovendo visibilidade e flexibilidade no gerenciamento de tarefas.

## Fase de Análise no Desenvolvimento de Software

### Tipos de Requisitos

#### Requisitos Funcionais
- **Descrição**: Serviços que o sistema deve fornecer, reações a entradas específicas e comportamento em determinadas situações.
- **Importância**: Requisitos precisos para evitar mudanças e atrasos.
- **Especificação**: Deve ser completa e consistente.

#### Requisitos Não Funcionais
- **Descrição**: Restrições sobre serviços ou funções oferecidos pelo sistema (ex.: confiabilidade, tempo de resposta).
- **Meta e Verificação**: Definição clara de intenção e critérios objetivamente testáveis.

#### Requisitos de Domínio
- **Relacionamento**: Vinculados ao domínio de aplicação do sistema e refletem suas características.

### Engenharia de Requisitos

- **Processo**: Estabelecimento dos serviços requeridos pelo cliente e as restrições operacionais e de desenvolvimento.
- **Etapas**:
  - **Estudo de Viabilidade**: Avaliação inicial da viabilidade operacional, técnica, de cronograma e econômica.
  - **Elicitação e Análise de Requisitos**: Coleta e organização dos requisitos, incluindo a priorização e negociação.
  - **Documentação de Requisitos**: Formalização dos requisitos para as próximas iterações de desenvolvimento.

### Abordagens para Obtenção de Requisitos

- **Métodos**: Observação de documentos, entrevistas, etnografia, questionários, entre outros.

## Análise de Requisitos no Desenvolvimento de Software

### Obtenção de Requisitos
- **Processo**: Coleta de informações relacionadas ao sistema proposto.
- **Abordagens**:
  - Observação de documentos.
  - Entrevistas.
  - Etnografia (observação participante).
  - Questionários.
  - Pontos de vista.

### Especificação de Requisitos
- **Representação**: Utilização de linguagem natural e outras técnicas.
- **Desafios**: Potenciais problemas como ambiguidade, flexibilidade excessiva e falta de modularização.
- **Técnicas por Sommerville**:
  - Cenários: Exemplos reais de uso do sistema.
  - Histórias de Usuário: Descrições de funcionalidades que agregam valor, geralmente criadas pelo cliente.
  - Casos de Uso: Identificação das interações e agentes envolvidos.

### Validação de Requisitos
- **Objetivo**: Garantir que os requisitos definem o sistema que o cliente realmente deseja.
- **Verificações**:
  - **Validade**: O sistema atende às necessidades do cliente?
  - **Consistência**: Os requisitos estão alinhados e não são conflitantes?
  - **Completeza**: Todas as funções desejadas estão incluídas?
  - **Realismo**: Os requisitos são tecnicamente e financeiramente viáveis?
  - **Testabilidade**: Os requisitos podem ser verificados?
- **Técnicas**:
  - Revisões de Requisitos: Análise manual dos requisitos.
  - Prototipação: Uso de modelos executáveis para verificar requisitos.
  - Geração de Casos de Teste: Desenvolvimento de testes para verificar a testabilidade.

## UML e Diagrama de Caso de Uso (DCU)

### Introdução à UML
- **Definição**: UML (Unified Modeling Language) é uma linguagem de modelagem utilizada para visualizar, descrever, tomar decisões e documentar sistemas de software.
- **Modelos**: Simplificam a visão de um sistema.
- **Utilização**: Frequentemente usada em projetos de software, embora a manutenção atualizada dos modelos seja um desafio.

### Diagrama de Caso de Uso (DCU)
- **Objetivo**: Capturar requisitos funcionais do sistema.
- **Componentes**:
  - **Casos de Uso**: Sequências de interações entre o sistema e agentes externos. Representação gráfica e textual.
  - **Atores**: Elementos externos que interagem com o sistema (pessoas, organizações, outros sistemas).
  - **Relacionamentos**: Indicam as interações entre atores e casos de uso.

### Tipos de Relacionamento no DCU
1. **Relacionamento de Inclusão**: Um caso de uso é parte obrigatória de outro.
2. **Relacionamento de Extensão**: Um caso de uso pode estender o comportamento de outro.
3. **Relacionamento de Generalização**: Indica herança de características entre elementos.

### Outros Conceitos no DCU
- **Fluxos**: Principal, alternativos e exceção.
- **Pré-condições e Pós-condições**: Estado necessário antes e depois da execução do caso de uso.

### Importância do DCU
- **Para o Cliente**: Oferece uma visão clara do que o sistema irá fazer.
- **Para os Desenvolvedores**: Auxilia na refinamento dos requisitos para desenvolvimento do sistema.
- **Ordenação**: Um DCU não define explicitamente a ordem de execução dos casos de uso.

## Histórias de Usuário em Metodologias Ágeis

### Conceito de Histórias de Usuário
- **Origem**: Adotadas inicialmente na metodologia Extreme Programming (XP) e usadas em outras abordagens ágeis como Scrum.
- **Definição**: Descrição de uma funcionalidade do sistema do ponto de vista do usuário.
- **Criação**: Idealmente, devem ser criadas pelo cliente ou com sua participação ativa.

### Estrutura do Cartão de História de Usuário
- **ID**: Número para identificação e ordem de criação.
- **Nome**: Título sugestivo e breve da história (2 a 10 palavras).
- **Importância**: Prioridade de implementação, podendo ser números ou categorias.
- **Estimativa**: Tempo estimado para implementar a funcionalidade.
- **Descrição**: Texto descrevendo o cenário de uso da funcionalidade.
- **Flexibilidade**: O modelo pode evoluir com o tempo, mas é importante manter um padrão inicial.

### Divisão de Histórias Grandes
- Histórias estimadas como grandes devem ser divididas em histórias menores para facilitar a gestão e o desenvolvimento.
- **Exemplos**:
  - Inserir as notas.
  - Recuperar todos os discentes de uma turma.
  - Recuperar todos os discentes de uma turma em ordem alfabética.
  - Pesquisar um discente específico por nome.
  - Salvar as notas (primeira vez).
  - Atualizar as notas (valores já existentes).

# Projeto de Software em Engenharia de Software

## Introdução ao Ciclo de Vida de um Software O.O.

- **Análise**: Compreender o domínio e definir o escopo.
- **Projeto**: Modelagem da solução e seleção de tecnologias.
- **Codificação**: Implementação usando linguagens de programação O.O.
- **Verificação e Validação**: Testes e inspeções da implementação.
- **Transição**: Melhoria contínua dos artefatos.

## Projeto de Arquitetura de Software

- **Definição de Sommerville**: Representação de alto nível do sistema.
- **Definição de Pressman**: Estrutura hierárquica dos componentes e suas interações.

### Exemplos de Arquiteturas

- Layers (Camadas)
- Client-server (Cliente-Servidor)
- Model-view-controller (MVC)
- Microservices (Microserviços)
- Peer-to-Peer (P2P)
- Service-Oriented Architecture (SOA)

## Projeto de Interface Entre Objetos

- Interfaces devem ser especificadas para permitir o design paralelo de objetos e componentes.
- Em Java, a especificação da interface é realizada utilizando a construção de mesmo nome.

## Abordagens de Projeto de Software

- **Projeto Orientado a Objetos**: Descrição de classes, objetos, e interações.
  - Diagrama de caso de uso: Comportamento externo.
  - Diagrama de classes: Estrutura interna.
  - Diagrama de sequência: Interações internas.
- **Projeto de Banco de Dados**: Esquema para persistência de dados.
  - Modelos: Entidade Relacionamento, Relacional, de Objetos.
  - Tecnologias: SQL e NoSQL.
- **Projeto de Interface com o Usuário**: Meios de interação com o usuário.
  - Design, Prototipação e Avaliação.

## Paradigma de Orientação a Objetos

- Padrão de desenvolvimento atual que utiliza a interação entre objetos para fornecer comportamentos.
- Classes e objetos definem a estrutura.
- Interações por trocas de mensagens.
- Comportamentos surgem das interações entre objetos.

### UML para Projeto O.O.

- A UML oferece diagramas para documentar o projeto O.O., incluindo diagramas de classes, interação e comportamento.

## Projeto de Software O.O.

### Introdução
- O projeto O.O. envolve colaborações entre objetos para realizar funcionalidades internamente, com atores visualizando os resultados externos.

### Modelo de Casos de Uso
- Descreve requisitos funcionais e entidades externas interagindo com o sistema, sem detalhar o comportamento interno.

### Diagrama de Classes (DC)
- Mapeia aspectos estruturais estáticos, mostrando classes, relacionamentos e colaborações.

#### Componentes do DC
- **Classe**: Abstração de entidades com métodos (comportamentos) e atributos (características).
- **Atributos**: Características das entidades, representadas por `[NOME]: [TIPO]` (ex: `saldo: float`).
- **Métodos**: Ações executadas pelos objetos, com estrutura `[NOME]([PARAMETROS]): [TIPO DE RETORNO]` (ex: `solicitarSaque(valor: float): boolean`).
- **Relacionamentos**: Ligações entre classes que permitem a troca de mensagens entre objetos.

#### Tipos de Associação no DC
- **Associação Simples**: Classes com algum grau de envolvimento.
- **Associação Recursiva**: Classe associada a si mesma, com papéis ou nome para clareza.
- **Associação Exclusiva**: Relacionamento que ocorre com uma classe OU outra, mas não ambas.
- **Associação de Classe**: Relacionamento com atributos próprios.
- **Agregação**: Relacionamento TODO-PARTE com grau de independência.
- **Composição**: Relacionamento TODO-PARTE com alto grau de dependência.

## Paradigma de Orientação a Objetos

- **Definição**: Abordagem de projeto onde as partes representam objetos que encapsulam estados e informações.
- **UML**: Ferramenta que oferece diagramas para documentar o projeto O.O., incluindo o Diagrama de Classes.
- **Classes e Objetos**: Definem a estrutura e como os objetos interagem por meio de trocas de mensagens para gerar comportamentos desejados.

# Conceitos de Projeto de Software Orientado a Objetos

## Associação e Herança
- **Associação**: Objetos de uma classe associam-se com objetos de si mesmos ou de outras classes.
- **Herança**: Objetos são subtipos de outros, herdam propriedades de antecessores.
  - Exemplo de Herança: "Gerentes são tipos de funcionários."
  - Exemplo de Associação: "Gerentes chefiam departamentos."

## Coesão e Acoplamento
- **Coesão**: Grau de responsabilidade única e bem definida de um módulo.
- **Acoplamento**: Grau de dependência entre módulos.
  - Objetivo em sistemas O.O.: Alta coesão e baixo acoplamento.
  - Herança tem alto acoplamento; associação tem baixo acoplamento.

## Propriedades da Herança
- **Transitividade**: Classe herda propriedades de todas as antecessoras sem limitação de níveis.
- **Assimetria**: Herança não é recíproca e não pode formar ciclos.

## Relacionamentos em Projeto de Software
- Classes organizadas em hierarquia com herança de atributos e operações.
- **Outros Elementos**:
  - Multiplicidade: Limites de objetos em uma associação.
  - Nome da Associação: Significado da ligação.
  - Papéis: Funções desempenhadas pelas classes.
  - Direção de Leitura: Como interpretar a associação.
  - Visibilidade: Acesso controlado aos atributos e métodos.

## Visibilidade (Modificadores de Acesso)
- `+` public: Acesso universal.
- `#` protected: Acesso pela própria classe, subclasses ou mesmo pacote.
- `-` private: Acesso restrito à própria classe.
- Package: Acesso restrito ao mesmo pacote.
- Exemplos:
  - `- idade : int`
  - `+ tipoSanguineo : String`

## Diagrama de Classes (DC)
- **Visão Estática e Estrutural**: Mostra classes do domínio e suas relações.
- **Identificação de Classes**:
  - Candidatas: Qualquer conceito possível no sistema.
  - Desnecessárias: Remoção de classes não úteis.

### Técnicas de Identificação
- Análise Textual de Abbott: Identificar substantivos, verbos e adjetivos.
- Análise dos Casos de Uso: Relacionar com requisitos funcionais.
- Análise de Robustez: Categorização BCE (Boundary, Control, Entity).

### Sugestão de Ações para Identificar Classes
- **Análise Textual de Abbott**:
  - Substantivos tornam-se classes ou atributos.
  - Verbos geram operações ou relações.
  - Verbos de ação levam a operações.

# Modelos de Caso de Uso, Classes e Interações em Engenharia de Software

## Modelo de Casos de Uso
- **Descreve**:
  - Conjunto de requisitos funcionais.
  - Entidades externas que interagem com o sistema.
- **Limitações**:
  - Não fornece detalhes internos do comportamento do sistema.

## Modelo de Classes
- **Descreve**:
  - Classes que compõem o sistema.
  - Relacionamentos entre as classes.
- **Limitações**:
  - Não detalha como objetos interagem para realizar um caso de uso.

## Modelos de Interações
- **Descreve**:
  - Mensagens trocadas nas interações.
  - Ordem das mensagens trocadas.
- **Realização de Caso de Uso**:
  - Interações entre objetos para executar funcionalidades de um caso de uso.
- **Elementos Comuns**:
  - Mensagens, atores, objetos e classes.
- **Atores**:
  - Iniciam o evento de troca de mensagens.

## Diagrama de Sequência
- **Foco**:
  - Emphasize na ordem temporal das mensagens.
- **Componentes**:
  - Linha de vida: Tempo em que um objeto existe.
  - Foco de controle: Período de ação de um objeto.
- **Mensagens**:
  - Especificação de comunicação entre objetos.
  - Exemplos:
    - `1: adicionar()` - Mensagem simples.
    - `2: adicionarItem(item)` - Mensagem com argumento.
    - `1.1: x := selecionar(item)` - Mensagem com valor de retorno.

### Representação de Objetos e Classes
- Objeto: Representado por variável e linha de vida.
- Classe: Representada apenas pelo nome; operações estão presentes, mas atributos não.

### Importância do Diagrama de Sequência
- O diagrama de sequência é crucial para entender a ordem e o tempo das interações entre objetos e atores no sistema.

# Projeto de Software em Engenharia de Software

## Visão Geral
- O projeto de software inclui várias disciplinas como Banco de Dados (B.D.), Interação Humano-Computador (I.H.C.), Análise de Projeto de Algoritmos (A.P.A.) e Estruturas de Dados (E.D.).

## Projeto de Banco de Dados
- **Objetivo**: Representar fatos do mundo real no banco de dados.
- **Etapas**:
  - Definição do Minimundo com participação do cliente/usuário.
  - Modelagem conceitual via Modelo Entidade Relacionamento (MER).
  - Escolha de tecnologias e padrões de Banco de Dados e SGBD.
  - Modelagem relacional para implementação.
  - Construção e manipulação do banco de dados com SQL.

## Projeto de Interação Usuário e Sistema
- Problema comum: Interfaces são frequentemente desenvolvidas tardiamente no ciclo de codificação.
- **Solução**:
  - Desenvolvimento iterativo e incremental da interface.
  - Colaboração entre usuários e desenvolvedores.
  - Uso de protótipos de diferentes fidelidades.

## Qualidade em Engenharia de Software
- **ISO 9126 / NBR 13596 Observações**:
  - Funcionalidade: Atende às necessidades?
  - Confiabilidade: Imune a falhas?
  - Usabilidade: Fácil de usar?
  - Eficiência: Rápido e enxuto?
  - Manutenibilidade: Fácil de modificar?
  - Portabilidade: Fácil de transferir?

## Processo de Desenvolvimento de Software
- **Etapas**:
  - Análise: Identificar necessidades.
  - Projeto: Decidir sobre a estrutura e tecnologias.
  - Codificação: Implementação do software.
  - Verificação e Validação: Testar e inspecionar a implementação.
  - Implantação: Entregar o produto final.
  - Evolução/Manutenção: Manter e atualizar o software.

## Interface Usuário vs. Programador
- **Desafios**:
  - Interfaces podem ser inadequadas para usuários, mas convenientes para programadores.
  - Excesso de funcionalidades implementadas, mas poucas utilizadas.
  - Mensagens de erro orientadas ao sistema, não ao usuário.

## Validação de Software e IHC
- Validação em Engenharia de Software tem sobreposição significativa com a avaliação em IHC.
- **Exemplos de Heurísticas de Nielsen**:
  - Visibilidade do status do sistema.
  - Controle do usuário e liberdade para reverter ações facilmente.

# Codificação no Desenvolvimento de Software

## Introdução à Codificação
A codificação é a etapa em que o planejamento anterior é transformado em código executável. Diagramas e planos de projeto convertem-se em software funcional. Além disso, a fase de codificação é um momento para refinar e aperfeiçoar o design do projeto.

## Reuso de Código
Não é necessário construir tudo do zero; existem alternativas eficazes para o reuso:
- **Componentes**: Blocos de construção reutilizáveis para funções comuns.
- **Frameworks**: Estruturas pré-definidas que fornecem um esqueleto de software.
- **Ferramentas de Geração de Código**: Automatizam a criação de partes do código.

## Ambiente de Desenvolvimento
Configuração adequada do ambiente é crucial para eficiência e consistência no desenvolvimento:
- **Configuração**: Inclui bibliotecas e arquivos de configuração.
- **Repositório de Códigos**: Espaço centralizado para armazenar e versionar o código fonte.
- **Ferramentas e Padrão de Codificação**: Define o conjunto de ferramentas e práticas padrão que a equipe seguirá.

### Docker
- Docker é uma ferramenta para criar contêineres que permitem a execução de ambientes isolados, facilitando a configuração e a portabilidade.

### Controle de Versão com Git
- Git é um sistema de controle de versões distribuído que suporta fluxos de trabalho colaborativos.

### Ferramentas e Padrões
- A escolha das ferramentas de desenvolvimento deve ser feita considerando as preferências da equipe e a compatibilidade com as tecnologias definidas.
- Um padrão de codificação unificado deve ser seguido para manter a consistência e a qualidade do código.

## UML para Código
- Diagramas UML são valiosos para direcionar e informar o processo de codificação:
  - **Diagrama de Caso de Uso**: Fornece uma visão geral das funcionalidades a serem implementadas.
  - **Diagrama de Classes**: Define a estrutura do sistema em termos de classes e relações.
  - **Diagramas de Interação**: Detalham os métodos necessários para realizar as funcionalidades.

# Reuso em Engenharia de Software

## Introdução ao Reuso
A Engenharia de Software (ES) evoluiu do desenvolvimento tradicional para abordagens focadas no reuso de software existente. O desenvolvimento baseado em reuso visa utilizar software pré-existente, adaptando-o quando necessário, para economizar recursos e melhorar a qualidade do produto final.

## Unidades de Reuso
O reuso pode variar em escala, incluindo:
- **Reuso de Aplicações**: Incorporação de aplicações inteiras.
- **Reuso de Componentes**: Utilização de subsistemas completos.
- **Reuso de Objetos e Funções**: Aplicação de funções, objetos ou bibliotecas específicas.

## Benefícios do Reuso
- **Redução de Custos**: Menor necessidade de desenvolvimento do zero.
- **Entregas Mais Rápidas**: Utilização de soluções pré-implementadas acelera o processo.
- **Qualidade Aprimorada**: Software reutilizado já foi testado e aprimorado.
- **Eficiência de Recursos Humanos**: Especialistas evitam trabalhos repetitivos.

## Desafios do Reuso
- **Síndrome do 'Não Inventado Aqui'**: Preferência por soluções internas.
- **Falta de Documentação**: Dificuldades por falta de materiais de apoio.
- **Custos Iniciais de Manutenção**: Aprendizado inicial pode ser desafiador.

## Panorama do Reuso
Várias técnicas podem ser adotadas para facilitar o reuso, cada uma adequada a diferentes cenários:
- **Funções**: Reuso de trechos de código.
- **Bibliotecas de Programa**: Uso de bibliotecas para funções comuns.
- **Frameworks**: Estruturas que podem ser estendidas ou adaptadas.
- **Padrões de Projeto**: Soluções genéricas para problemas recorrentes.
- **Desenvolvimento Baseado em Componentes**: Integração de componentes reutilizáveis.
- **Linhas de Produto**: Aplicações de uma arquitetura comum a diferentes produtos.

## Escolha da Técnica de Reuso
A seleção da técnica de reuso depende de vários fatores, como o tipo de software a ser desenvolvido, as tecnologias usadas, os ativos reutilizáveis disponíveis, as preferências da equipe e o nível de conhecimento dos desenvolvedores.

# Padrões de Projeto em Engenharia de Software

## Introdução
Padrões de projeto oferecem soluções reutilizáveis para problemas comuns em projeto de software orientado a objetos. Eles baseiam-se em experiências anteriores bem-sucedidas, tornando os projetos mais flexíveis, reutilizáveis e manuteníveis.

## O que é um Padrão de Projeto?
Segundo Christopher Alexander, um padrão de projeto descreve um problema recorrente e o núcleo de sua solução, permitindo que decisões de projeto ocorram mais facilmente. Um padrão é formado por:
- **Nome**: Identifica o padrão brevemente.
- **Problema**: Contextualiza o problema que o padrão resolve.
- **Solução**: Aborda de forma abstrata como o problema pode ser solucionado.
- **Consequências**: Discussão sobre vantagens e desvantagens do uso do padrão.

## Anti-padrões
Descrevem soluções ineficientes que pareciam adequadas, mas que trazem mais problemas para o projeto.

## Descrição dos Padrões GoF
Os padrões criados pelo Gang of Four (GoF) incluem detalhes como intenção, aplicabilidade, participantes, colaborações, implementação, exemplos de código, usos conhecidos e padrões relacionados.

### Exemplo: Template Method
- **Finalidade/Escopo**: Comportamento/Classe.
- **Intenção**: Definir o esqueleto de um algoritmo, permitindo que subclasses redefinam determinados passos sem alterar a estrutura do algoritmo.
- **Participantes**: `AbstractClass` e `ConcreteClass`.
- **Motivação**: Facilitar a criação de frameworks ou aplicações que necessitam de algoritmos com estruturas definidas, mas com passos variáveis.
- **Aplicabilidade**: Usado quando há partes invariantes de um algoritmo e comportamentos específicos que devem ser implementados por subclasses.

## Padrões Relacionados
- **Factory Method**: Frequentemente chamado por um método template.
- **Strategy**: Permite a substituição de passos do algoritmo definido no método template.

## Catálogo de Padrões GoF
Divididos por finalidade (criação, estrutura, comportamento) e escopo (classe, objeto), incluindo padrões como Abstract Factory, Singleton, Adapter, Strategy, entre outros.

## Padrões de Projeto em Engenharia de Software

Os padrões de projeto são soluções reutilizáveis para problemas comuns em design de software. Eles são melhores práticas aprovadas pela experiência que um programador pode usar para resolver problemas de design recorrentes de forma eficaz.

### Introdução aos Padrões de Projeto
- **Padrões de Criação:** Lidam com processos de criação de objetos, enfatizando a abstração da instância de objetos.
  - Exemplos: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
- **Padrões Estruturais:** Focam em como classes e objetos são compostos para formar estruturas maiores.
  - Exemplos: Adapter, Composite, Proxy, Flyweight, Facade, Bridge, Decorator.
- **Padrões Comportamentais:** Tratam da comunicação eficiente e da responsabilidade entre objetos.
  - Exemplos: Observer, Strategy, Command, Iterator, State, Chain of Responsibility, Mediator, Visitor, Template Method, Memento.

### Benefícios dos Padrões de Projeto
- **Reuso de Software:** Permite a reutilização de soluções de design comprovadas, reduzindo o tempo de desenvolvimento e aumentando a eficiência.
- **Soluciona Problemas de Design:** Oferece soluções testadas e aprovadas para problemas de design frequentemente encontrados.
- **Facilita a Documentação e a Comunicação entre Desenvolvedores:** Cada padrão tem um nome bem definido que pode ser usado para comunicar soluções de design de forma concisa.

### Desafios e Considerações
- **Complexidade:** A aplicação de padrões de projeto pode introduzir complexidade adicional se usada desnecessariamente.
- **Escolha Adequada:** É crucial escolher o padrão correto para a situação certa, pois uma escolha inadequada pode levar a um design pobre.

### Exemplo: Padrão Singleton
- **Objetivo:** Garantir que uma classe tenha apenas uma instância e forneça um ponto de acesso global a essa instância.
- **Uso Comum:** Usado em situações onde um ponto de controle centralizado é necessário, como em configurações globais de um aplicativo.

## Mais alguns exemplos(tem um slide só deles)

## Padrão Strategy
- **Escopo:** Comportamento / Objeto
- **Intenção e Objetivo:** Definir uma família de algoritmos, encapsular cada uma delas e torná-las intercambiáveis. O Strategy permite que o algoritmo varie independentemente dos clientes que o utilizam.
- **Sinônimo:** Policy

### Implementação
- Definição de interfaces de Strategy e Context, tornando os objetos Strategy opcionais e permitindo comportamento por falta ou específico.

### Exemplo
- Problema de impressão de documentos em formatos distintos (PDF, HTML, TXT) com uma solução baseada em Strategy separando a regra de negócio "Impressão" da representação do documento.

## Padrão Facade
- **Escopo:** Estrutura / Objeto
- **Intenção e Objetivo:** Fornecer uma interface unificada para um conjunto de interfaces em um subsistema. Facade define uma interface de nível mais alto que torna o subsistema mais fácil de ser usado.

### Motivação
- Minimizar comunicações e dependências entre subsistemas, fornecendo uma interface única para os serviços de um subsistema.

## Padrão Adapter
- **Escopo:** Estrutura / Classe*
- **Intenção e Objetivo:** Converter a interface de uma classe em outra interface esperada pelos clientes. O Adapter permite que classes com interfaces incompatíveis trabalhem juntas.

### Participantes
- **Target (Shape):** Define a interface do domínio específico que o cliente utiliza.
- **Adapter (TextShape):** Adapta a interface Adaptee para a interface Target.

## Padrão Factory Method
- **Escopo:** Criação / Classe
- **Intenção e Objetivo:** Definir uma interface para criar um objeto, mas deixar as subclasses decidirem qual classe instanciar. Factory Method permite adiar a instanciação para subclasses.

### Participantes
- **Product (Document):** Define a interface dos objetos que o Factory Method cria.
- **Creator (Application):** Declara o método fábrica que retorna um objeto do tipo Product.

## Padrão Prototype
- **Escopo:** Criação / Objeto
- **Intenção e Objetivo:** Especificar os tipos de objetos a serem criados usando uma instância protótipo e criar novos objetos pela cópia deste protótipo.

### Motivação
- Um editor de documentos pode fornecer modelos a partir dos quais o usuário irá criar seus documentos, cada modelo de documento é criado com base em um protótipo (clone).

# Padrões de Arquitetura MVC e DAO

## MVC (Model-View-Controller)

MVC é um padrão arquitetural que divide o software em três componentes interconectados:

- **Modelo (Model):** Camada de manipulação dos dados, responsável pela leitura, escrita e validação de dados.
- **Visão (View):** Camada de interação do usuário, encarregada da exibição dos dados e captura de entradas do usuário.
- **Controle (Controller):** Camada intermediária que recebe todas as requisições, conectando a visão aos modelos.

### Padrões de Projeto no MVC

Diversos padrões de projeto são aplicados no MVC para otimizar a comunicação e responsabilidades entre as camadas:

- **Observer:** Utilizado para notificar mudanças de estado do modelo às visões associadas.
- **Composite:** Permite que visões sejam compostas por um conjunto de objetos.
- **Strategy:** Emprega representação de algoritmos como objetos.
- **Decorator:** Adiciona responsabilidades a objetos dinamicamente.

## DAO (Data Access Object)

- **Motivação:** Acessar a base de dados em vários pontos da aplicação pode ser problemático. O padrão DAO propõe uma solução centralizada para a persistência dos dados, melhorando a organização e manutenção do código.
- **Descrição:** O DAO atua como intermediário entre a camada de negócios da aplicação e o meio de persistência dos dados (como bancos de dados, arquivos XML, etc.), abstraindo os detalhes de implementação da persistência.

### Participantes

- **BusinessObject:** Implementa a lógica de negócios da aplicação.
- **DataAccessObject (DAO):** Liga a camada de negócios com o meio de persistência, realizando operações de CRUD.
- **DataSource:** O meio onde os dados são persistidos (e.g., banco de dados).
- **TransferObject:** Objeto que representa uma entidade do domínio da aplicação e é utilizado para transferir dados entre camadas.

### Vantagens do DAO

- Separação clara entre a lógica de negócios e a lógica de persistência, facilitando manutenção e compreensão.
- Flexibilidade para mudar o meio de persistência sem afetar a camada de negócios.
- Encapsulamento dos detalhes da implementação de acesso aos dados.

### Desvantagens

- Aumento no número de classes devido à separação de responsabilidades.

### Formas de Implementação

- Pode-se criar um DAO geral para o sistema, um específico para cada entidade, por módulo ou para entidades relacionadas, dependendo da complexidade e necessidades específicas do projeto.

# Frameworks

Inicialmente, propôs-se que o desenvolvimento orientado a objetos era a abstração ideal para reuso. No entanto, objetos são pequenos e especializados demais para prover reuso em larga escala.

## O que é um Framework?

- Um framework é um projeto de um sistema composto por um conjunto de classes abstratas e classes concretas, além de interfaces entre estas classes.
- É uma aplicação semi acabada que pode ser reutilizada.
- Funciona como um esqueleto de aplicação onde o “comportamento” e a “aparência” desejada podem ser acopladas.

## Frameworks

- São genéricos e são estendidos para criar uma aplicação ou subsistema mais específico.
- Para criar uma aplicação baseada em um framework, é necessário implementar o comportamento específico desejado na aplicação.
- A extensão do framework envolve:
  - Adicionar classes concretas que herdam operações de classes abstratas do framework.
  - Implementar métodos que são chamados em resposta aos eventos reconhecidos pelo framework.

## Desafios no Uso de Frameworks

- A principal dificuldade relacionada ao uso de frameworks é a complexidade.
- Compreender o funcionamento e utilizar um framework pode levar algum tempo.

## Exemplo de Framework: JHotDraw

- JHotDraw é um framework para construção de editores gráficos, desenvolvido por Erich Gamma (um dos autores do GoF).
- Baseado em um conjunto de padrões de projeto.
- Editores de desenho consistem basicamente em arrumar um conjunto de elementos gráficos na tela, possuindo funcionalidades similares, mas com conjunto de elementos gráficos que pode variar.
- Exemplos de aplicação:
  - Editor de redes de petri com animações.
  - Editor para animações de química.
  - Editor de modelos UML.

# Refactoring

## Motivação

- A qualidade do projeto e do código tende a deteriorar-se com o tempo devido a pressões de negócio, restrições de tempo e bugs não identificados durante o desenvolvimento.
- Manutenções corretivas, evolutivas e adaptativas são frequentemente necessárias.

## Sobre Refatoração

- "Refatorar" significa melhorar o design de um código já existente sem alterar seu comportamento externo, visando uma melhor qualidade interna.
- Refatoração é crucial para a manutenibilidade do software.
- William Opdyke introduziu o termo em sua tese de doutorado em 1992, enquanto Kent Beck e Martin Fowler são grandes promotores da prática.

## Processo de Refatoração

1. Identificar "code smells" – sinais de problemas no código.
2. Selecionar a refatoração apropriada.
3. Aplicar a refatoração.
4. Compilar e testar para garantir que não houve mudanças no comportamento.
5. Repetir o processo para contínua melhoria.

## Code Smells

- Indicativos de problemas no design ou código que podem necessitar refatoração.
- Categorias principais incluem Bloaters, Object-Orientation Abusers, Change Preventers, Dispensables e Couplers.

### Exemplos Comuns de Code Smells

- **Long Method:** Métodos muito longos, difíceis de ler e manter.
- **Large Class:** Classes com muitas responsabilidades.
- **Switch Statements:** Uso excessivo pode indicar a necessidade de polimorfismo.
- **Shotgun Surgery:** Pequenas mudanças que requerem muitas modificações em várias classes.

## Código Limpo

- Facilmente compreensível por outros programadores.
- Sem duplicações e a solução mais simples.
- Passa todos os testes.
- Fácil e barato de manter.

## Catálogo de Refatorações

- **Extract Method:** Para longos blocos de código que podem ser agrupados.
- **Rename Method:** Quando o nome do método não descreve sua função.
- **Remove Magic Numbers:** Substituir números mágicos por constantes nomeadas para clareza.

## Refatorações Específicas

- **Desvendando Números Mágicos:** Substituir números mágicos por constantes nomeadas para melhor clareza e manutenibilidade.

## Considerações Finais sobre Refatoração

- A coesão e o acoplamento devem ser constantemente avaliados para assegurar um design eficaz.
- Preferir delegação/associações em vez de herança para evitar alto acoplamento.
- Testes automáticos são essenciais para garantir que as modificações não alterem o comportamento esperado do software.
- A refatoração deve ser aplicada continuamente para manter a qualidade e a manutenibilidade do software.

# no slide tem exemplos melhores e mais detalhados, não coloquei aqui

# Verificação e Validação (V&V)

## Introdução

- V&V são atividades com objetivos distintos:
  - **Verificação:** "Estamos construindo o produto corretamente?" Checa se o software está de acordo com suas especificações.
  - **Validação:** "Estamos construindo o produto correto?" Avalia se o sistema atende às expectativas do cliente/usuário.

- Importância de V&V:
  - Descobrir defeitos/limitações no software.
  - Avaliar a utilidade e usabilidade em uma situação operacional.

## Verificação vs. Validação

- **Verificação:** Focada na especificação, identifica problemas em relação ao especificado.
- **Validação:** Focada no usuário, busca identificar problemas junto ao usuário.

## Atividades de V&V

- Incluem planejamento, preparação, execução e acompanhamento.

## Verificação Estática vs. Dinâmica

- **Inspeções de Software (Verificação Estática):** Observação de representações estáticas do sistema para descobrir problemas.
- **Teste de Software (Verificação Dinâmica):** Execução do produto para observar seu comportamento e identificar defeitos.

## Inspeções de Software

- Abordagem formalizada para revisão de artefatos (código, requisitos, etc.).
- Não requer execução do software.
- Voltada para detecção de erros, não correção.

### Code Review

- Uma atividade de inspeção importante. Documentação de práticas pode ser encontrada na documentação de práticas de engenharia do Google.

### Análise Estática Automatizada

- Ferramentas que auxiliam na inspeção de software, como Lint e checkstyle.

## Testes de Software

- **Classificação dos Testes:**
  - **Por Perspectiva:** 
  - - **Teste Caixa-Branca:** Foco no funcionamento interno do software. Utiliza conhecimento do código para testar caminhos específicos e condições.
  - - **Teste Caixa-Preta:** Avalia o software baseado em sua funcionalidade externa, sem considerar como as funções são executadas internamente. Baseia-se nas especificações para criar testes que cubram todas as funcionalidades.
  - **Por Objetivo:** Teste de validação (checar se atende requisitos) vs. Teste de defeitos (identificar defeitos).
  - **Por Fase de Aplicação:** Teste de unidade, Teste de Integração, Teste de Sistema.
  - **Por Critério de Aplicação:** Teste funcional, Teste estrutural, Teste baseado em defeito.

### Tipos de Teste

- **Teste de Sistema:** Testa o sistema como um todo.
- **Teste de Componente/Unidade:** Testa partes individuais do sistema.
- **Teste de Integração:** Checa problemas na interação entre componentes.

## Estratégias de V&V

- **Estratégia de Teste em V:** Abordagem tradicional que segue a sequência de desenvolvimento.
- **Desenvolvimento Guiado por Testes (TDD):** Ciclo iterativo de escrita de teste antes do código, implementação e refatoração.

## Termos Importantes

- **Defeito, Engano, Erro, Falha:** Conceitos relacionados a problemas encontrados durante V&V.
- **Domínio de Entrada, Dado de Teste, Caso de Teste, Conjunto de Teste:** Elementos fundamentais na definição de testes.

### Domínio de Entrada e Testes
- **Domínio de Entrada (D(P)):** Todos os possíveis valores de entrada que o programa pode receber.
- **Caso de Teste:** Combinação de condições de entrada e saídas esperadas usadas para verificar a conformidade do comportamento do software.


## Teste vs. Debugging

- **Teste:** Identificação de defeitos.
- **Debugging:** Localização e reparação de defeitos.

## Critérios de Teste

- O projeto de casos de teste é uma etapa fundamental no processo de teste de software, visando gerar um conjunto de casos que possam ser efetivamente utilizados para validar e verificar o software. O desafio está em selecionar os elementos que farão parte desse conjunto.

### Teste Exaustivo

- Realizar um teste exaustivo, selecionando todos os elementos do domínio de teste, é impraticável devido à vasta quantidade de possíveis casos de teste. Por exemplo, para um programa que calcula \(x^y\), o conjunto de teste para todos os pares de inteiros possíveis teria uma cardinalidade gigantesca, tornando a execução de todos os casos humanamente impossível.

### Teste Aleatório

- O teste aleatório seleciona uma grande quantidade de casos de forma aleatória, na esperança de cobrir todos os subdomínios do domínio de entrada (\(D(P)\)). Apesar de ser uma estratégia mais viável que o teste exaustivo, ainda é considerada ineficiente devido à sua natureza aleatória.

### Teste de Partições

- Uma abordagem mais eficiente é o teste de partições, que divide os dados de entrada e saída em classes ou partições. Testar todas as partições, e não cada dado individualmente, pode ser uma maneira mais prática e eficaz de garantir a cobertura do teste.

## Critérios para Geração de Conjunto de Teste

- **Teste Exaustivo:** Impraticável devido ao seu vasto escopo.
- **Teste Aleatório:** Ineficiente pela sua aleatoriedade.
- **Teste de Partição:** Dividir o domínio de entrada em partições para realizar os testes.
- **Teste Funcional (Caixa-Preta):** Baseado na especificação do programa, foca na funcionalidade sem considerar a estrutura interna.
  - **Particionamento de Equivalência**
  - **Análise do Valor Limite**
  - **Teste Funcional Sistemático**
- **Teste Estrutural (Caixa-Branca):** Deriva casos de teste com base na estrutura interna do programa.
  - **Teste de Comando**
  - **Teste de Decisão**
  - **Teste de Condição**
  - **Teste de Caminho**
- **Teste Baseado em Defeitos (Caixa-Branca):** Cria casos de teste com base no conhecimento de defeitos comuns na codificação.
  - **Teste de Mutação (ou Análise de Mutantes)**

## Particionamento de Equivalência

- Esse critério divide o domínio do programa em subconjuntos representativos, simplificando a seleção de casos de teste. É aplicado tanto aos elementos de entrada quanto de saída, agrupando elementos válidos e inválidos conforme a especificação do programa.

## Teste Estrutural (Caixa-Branca)

- O teste estrutural, ou teste caixa-branca, gera casos de teste explorando a estrutura interna do código. Isso permite verificar se o conjunto de teste cobre adequadamente o código do programa. Os critérios estruturais são complementares aos funcionais, contribuindo para uma cobertura de teste mais abrangente.

### Grafo de Fluxo de Controle (GFC)

- O GFC é um modelo que representa a estrutura interna de um programa, mostrando blocos de código (vértices) e como o controle é transferido entre eles (arestas). É utilizado para apoiar a verificação dos critérios estruturais, ajudando a garantir que todos os trechos do programa sejam exercitados pelos testes.

### Teste de Caminho Básico

- Baseado na complexidade ciclomática, este critério estipula que todos os caminhos linearmente independentes do GFC devem ser percorridos pelos casos de teste. A complexidade ciclomática ajuda a determinar a quantidade de caminhos básicos e, consequentemente, o número máximo de casos de teste necessários.

### Complexidade Ciclomática

- A complexidade ciclomática é calculada com base no GFC e fornece uma medida da complexidade do programa, indicando o número de caminhos linearmente independentes. Ela orienta na definição do limite máximo de casos de teste necessários para uma cobertura completa.

### Teste de Comando

- Este critério assegura que todos os comandos do programa sejam executados ao menos uma vez, garantindo que todos os nós do GFC sejam visitados.

# Grande parte dessa parte do conteudo ficou melhor explicada em imagens nos slides, recomendo ver lá :)