import java.util.Scanner; import java.util.InputMismatchException; import java.text.NumberFormat; import java.util.Locale; /** * Sistema bancário simples baseado em console (CLI). *
* Esta classe gerencia operações bancárias básicas como extrato, * saque e depósito para contas correntes e poupança simuladas. * Implementa validação de entrada e formatação monetária regional. *
* * @version 2.0 (Modularizada) */ public class Main { // Variáveis globais de autenticação (Constantes) private static final String NUMERO_CONTA_VALIDO = "12345"; private static final String SENHA_CONTA_VALIDA = "123abc"; /** * Ponto de entrada principal da aplicação. * Gerencia o ciclo de vida da sessão do usuário e o menu principal. */ public static void main(String[] args) { Scanner input = new Scanner(System.in); // Dados do Cliente String nomeCliente = "Lúcio Pereira da Costa"; String cpfCliente = "123-456-7890"; // Saldos (Estado da aplicação) double ccCliente = 22522.94; double cpCliente = 24888.25; System.out.println("=== Bem-Vindo ao Banco JAVA! ==="); System.out.print("Deseja realizar uma operação? (S/N): "); String resposta = input.next(); if (!resposta.equalsIgnoreCase("s")) { System.out.println("Operação cancelada. Até logo!"); input.close(); return; } // Tenta realizar o login. Se falhar, encerra o programa. if (!realizarLogin(input)) { System.out.println("❌ DADOS INVÁLIDOS! ACESSO NEGADO!"); input.close(); return; } // Loop do Menu Principal int operacao = 0; do { limparTela(); exibirMenuPrincipal(nomeCliente); operacao = lerOpcao(input); limparTela(); // Limpa para mostrar o resultado da operação switch (operacao) { case 1: // Extrato exibirExtrato(nomeCliente, cpfCliente, ccCliente, cpCliente); break; case 2: // Retirada (Saque) // A lógica escolhe qual saldo afetar e atualiza a variável if (escolherTipoConta(input) == 1) { ccCliente = processarSaque(input, ccCliente, "Conta Corrente"); } else { cpCliente = processarSaque(input, cpCliente, "Conta Poupança"); } break; case 3: // Depósito // A lógica escolhe qual saldo afetar e atualiza a variável if (escolherTipoConta(input) == 1) { ccCliente = processarDeposito(input, ccCliente, "Conta Corrente"); } else { cpCliente = processarDeposito(input, cpCliente, "Conta Poupança"); } break; case 0: System.out.println("Encerrando a sessão... Obrigado por usar o Banco JAVA!"); break; default: System.out.println("❌ Opção inválida! Tente novamente."); } if (operacao != 0) pausa(input); } while (operacao != 0); input.close(); } // ======================================================================== // MÉTODOS DE LÓGICA DE NEGÓCIO (Saque, Depósito, Login) // ======================================================================== /** * Realiza o processo de autenticação do usuário. * * @param sc Scanner para leitura dos dados. * @return true se as credenciais estiverem corretas, false caso contrário. */ public static boolean realizarLogin(Scanner sc) { System.out.print("Informe sua conta: "); String contaInput = sc.next(); System.out.print("Informe sua senha: "); String senhaInput = sc.next(); if (contaInput.equals(NUMERO_CONTA_VALIDO) && senhaInput.equals(SENHA_CONTA_VALIDA)) { System.out.println("\n✅ Acesso Permitido!"); try { Thread.sleep(2000); } catch (InterruptedException e) {} return true; } return false; } /** * Processa uma operação de saque. * Verifica se há saldo suficiente antes de deduzir o valor. * * @param sc Scanner para entrada de dados. * @param saldoAtual O saldo disponível na conta selecionada. * @param nomeConta O nome da conta (para exibição no log). * @return O novo saldo (atualizado se sucesso, ou o mesmo se falha). */ public static double processarSaque(Scanner sc, double saldoAtual, String nomeConta) { System.out.println("--- RETIRADA: " + nomeConta.toUpperCase() + " ---"); System.out.print("Informe o valor do saque: "); double valor = lerValorMonetario(sc); if (valor <= saldoAtual) { saldoAtual -= valor; System.out.printf("✅ Saque realizado! Novo saldo %s: %s\n", nomeConta, formatarReais(saldoAtual)); return saldoAtual; } else { System.out.println("❌ Saldo insuficiente na " + nomeConta + "."); return saldoAtual; // Retorna o saldo sem alterações } } /** * Processa uma operação de depósito. * * @param sc Scanner para entrada de dados. * @param saldoAtual O saldo atual da conta. * @param nomeConta O nome da conta para exibição. * @return O novo saldo acrescido do depósito. */ public static double processarDeposito(Scanner sc, double saldoAtual, String nomeConta) { System.out.println("--- DEPÓSITO: " + nomeConta.toUpperCase() + " ---"); System.out.print("Informe o valor do depósito: "); double valor = lerValorMonetario(sc); saldoAtual += valor; System.out.printf("✅ Depósito realizado! Novo saldo %s: %s\n", nomeConta, formatarReais(saldoAtual)); return saldoAtual; } // ======================================================================== // MÉTODOS DE INTERFACE E UTILITÁRIOS // ======================================================================== /** * Exibe o menu principal com as opções disponíveis. * @param nome Nome do cliente para personalização. */ public static void exibirMenuPrincipal(String nome) { System.out.println("================================="); System.out.println(" MENU PRINCIPAL "); System.out.println("================================="); System.out.printf("Cliente: %s\n", nome); System.out.println("---------------------------------"); System.out.println("1 - Extrato"); System.out.println("2 - Retirada (Saque)"); System.out.println("3 - Depósito"); System.out.println("0 - Sair/Encerrar"); System.out.println("---------------------------------"); System.out.print("Escolha uma operação: "); } /** * Exibe um submenu para o usuário escolher entre Conta Corrente ou Poupança. * @param sc Scanner para leitura. * @return 1 para Conta Corrente, 2 para Conta Poupança (ou repete se inválido). */ public static int escolherTipoConta(Scanner sc) { System.out.println("1 - Conta Corrente"); System.out.println("2 - Conta Poupança"); System.out.print("Escolha a conta: "); int opcao; while (true) { opcao = lerOpcao(sc); if (opcao == 1 || opcao == 2) { return opcao; } System.out.print("❌ Opção inválida. Escolha 1 ou 2: "); } } /** * Imprime o extrato bancário consolidado. */ public static void exibirExtrato(String nome, String cpf, double cc, double cp) { System.out.println("---------------------------------"); System.out.println(" EXTRATO BANCÁRIO "); System.out.println("---------------------------------"); System.out.printf("Cliente: %s\nCPF: %s\n", nome, cpf); System.out.println("---------------------------------"); System.out.println("Conta-Corrente: " + formatarReais(cc)); System.out.println("Conta-Poupança: " + formatarReais(cp)); System.out.println("TOTAL: " + formatarReais(cc + cp)); System.out.println("---------------------------------"); } /** * Formata um valor double para o padrão monetário brasileiro (R$). * Ex: 1200.50 -> R$ 1.200,50 */ public static String formatarReais(double valor) { Locale localeBR = new Locale("pt", "BR"); NumberFormat dinheiro = NumberFormat.getCurrencyInstance(localeBR); return dinheiro.format(valor); } /** * Lê um número inteiro do usuário com tratamento de erro (InputMismatchException). * Garante que o programa não trave se o usuário digitar letras. */ public static int lerOpcao(Scanner sc) { while (true) { try { return sc.nextInt(); } catch (InputMismatchException e) { System.out.print("Erro: Digite apenas números inteiros. Tente novamente: "); sc.next(); // Limpa o buffer } } } /** * Lê um valor monetário (double) garantindo que seja positivo e numérico. */ public static double lerValorMonetario(Scanner sc) { while (true) { try { double valor = sc.nextDouble(); if (valor < 0) { System.out.print("Erro: O valor não pode ser negativo. Informe novamente: "); } else { return valor; } } catch (InputMismatchException e) { System.out.print("Erro: Digite um valor válido (ex: 500,00): "); sc.next(); // Limpa o buffer } } } public static void pausa(Scanner sc) { System.out.println("\nPressione ENTER para voltar ao menu..."); sc.nextLine(); // Limpa buffer sc.nextLine(); // Espera enter } public static void limparTela() { for (int i = 0; i < 50; i++) System.out.println(); } }