Menu
Coddy logo textTech

Livro-razão Bancário

Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 57 de 57.

challenge icon

Desafio

Difícil

Construa um banco pequeno.

  • BankError(message) é uma classe selada que estende Exception, com as subclasses InvalidAmount (invalid amount), Insufficient(id) (insufficient funds in 2), WithdrawalLimit(id) (withdrawal limit on 2) e NoAccount(id) (no account 9).
  • Account(id, owner) é abstrata. Seu balance pode ser lido em qualquer lugar e alterado apenas pelas classes de conta. deposit(amount) e withdraw(amount) lançam InvalidAmount para valores menores que 1, e withdraw lança Insufficient quando o saldo ficaria abaixo de lowestBalance da conta. Ela declara o kind abstrato e um monthEnd() aberto que não faz nada.
  • Checking permite um cheque especial de até -100. Savings nunca fica abaixo de 0, permite no máximo 2 saques por mês (WithdrawalLimit) e, em monthEnd(), adiciona juros de 1% (arredondados para baixo) e redefine a contagem de saques.
  • Bank tem open(kind, id, owner), account(id) (lança NoAccount), transfer(from, to, amount), que busca primeiro as duas contas e depois faz o saque e o depósito, monthEnd() para cada conta e accounts() ordenado por id.

O código fornecido lê os comandos open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 ou month, imprime ok ou a mensagem do erro e, por fim, cada conta como 1 ada checking: -20.

Seu código deve ficar em BankError.kt, InvalidAmount.kt, Insufficient.kt, WithdrawalLimit.kt, NoAccount.kt, Account.kt, Checking.kt, Savings.kt e Bank.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

fun main() {
    // Código de entrada/saída fornecido: mantenha-o como está
    val input = generateSequence(::readLine).toList()
    val bank = Bank()
    for (cmd in input) {
        val p = cmd.split(" ")
        try {
            when (p[0]) {
                "open" -> bank.open(p[1], p[2].toInt(), p[3])
                "dep" -> bank.account(p[1].toInt()).deposit(p[2].toInt())
                "wd" -> bank.account(p[1].toInt()).withdraw(p[2].toInt())
                "tr" -> bank.transfer(p[1].toInt(), p[2].toInt(), p[3].toInt())
                else -> bank.monthEnd()
            }
            println("ok")
        } catch (e: BankError) {
            println(e.message)
        }
    }
    for (a in bank.accounts()) println("${a.id} ${a.owner} ${a.kind}: ${a.balance}")
}

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Kotlin