Банковская система
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 89 из 91.
Задание
ЛегкоДавайте создадим Banking System, который работает с account, транзакциями и переводами между account. Вы создадите систему с правильной инкапсуляцией для защиты финансовых данных, наследованием для разных типов account и проверкой для обеспечения целостности данных.
Вы распределите код по шести файлам:
Transaction.php: СоздайтеTransactionclass для записи финансовых операций. Используйте продвижение свойств конструктора дляtype(string: "deposit", "withdrawal", или "transfer"),amount(float) иtimestamp(string). Все свойства должны быть public readonly. Добавьте методgetDescription(): string, который возвращает"[type]: $[amount]"(форматируйте amount с 2 знаками после десятичной точки).BankAccount.php: Подключите файл Transaction. Создайте abstractBankAccountclass со следующими элементами:- Продвижение свойств конструктора для
accountNumber(string, public readonly) иholderName(string, public readonly) - Защищённое свойство
$balance, инициализированное значением 0.0 - Приватный array для хранения истории транзакций
getBalance(): float: возвращает текущий balancedeposit(float $amount): string: увеличивает balance, записывает транзакцию и возвращает"Deposited: $[amount]"abstract withdraw(float $amount): string: дочерние class реализуют правила снятия средствaddTransaction(Transaction $t): void: защищённый метод для добавления транзакций в историюgetTransactionCount(): int: возвращает количество транзакций
- Продвижение свойств конструктора для
SavingsAccount.php: Подключите файл BankAccount. СоздайтеSavingsAccountclass, расширяющийBankAccount, со следующими элементами:- Константа class
INTEREST_RATEсо значением 0.02 (2%) withdraw(float $amount): string: если amount exceeds balance, верните"Insufficient funds"; в противном случае вычтите amount, запишите транзакцию и верните"Withdrew: $[amount]"applyInterest(): string: вычисляет проценты от текущего balance, добавляет их как deposit и возвращает"Interest applied: $[interest]"
- Константа class
CheckingAccount.php: Подключите файл BankAccount. СоздайтеCheckingAccountclass, расширяющийBankAccount, со следующими элементами:- Приватное свойство
$overdraftLimit, устанавливаемое через конструктор (добавьте третий параметр со значением по умолчанию 100.0) withdraw(float $amount): string: разрешает снятие средств, если amount doesn превышает balance + лимит овердрафта; при ошибке верните"Insufficient funds (overdraft limit: $[limit])", а при успехе —"Withdrew: $[amount]"getOverdraftLimit(): float: возвращает лимит овердрафта
- Приватное свойство
Bank.php: Подключите оба файла account. СоздайтеBankclass, который управляет account:- Приватный array для хранения account, проиндексированных по номеру account
addAccount(BankAccount $account): void: добавляет accountfindAccount(string $accountNumber): ?BankAccount: возвращает account или nulltransfer(string $fromAccount, string $toAccount, float $amount): string: переводит деньги между account. Верните"Source account not found","Destination account not found"или результат снятия средств, если оно fails. При успехе выполните deposit на destination и верните"Transferred $[amount] from [from] to [to]"
main.php: Подключите файл Bank. Вы получите два входных значения: данные account (JSON) и операции (JSON).Формат JSON для account:
[{"type": "savings", "number": "SAV001", "holder": "Alice", "initial": 1000}, {"type": "checking", "number": "CHK001", "holder": "Bob", "initial": 500, "overdraft": 200}]Формат JSON для операций:
[{"op": "deposit", "account": "SAV001", "amount": 200}, {"op": "withdraw", "account": "CHK001", "amount": 600}, {"op": "transfer", "from": "SAV001", "to": "CHK001", "amount": 300}, {"op": "interest", "account": "SAV001"}, {"op": "balance", "account": "SAV001"}]Создайте bank и все account, выполняя deposit начальных сумм. Обработайте каждую операцию:
"deposit": выведите результатdeposit()"withdraw": выведите результатwithdraw()"transfer": выведите результатtransfer()"interest": выведите результатapplyInterest()(только для account типа savings)"balance": выведите"[holder] balance: $[balance]"(с 2 знаками после десятичной точки)
Выводите каждый результат с новой строки. Форматируйте все денежные суммы с 2 знаками после десятичной точки.
Помните, что переводы должны быть атомарными: если снятие средств fails, deposit выполняться не должен. Защищённое свойство $balance позволяет дочерним class изменять его, скрывая его от внешнего кода, что демонстрирует правильную инкапсуляцию в финансовом контексте.
Попробуйте сами
<?php
require_once 'Bank.php';
// Прочитать ввод
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));
// Разобрать JSON-входы
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);
// TODO: Создать экземпляр Bank
// TODO: Создать счета из данных accounts
// Для каждого account в $accounts:
// - Если type равен "savings", создать SavingsAccount
// - Если type равен "checking", создать CheckingAccount (с overdraft, если указан)
// - Добавить account в bank
// - Внести начальную сумму
// TODO: Обработать каждую operation
// Для каждой operation в $operations:
// - "deposit": Вывести результат deposit()
// - "withdraw": Вывести результат withdraw()
// - "transfer": Вывести результат transfer()
// - "interest": Вывести результат applyInterest() (только для savings)
// - "balance": Вывести "[holder] balance: $[balance]" (2 знака после запятой)
?>Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов2Пространства имён и автозагрузка
Введение в пространства имёнКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerПовторение — структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс и абстрактный классАннотация типов с интерфейсамиПовторение — калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeПовторение — пользовательская коллекция3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищённые свойстваСвойства только для чтения (PHP 8.1)Повторение — менеджер банковского счёта6Полиморфизм
Повторение переопределения методовПолиморфизм через интерфейсыАннотации типов и объединённые типыПозднее статическое связываниеПовторение — обработчик платежей9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования, часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy15Финальные задания
Платформа электронного обученияБанковская системаРазработка игрового персонажаСервис аренды транспортных средствПотренируйтесь самостоятельно: Онлайн-компилятор PHP