Livro-caixa Bancário
Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 57 de 57.
Desafio
DifícilConstrua um pequeno banco. Account é uma classe com id, owner e private(set) var balance, além dos métodos deposit(_:) e withdraw(_:), que lançam BankError.invalidAmount (abaixo de 1) e BankError.insufficient(id:). Checking permite um saque a descoberto de 100 (o saldo pode chegar a -100); Savings recusa saques que tornariam o saldo negativo, adiciona juros de 1% (arredondados para baixo) em monthEnd() e permite no máximo 2 saques por mês (BankError.limit(id:)), com a contagem redefinida por monthEnd(). Account.monthEnd() não faz nada. A classe Bank armazena as contas por id e possui transfer(from:to:amount:), que faz o saque e o depósito ou não faz nada em caso de falha.
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, exibe ok ou o erro (invalid amount, insufficient funds in 2, withdrawal limit on 2, no account 9) e, por fim, exibe cada conta ordenada por id, como 1 ada checking: -20.
Seu código deve ficar em BankError.swift, Account.swift, Checking.swift, Savings.swift e Bank.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
// Código de entrada/saída fornecido: mantenha-o como está
var input: [String] = []
while let line = readLine() { input.append(line) }
let bank = Bank()
for cmd in input {
let p = cmd.split(separator: " ").map(String.init)
do {
switch p[0] {
case "open":
let id = Int(p[2])!
bank.accounts[id] = p[1] == "savings" ? Savings(id: id, owner: p[3]) : Checking(id: id, owner: p[3])
case "dep": try bank.account(Int(p[1])!).deposit(Int(p[2])!)
case "wd": try bank.account(Int(p[1])!).withdraw(Int(p[2])!)
case "tr": try bank.transfer(from: Int(p[1])!, to: Int(p[2])!, amount: Int(p[3])!)
default: bank.accounts.values.forEach { $0.monthEnd() }
}
print("ok")
} catch BankError.invalidAmount {
print("invalid amount")
} catch BankError.insufficient(let id) {
print("insufficient funds in \(id)")
} catch BankError.limit(let id) {
print("withdrawal limit on \(id)")
} catch BankError.noAccount(let id) {
print("no account \(id)")
} catch {
print("error")
}
}
for id in bank.accounts.keys.sorted() {
let a = bank.accounts[id]!
print("\(a.id) \(a.owner) \(a.kind): \(a.balance)")
}
Todas as lições de Programação Orientada a Objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesMétodos e selfInicializadoresClasses são ReferênciasRevisão - Cartão da Biblioteca4Encapsulamento
Controle de AcessoSomente Leitura ExternaProtegendo o EstadoInicializadores que Podem FalharRevisão - Conta Bancária7Polimorfismo e Genéricos
PolimorfismoConversão de TiposFunções GenéricasTipos GenéricosRevisão - Calculadora de Formas2Structs e Tipos de Valor
StructsSemântica de ValorMétodos MutáveisStruct ou ClasseRecapitulação - Item de Inventário5Herança
SubclassesSobrescrita de métodosInicializadores e superfinal e hierarquiasRecapitulação - Hierarquia de funcionários8Protocolos Padrão
CustomStringConvertibleEquatableComparableHashableRecapitulação - Ordenação Personalizada11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Playground de Swift