11 Chatbot de console
Integrar os fundamentos em uma aplicação completa
11.1 Objetivos de aprendizagem
Ao concluir este capítulo, você deverá ser capaz de:
- integrar entrada, decisão, repetição, métodos, listas e exceções;
- definir claramente o contrato de cada comando;
- separar interação de console das regras do chatbot;
- manter uma semântica consistente para o histórico.
11.2 Contrato de comandos
Nesta versão:
oi: apresenta o bot;ajuda: lista comandos;dica: mostra uma dica de Java;historico: mostra interações anteriores;sair: encerra a conversa.
Mensagens vazias não entram no histórico. Os comandos historico e sair também não são registrados. Cada interação normal gera duas linhas: uma da pessoa usuária e uma do bot.
11.3 Implementação integrada
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
public class Capitulo10Chatbot {
private final String nome;
private final List<String> historico = new ArrayList<>();
public Capitulo10Chatbot(String nome) {
if (nome == null || nome.isBlank()) {
throw new IllegalArgumentException("Nome obrigatório.");
}
this.nome = nome.strip();
}
private static String normalizar(String texto) {
if (texto == null) {
return "";
}
return texto.strip().toLowerCase(Locale.ROOT);
}
public String responder(String entrada) {
String comando = normalizar(entrada);
if (comando.isBlank()) {
return "Digite uma mensagem.";
}
if (comando.equals("historico")) {
return historico.isEmpty()
? "Sem histórico."
: String.join(System.lineSeparator(), historico);
}
String resposta = switch (comando) {
case "oi" -> "Olá! Eu sou " + nome + ".";
case "ajuda" -> "Comandos: oi, ajuda, dica, historico e sair.";
case "dica" -> "Compile e teste depois de cada pequena mudança.";
default -> "Não entendi. Digite ajuda.";
};
historico.add("USUÁRIO: " + entrada.strip());
historico.add("BOT: " + resposta);
return resposta;
}
public int totalInteracoes() {
return historico.size() / 2;
}
public static void main(String[] args) {
Capitulo10Chatbot bot = new Capitulo10Chatbot("TutorJavaBot");
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("Digite ajuda para ver os comandos.");
while (true) {
System.out.print("Você: ");
String entrada = scanner.nextLine();
if (normalizar(entrada).equals("sair")) {
break;
}
System.out.println("Bot: " + bot.responder(entrada));
}
}
System.out.println("Interações registradas: " + bot.totalInteracoes());
System.out.println("Bot: Até logo!");
}
}11.4 Separação de responsabilidades
A classe ainda contém a interface de console e as regras, mas a fronteira já está visível:
main: lê e escreve no terminal;normalizar: padroniza comandos;responder: aplica regras;historico: representa o estado da conversa.
Na segunda parte do livro, essas responsabilidades serão distribuídas entre classes e contratos menores.
11.5 Evolução do projeto: versão 10
Esta versão conclui a trilha de fundamentos. O programa compila, executa até sair, orienta entradas inválidas e mantém histórico com significado definido.
O exemplo completo está em examples/src/Capitulo10Chatbot.java.
11.6 Roteiro de teste manual
| Cenário | Sequência | Resultado |
|---|---|---|
| fluxo normal | oi, dica, sair |
duas interações |
| comando desconhecido | xyz |
orientação para ajuda |
| entrada vazia | Enter | mensagem de correção, sem registro |
| histórico | oi, historico |
duas linhas da interação anterior |
| caixa e espaços | AJUDA |
lista de comandos |
11.7 Prática verificável
- Mostre somente as seis últimas linhas do histórico.
- Acrescente o comando
sobre. - Salve o histórico ao encerrar.
- Evite duplicar a lista de comandos em diferentes métodos.
Guarde esta versão funcionando. Os próximos capítulos mudarão a estrutura interna sem alterar o contrato observado pela pessoa usuária.