Libro mayor bancario
Parte de la sección Programación orientada a objetos del Journey de Swift de Coddy. Lección 57 de 57.
Desafío
DifícilConstruye un banco pequeño. Account es una clase con id, owner y un private(set) var balance, además de los métodos deposit(_:) y withdraw(_:), que generan BankError.invalidAmount (por debajo de 1) y BankError.insufficient(id:). Checking permite un descubierto de 100 (el saldo puede bajar hasta -100); Savings rechaza los retiros que harían que el saldo fuera negativo, añade un interés del 1 % (redondeado hacia abajo) en monthEnd() y permite como máximo 2 retiros por mes (BankError.limit(id:)), restablecidos por monthEnd(). Account.monthEnd() no hace nada. La clase Bank almacena las cuentas por id y tiene transfer(from:to:amount:), que retira y deposita, o no hace nada si falla.
El código proporcionado lee los comandos open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 o month, imprime ok o el error (invalid amount, insufficient funds in 2, withdrawal limit on 2, no account 9) y, finalmente, imprime cada cuenta ordenada por id como 1 ada checking: -20.
Tu código va en BankError.swift, Account.swift, Checking.swift, Savings.swift y Bank.swift. main.swift contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
// Código de entrada/salida suministrado: déjalo 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 las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesMétodos y selfInicializadoresLas clases son referenciasRepaso: tarjeta de biblioteca4Encapsulación
Control de accesoSolo lectura desde fueraProtección del estadoInicializadores que pueden fallarRepaso - Cuenta bancaria7Polimorfismo y genéricos
PolimorfismoConversión de tiposFunciones genéricasTipos genéricosRepaso - Calculadora de formas2Structs y tipos por valor
StructsSemántica de valoresMétodos mutablesStruct o claseRepaso - elemento del inventario5Herencia
SubclasesSobrescritura de métodosInicializadores y superfinal y jerarquíasRepaso: jerarquía de empleados8Protocolos estándar
CustomStringConvertibleEquatableComparableHashableRepaso - Ordenamiento personalizado11Proyecto: Gestión de bibliotecas
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Swift