Банковская книга
Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 57 из 57.
Задание
СложноСоздайте небольшой банк. Account — это класс с id, owner и private(set) var balance, а также с методами deposit(_:) и withdraw(_:), которые выбрасывают BankError.invalidAmount (если сумма меньше 1) и BankError.insufficient(id:). Checking разрешает овердрафт в размере 100 (баланс может опускаться до -100); Savings отклоняет снятия, которые сделали бы баланс отрицательным, начисляет 1% годовых (с округлением вниз) в monthEnd() и разрешает не более 2 снятий в месяц (BankError.limit(id:)), а счётчик сбрасывается методом monthEnd(). Account.monthEnd() ничего не делает. Класс Bank хранит счета по идентификаторам и имеет метод transfer(from:to:amount:), который списывает средства и зачисляет их либо при ошибке ничего не делает.
Предоставленный код считывает команды open checking 1 ada, open savings 2 bo, dep 1 100, wd 2 30, tr 1 2 50 или month, выводит ok или сообщение об ошибке (invalid amount, insufficient funds in 2, withdrawal limit on 2, no account 9), а затем выводит каждый счёт, отсортированный по идентификатору, в формате 1 ada checking: -20.
Ваш код должен находиться в файлах BankError.swift, Account.swift, Checking.swift, Savings.swift и Bank.swift. В main.swift находится предоставленный код ввода и вывода, и его нельзя редактировать.
Попробуйте сами
// Предоставленный код ввода/вывода: оставьте его как есть
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)")
}
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовМетоды и selfИнициализаторыКлассы — это ссылкиПовторение — читательский билет4Инкапсуляция
Контроль доступаТолько чтение извнеЗащита состоянияИнициализаторы с возможностью сбояПовторение — банковский счёт7Полиморфизм и обобщения
ПолиморфизмПриведение типовОбобщённые функцииОбобщённые типыПовторение — калькулятор фигур10Паттерны проектирования. Часть 2
Паттерн делегированияПаттерн декораторПаттерн строительПаттерн состояния2Структуры и типы-значения
СтруктурыСемантика значенийИзменяющие методыСтруктура или классПовторение — элемент инвентаря5Наследование
ПодклассыПереопределение методовИнициализаторы и superfinal и иерархииПовторение — иерархия сотрудников8Стандартные протоколы
CustomStringConvertibleEquatableComparableHashableПовторение — пользовательская сортировка11Проект: Управление библиотекой
Книги и читателиВыдача книгПотренируйтесь самостоятельно: Песочница Swift