Capítulo 20: Projeto Integrador Final - FastLog TMS Enterprise

🎯 Objetivo da Aula

Chegou o momento de consolidar todos os conhecimentos adquiridos ao longo dos 20 capítulos do curso. Você iniciou aprendendo o que é um algoritmo e agora domina a Lógica de Programação Estruturada com sintaxe moderna C/Java no Portugol Studio.

Nesta aula final, você desenvolverá o Projeto Integrador FastLog TMS (Transportation Management System) Enterprise, um software corporativo completo em modo console que integra:

  1. Menus de navegação contínuos com faca-enquanto e escolha-caso.
  2. Persistência em memória com vetores paralelos para controle de 5 caminhões.
  3. Funções modulares de interface (funcao vazio) e funções de cálculo estatístico (funcao real).
  4. Algoritmos de busca linear com flag booleana e localização de maior valor.

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


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

Situação: A diretoria executiva da FastLog aprovou o projeto de automação da torre de controle operacional. O software precisa gerenciar a frota titular de 5 carretas pesadas, oferecendo aos operadores:

  • Módulo 1 (Cadastro de Frota): Registro do Nome do Motorista Titular, Placa do Veículo (padrão Mercosul de 7 dígitos) e Quilometragem Mensal Rodada.
  • Módulo 2 (Relatório de Performance): Tabela alinhada com todos os veículos, Quilometragem Total da frota e Média de KM por caminhão.
  • Módulo 3 (Auditoria do Campeão): Identificação automática do motorista que mais rodou no mês para receber o Prêmio de Eficiência.
  • Módulo 4 (Localizador Instantâneo): Busca dinâmica de caminhão por nome do motorista.

Missão: Programar o sistema completo seguindo a Arquitetura em 3 Camadas e apresentá-lo 100% funcional.

Por que este capítulo não tem “Checkpoint” nem “Desafio de Fixação”?
Por ser o Projeto Integrador Final, este capítulo substitui essas duas seções pelo 🛠️ Roteiro de Testes e Validação (ao final) — em vez de um exercício novo e isolado, sua tarefa é validar o sistema completo que acabou de construir, módulo por módulo.


🧠 Fundamentos: A Arquitetura em 3 Camadas do Sistema

graph TD
    UI["1. CAMADA DE APRESENTAÇÃO (UI / Menu Principal)<br/>faca { ... } enquanto (opcao != 0)"] --> Router{"escolha opcao"}
    
    Router -->|1| ModCad["Módulo 1: cadastrar_veiculos()<br/>(funcao vazio)"]
    Router -->|2| ModRel["Módulo 2: emitir_relatorio()<br/>(funcao vazio + somar_km_total)"]
    Router -->|3| ModAud["Módulo 3: identificar_campeao()<br/>(funcao vazio / Maior Elemento)"]
    Router -->|4| ModBus["Módulo 4: pesquisar_motorista()<br/>(Busca Linear com Flag)"]
    
    ModCad --> DB[(Camada de Dados em RAM:<br/>Vetores nomes, placas e kmRodados)]
    ModRel --> DB
    ModAud --> DB
    ModBus --> DB
    
    style UI fill:#8e44ad,stroke:#fff,color:#fff
    style Router fill:#f39c12,stroke:#fff,color:#fff
    style DB fill:#217346,stroke:#fff,color:#fff

Cada um dos 4 módulos acima aplica o Princípio da Responsabilidade Única (SRP) que você aprendeu no Capítulo 19: cada função tem exatamente uma responsabilidade (cadastrar, relatar, auditar ou buscar). É exatamente por causa dessa separação que é possível testar e corrigir cada módulo isoladamente, sem afetar os demais — veja o Roteiro de Testes e Validação ao final deste capítulo, que testa cada módulo em separado.


📖 O Código-Fonte Completo do Projeto Integrador

  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
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
programa 
{
	// ============================================================================
	// PROJETO INTEGRADOR: FASTLOG TRANSPORTATION MANAGEMENT SYSTEM (TMS)
	// Versão: 3.0 Enterprise (Portugol Studio)
	// ============================================================================

	// 1. CAMADA DE PERSISTÊNCIA EM MEMÓRIA (BANCO DE DADOS EM RAM)
	cadeia nomes[5]
	cadeia placas[5]
	real kmRodados[5]
	inteiro totalCadastrados = 0

	// ============================================================================
	// 2. CAMADA DE PROCESSAMENTO E FUNÇÕES MATEMÁTICAS PURAS
	// ============================================================================

	// Função 1: Somatório Total de Quilometragem
	funcao real somar_km_total() 
	{
		real soma = 0.0
		para (inteiro i = 0; i < totalCadastrados; i++) 
		{
			soma += kmRodados[i]
		}
		retorne soma
	}

	// Função 2: Média de Quilometragem da Frota
	funcao real calcular_media_km() 
	{
		se (totalCadastrados > 0) 
		{
			retorne somar_km_total() / totalCadastrados
		} 
		senao 
		{
			retorne 0.0
		}
	}

	// ============================================================================
	// 3. CAMADA DE MÓDULOS OPERACIONAIS E PROCEDIMENTOS DE INTERFACE
	// ============================================================================

	funcao vazio desenhar_cabecalho(cadeia titulo) 
	{
		escreva("==================================================\n")
		escreva("         FASTLOG TMS - SISTEMA DE FROTAS          \n")
		escreva("   ", titulo, "\n")
		escreva("==================================================\n")
	}

	funcao vazio cadastrar_veiculos() 
	{
		desenhar_cabecalho("MÓDULO 1: CADASTRO DE FROTA")
		para (inteiro i = 0; i < 5; i++) 
		{
			escreva("--- VEÍCULO #", i+1, " ---\n")
			escreva("Nome do Motorista Titular : ")
			leia(nomes[i])
			escreva("Placa do Veículo (Mercosul): ")
			leia(placas[i])

			faca 
			{
				escreva("Quilometragem Mensal (KM)  : ")
				leia(kmRodados[i])
				se (kmRodados[i] < 0.0) 
				{
					escreva("[ERRO]: A quilometragem não pode ser negativa!\n")
				}
			} enquanto (kmRodados[i] < 0.0)

			escreva("\n")
		}
		totalCadastrados = 5
		escreva(">> [SUCESSO] 5 veículos cadastrados e integrados ao sistema!\n")
	}

	funcao vazio emitir_relatorio_performance() 
	{
		se (totalCadastrados == 0) 
		{
			escreva(">> [ALERTA] Nenhum veículo cadastrado. Execute a Opção [1] primeiro.\n")
		} 
		senao 
		{
			desenhar_cabecalho("MÓDULO 2: RELATÓRIO DE PERFORMANCE")
			escreva(" ID | MOTORISTA TITULAR   | PLACA   | KM RODADOS  \n")
			escreva("----+---------------------+---------+-------------\n")
			para (inteiro i = 0; i < totalCadastrados; i++) 
			{
				escreva(" #", i+1, " | ", nomes[i], "\t\t| ", placas[i], " | ", kmRodados[i], " km\n")
			}
			escreva("--------------------------------------------------\n")
			escreva("TOTAL KM ACUMULADO NA FROTA : ", somar_km_total(), " km\n")
			escreva("MÉDIA DE QUILOMETRAGEM/VEÍCULO: ", calcular_media_km(), " km\n")
			escreva("==================================================\n")
		}
	}

	funcao vazio identificar_campeao() 
	{
		se (totalCadastrados == 0) 
		{
			escreva(">> [ALERTA] Cadastre os veículos antes de apurar o destaque.\n")
		} 
		senao 
		{
			real maiorKm = kmRodados[0]
			inteiro posCampeao = 0

			para (inteiro i = 1; i < totalCadastrados; i++) 
			{
				se (kmRodados[i] > maiorKm) 
				{
					maiorKm = kmRodados[i]
					posCampeao = i
				}
			}

			desenhar_cabecalho("MÓDULO 3: CAMPEÃO DE PRODUTIVIDADE")
			escreva(">> MOTORISTA HOMENAGEADO DO MÊS:\n")
			escreva("   Colaborador : ", nomes[posCampeao], "\n")
			escreva("   Veículo     : Placa ", placas[posCampeao], "\n")
			escreva("   Total Rodado: ", maiorKm, " km\n")
			escreva("   Bonificação : R$ 1.500,00 (Prêmio Eficiência)\n")
			escreva("==================================================\n")
		}
	}

	funcao vazio pesquisar_motorista() 
	{
		se (totalCadastrados == 0) 
		{
			escreva(">> [ALERTA] Base de dados vazia. Cadastre os veículos primeiro.\n")
		} 
		senao 
		{
			cadeia termoBusca
			logico localizado = falso

			desenhar_cabecalho("MÓDULO 4: LOCALIZADOR DE VEÍCULO")
			escreva("Digite o nome exato do motorista: ")
			leia(termoBusca)

			para (inteiro i = 0; i < totalCadastrados; i++) 
			{
				se (nomes[i] == termoBusca) 
				{
					escreva("\n>> [REGISTRO ENCONTRADO NO BANCO]:\n")
					escreva("   Box no Pátio    : Vaga #", i+1, "\n")
					escreva("   Motorista       : ", nomes[i], "\n")
					escreva("   Placa do Veículo: ", placas[i], "\n")
					escreva("   KM Acumulada    : ", kmRodados[i], " km\n")
					localizado = verdadeiro
					pare
				}
			}

			se (nao localizado) 
			{
				escreva("\n>> [AVISO]: Motorista '", termoBusca, "' não foi localizado na base.\n")
			}
			escreva("==================================================\n")
		}
	}

	// ============================================================================
	// 4. BLOCO PRINCIPAL DE EXECUÇÃO (INTERFACE DO USUÁRIO)
	// ============================================================================

	funcao inicio() 
	{
		inteiro opcaoMenu

		faca 
		{
			escreva("\n")
			desenhar_cabecalho("PAINEL OPERACIONAL PRINCIPAL")
			escreva(" [1] Cadastrar 5 Veículos da Frota\n")
			escreva(" [2] Emitir Relatório Geral de Performance\n")
			escreva(" [3] Apurar Motorista Destaque (Maior KM)\n")
			escreva(" [4] Pesquisar Veículo por Nome de Motorista\n")
			escreva(" [0] Finalizar e Desconectar do Sistema\n")
			escreva("==================================================\n")
			escreva("Selecione a operação desejada: ")
			leia(opcaoMenu)

			escreva("\n")
			escolha (opcaoMenu) 
			{
				caso 1:
					cadastrar_veiculos()
					pare
				caso 2:
					emitir_relatorio_performance()
					pare
				caso 3:
					identificar_campeao()
					pare
				caso 4:
					pesquisar_motorista()
					pare
				caso 0:
					escreva(">> Desconectando da torre de controle... Até logo!\n")
					pare
				caso contrario:
					escreva(">> [ERRO]: Opção inválida! Digite um número de 0 a 4.\n")
			}
		} enquanto (opcaoMenu != 0)
	}
}

🛠️ Roteiro de Testes e Validação do Projeto

  1. Teste Defensivo: Ao iniciar, tente acessar a opção [2]. O sistema deve emitir o aviso amigável de base vazia sem travar.
  2. Teste de Cadastro: Acesse a opção [1] e cadastre 5 motoristas com placas e quilometragens (ex: 3.500 km, 6.200 km, 4.100 km, 7.800 km e 5.000 km).
  3. Teste de Relatório: Acesse a opção [2] e confira se a soma (26.600 km) e a média (5.320 km) aparecem alinhadas.
  4. Teste de Destaque: Acesse a opção [3] e valide se o motorista de 7.800 km é reconhecido como campeão.
  5. Teste de Busca: Acesse a opção [4] e teste um nome existente e um inexistente.
  6. Encerramento: Digite 0 para finalizar a sessão.

📤 Instruções de Entrega Final (Microsoft Teams)

  1. Salve o arquivo com o nome: PROJETO_FINAL_SeuNome_SeuSobrenome.por.
  2. No Microsoft Teams, envie na tarefa final “Portugol Cap 20 - Projeto Integrador”.
  3. Clique em Entregar (Turn In).

🎓 Mensagem de Encerramento e Próximos Passos

Parabéns! Você concluiu com sucesso a jornada completa de Lógica de Programação com Portugol Studio.

A partir de agora, a sintaxe de linguagens como C, C++, Java, C#, PHP e JavaScript será familiar e intuitiva para você, pois as estruturas fundamentais — chaves { }, operadores ==, loops while/for e indexação 0..N-1 — já estão gravadas no seu raciocínio lógico. Sucesso na sua jornada como desenvolvedor de software!


📝 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. Segundo o diagrama de Arquitetura em 3 Camadas, quais são os 4 módulos operacionais roteados a partir do menu principal (escolha opcao)?
  2. Quantos veículos o Sistema FastLog TMS gerencia, e quais três vetores paralelos armazenam os dados de cada um?
  3. O que faz a função somar_km_total(), e como a função calcular_media_km() reutiliza o resultado dela?
  4. No módulo cadastrar_veiculos(), qual validação defensiva é aplicada à quilometragem digitada, usando um laço faca ... enquanto?
  5. No módulo identificar_campeao(), qual algoritmo é usado para encontrar o motorista com maior quilometragem, e a partir de qual índice o laço de comparação começa?
  6. No módulo pesquisar_motorista(), qual técnica é usada para indicar se o motorista foi ou não localizado no vetor de nomes?
  7. Segundo o Roteiro de Testes e Validação, o que deve acontecer se o operador tentar acessar a opção [2] (Relatório) antes de cadastrar qualquer veículo?
  8. Segundo o Roteiro de Testes, com as quilometragens de exemplo sugeridas (3.500, 6.200, 4.100, 7.800 e 5.000 km), qual deve ser o total somado e a média da frota?
  9. Segundo a Mensagem de Encerramento, quais estruturas fundamentais aprendidas no curso preparam você para reconhecer a sintaxe de linguagens como C, C++, Java, C# e JavaScript?
  10. Explique, com suas palavras, por que dividir o Projeto Integrador em módulos separados (cadastro, relatório, auditoria, busca) — em vez de escrever tudo dentro de inicio() — facilita testar e corrigir o sistema.