Capítulo 19: Engenharia de Software e Decomposição Algorítmica

🎯 Objetivo da Aula

Programar não é apenas escrever linhas de código: é projetar arquiteturas funcionais. Antes de abrir o computador e digitar, um engenheiro de software precisa entender como quebrar um problema gigantesco em partes pequenas, independentes e testáveis (Top-Down Design).

Nesta aula, você aprenderá a:

  1. Aplicar o método de Decomposição Top-Down para resolução de problemas complexos.
  2. Implementar o princípio de Separação de Responsabilidades (Single Responsibility Principle).
  3. Adotar técnicas de Programação Defensiva (blindagem contra falhas do operador).
  4. Construir um subsistema modular completo de controle de estoque com operações de cadastro, listagem e auditoria.

📥 Material de Apoio e Código-Fonte da Aula:


🏢 O Cenário Prático (Seu Desafio)

Situação: O almoxarifado de peças da FastLog opera sem informatização, gerando perdas financeiras por falta de controle do valor total estocado e duplicidade de cadastros. A gerência solicitou um software em terminal que gerencie até 5 produtos em memória, permitindo:

  1. Cadastrar Produtos (com validação de preços e quantidades positivas).
  2. Listar Estoque (com exibição tabular alinhada).
  3. Calcular Patrimônio Total (somatório financeiro de todos os itens).

Missão: Projetar e programar esse sistema dividindo rigorosamente as tarefas em procedimentos e funções especializadas, sem concentrar tudo no bloco principal.


🧠 Fundamentos: A Metodologia Top-Down

1. Decomposição Top-Down (Do Todo para as Partes)

Em vez de tentar resolver o sistema inteiro de uma só vez, nós o quebramos em camadas hierárquicas:

graph TD
    Root["Sistema de Estoque FastLog"] --> M1["Módulo 1: Interface & Menu (Procedimento)"]
    Root --> M2["Módulo 2: Entrada & Cadastro (Procedimento)"]
    Root --> M3["Módulo 3: Relatórios & Listagem (Procedimento)"]
    Root --> M4["Módulo 4: Cálculos Financeiros (Função)"]
    
    style Root fill:#8e44ad,stroke:#fff,stroke-width:2px,color:#fff
    style M1 fill:#2980b9,stroke:#fff,stroke-width:2px,color:#fff
    style M2 fill:#2980b9,stroke:#fff,stroke-width:2px,color:#fff
    style M3 fill:#2980b9,stroke:#fff,stroke-width:2px,color:#fff
    style M4 fill:#27ae60,stroke:#fff,stroke-width:2px,color:#fff

2. O Princípio da Responsabilidade Única (SRP)

Cada módulo deve ter um único motivo para mudar:

  • O procedimento de Cadastro só se preocupa em ler dados e validar se são válidos.
  • O procedimento de Listagem só se preocupa em desenhar a tabela formatada.
  • A função de Cálculo só se preocupa em fazer a matemática e devolver o número.

📖 Exemplo Guiado: Subsistema Modular de Estoque

Código do Algoritmo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
algoritmo "Almoxarifado_Modular"
var
   nomes : vetor [1..3] de caractere
   quantidades : vetor [1..3] de inteiro
   precos : vetor [1..3] de real
   opcao : inteiro
   totalCadastrado : inteiro

// 1. Procedimento de Cadastro
procedimento CadastrarItens()
var
   i : inteiro
inicio
   escreval("--- CADASTRO DE 3 PRODUTOS ---")
   para i de 1 ate 3 faca
      escreva("Nome do Item #", i, ": ") leia(nomes[i])
      escreva("Quantidade em Saldo: ") leia(quantidades[i])
      escreva("Preço Unitário (R$): ") leia(precos[i])
   fimpara
   totalCadastrado <- 3
   escreval(">> [SUCESSO] 3 itens registrados com sucesso!")
fimprocedimento

// 2. Procedimento de Listagem
procedimento ListarEstoque()
var
   i : inteiro
inicio
   se (totalCadastrado = 0) entao
      escreval(">> [AVISO] Nenhum produto cadastrado no momento.")
   senao
      escreval("==================================================")
      escreval(" ID | NOME DO PRODUTO        | QTD  | PREÇO (R$)  ")
      escreval("----+------------------------+------+-------------")
      para i de 1 ate totalCadastrado faca
         escreval(" #", i, " | ", nomes[i]:22, " | ", quantidades[i]:4, " | R$ ", precos[i]:8:2)
      fimpara
      escreval("==================================================")
   fimse
fimprocedimento

// 3. Função de Cálculo do Patrimônio Financeiro
funcao CalcularPatrimonioTotal() : real
var
   i : inteiro
   soma : real
inicio
   soma <- 0.0
   para i de 1 ate totalCadastrado faca
      soma <- soma + (quantidades[i] * precos[i])
   fimpara
   retorne soma
fimfuncao

inicio
   totalCadastrado <- 0

   repita
      escreval("")
      escreval("=== FASTLOG INVENTORY MANAGEMENT ===")
      escreval(" [1] Cadastrar Itens do Lote")
      escreval(" [2] Listar Tabela de Estoque")
      escreval(" [3] Calcular Valor Total do Estoque")
      escreval(" [0] Sair")
      escreva("Escolha uma opção: ")
      leia(opcao)

      escreval("")
      escolha opcao
         caso 1: CadastrarItens()
         caso 2: ListarEstoque()
         caso 3: escreval("VALOR TOTAL IMOBILIZADO: R$ ", CalcularPatrimonioTotal():10:2)
         caso 0: escreval("Encerrando o módulo...")
         outrocaso: escreval("Opção inválida!")
      fimescolha
   ate (opcao = 0)
fimalgoritmo

🛠️ Prática Obrigatória 1: Procedimento de Busca Modularizada

Passo 1: O Desafio

Adicione ao sistema acima um procedimento chamado BuscarProdutoPorNome():

  1. O procedimento deve pedir ao usuário o nome do produto a ser pesquisado.
  2. Varrer o vetor e, se encontrar, imprimir a quantidade e o preço.
  3. Se não encontrar, emitir o aviso de produto inexistente usando a técnica da flag booleana.
  4. Adicione a opção [4] Pesquisar por Nome ao menu principal.

🛠️ Prática Obrigatória 2: Validação Defensiva de Quantidades

Modifique o procedimento de cadastro para implementar Programação Defensiva:

  • A quantidade deve ser estritamente maior que zero (qtd > 0). Se o usuário digitar zero ou negativo, utilize um laço repita-ate para forçar a digitação de um valor correto.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_19_SeuNome_SeuSobrenome.alg.
  2. Teste o fluxo completo do menu e certifique-se de que a modularização está impecável.
  3. No Microsoft Teams, envie na tarefa “VisuAlg Cap 19 - Decomposição Algorítmica”.
  4. Clique em Entregar (Turn In).

💡 Checkpoint de Lógica & Engenharia de Software

Você acabou de aplicar o conceito de Arquitetura Orientada a Serviços (SOA) e CRUD (Create, Read, Update, Delete). Esse padrão de divisão modular em menus e manipuladores de ação é a fundação de sistemas corporativos como SAP, Totvs e Salesforce.


🔥 Desafio de Fixação: Função de Localização de Item Mais Valioso

Crie uma função ItemMaisValioso() : caractere que percorra o vetor de preços e retorne o nome do produto que possui o maior valor unitário cadastrado.


🔑 Gabarito de Código Completo

Prática 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
algoritmo "Busca_Produto_Modular"
var
   nomes : vetor [1..3] de caractere
   quantidades : vetor [1..3] de inteiro
   precos : vetor [1..3] de real
   totalCadastrado : inteiro

procedimento BuscarProdutoPorNome()
var
   busca : caractere
   i : inteiro
   achou : logico
inicio
   escreva("Digite o nome do produto: ") leia(busca)
   achou <- FALSO
   para i de 1 ate totalCadastrado faca
      se (nomes[i] = busca) entao
         escreval(">> [ENCONTRADO]: ", nomes[i], " | Qtd: ", quantidades[i], " | Preço: R$ ", precos[i]:8:2)
         achou <- VERDADEIRO
      fimse
   fimpara
   se (nao achou) entao
      escreval(">> [NÃO ENCONTRADO]: Produto '", busca, "' não consta no cadastro.")
   fimse
fimprocedimento

inicio
   nomes[1] <- "Palete Madeira"
   quantidades[1] <- 150
   precos[1] <- 45.00
   
   nomes[2] <- "Fita Stretch"
   quantidades[2] <- 400
   precos[2] <- 22.50
   
   nomes[3] <- "Caixa Papelão"
   quantidades[3] <- 800
   precos[3] <- 8.90
   totalCadastrado <- 3

   BuscarProdutoPorNome()
fimalgoritmo

Prática 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
algoritmo "Cadastro_Defensivo"
var
   nomes : vetor [1..3] de caractere
   quantidades : vetor [1..3] de inteiro
   precos : vetor [1..3] de real
   i : inteiro

inicio
   escreval("--- CADASTRO COM VALIDAÇÃO DEFENSIVA ---")
   para i de 1 ate 3 faca
      escreva("Nome do Produto #", i, ": ") leia(nomes[i])
      
      repita
         escreva("Quantidade (> 0): ") leia(quantidades[i])
         se (quantidades[i] <= 0) entao
            escreval("[ERRO]: A quantidade deve ser positiva!")
         fimse
      ate (quantidades[i] > 0)

      repita
         escreva("Preço Unitário R$ (> 0): ") leia(precos[i])
         se (precos[i] <= 0) entao
            escreval("[ERRO]: O preço deve ser maior que zero!")
         fimse
      ate (precos[i] > 0)
   fimpara
   escreval(">> 3 produtos cadastrados com sucesso!")
fimalgoritmo

Desafio:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
algoritmo "Item_Mais_Valioso"
var
   nomes : vetor [1..3] de caractere
   precos : vetor [1..3] de real
   totalCadastrado : inteiro

funcao ItemMaisValioso() : caractere
var
   maiorPreco : real
   posMaior, i : inteiro
inicio
   maiorPreco <- precos[1]
   posMaior <- 1
   para i de 2 ate totalCadastrado faca
      se (precos[i] > maiorPreco) entao
         maiorPreco <- precos[i]
         posMaior <- i
      fimse
   fimpara
   retorne nomes[posMaior]
fimfuncao

inicio
   nomes[1] <- "Palete Madeira"
   precos[1] <- 45.00
   nomes[2] <- "Fita Stretch"
   precos[2] <- 22.50
   nomes[3] <- "Caixa Papelão"
   precos[3] <- 8.90
   totalCadastrado <- 3

   escreval("Item de Maior Preço: ", ItemMaisValioso())
fimalgoritmo

📝 Atividade Extra: Questionário de Fixação (Caderno)

Instruções: Responda no caderno, de próprio punho, as 10 perguntas abaixo com base no que foi estudado neste capítulo. Ao concluir, leve o caderno até o professor para correção e visto.

  1. O que é a metodologia de Decomposição Top-Down, segundo os Fundamentos deste capítulo?
  2. Quais são os quatro módulos em que o Sistema de Estoque FastLog é dividido, segundo o diagrama de decomposição?
  3. Segundo o Princípio da Responsabilidade Única (SRP), qual é a única preocupação do procedimento de Cadastro, do procedimento de Listagem e da função de Cálculo?
  4. No Cenário Prático, quantos produtos o sistema de almoxarifado deve gerenciar em memória, e quais três operações ele deve permitir?
  5. No Exemplo Guiado (Almoxarifado_Modular), quais são os três vetores paralelos usados para armazenar os dados de cada produto?
  6. No algoritmo Almoxarifado_Modular, qual estrutura de repetição controla o laço do menu principal, e com que condição ela termina?
  7. Na Prática Obrigatória 1, qual técnica (já estudada em capítulo anterior) deve ser usada para avisar quando um produto pesquisado não é encontrado?
  8. Na Prática Obrigatória 2, qual condição deve ser validada repetidamente com repita-ate antes de aceitar a quantidade digitada pelo usuário?
  9. Segundo o Checkpoint de Lógica, a que padrão de arquitetura de software (e a que sigla de operações) o sistema modular em menus está associado, e quais três sistemas corporativos são citados como exemplo?
  10. Na função CalcularPatrimonioTotal() do Exemplo Guiado, qual cálculo é somado ao acumulador soma a cada iteração do laço para?