Създайте конзолно приложение, което имитира функционалността на банкомат, позволяващ на потребителите да извършват различни банкови операции.
Целта на задачата е да се създаде приложение, което имитира основните функционалности на реален банкомат. Това включва възможността за проверка на баланс, депозитиране, теглене на средства, както и валидиране на потребителски данни.
-
Създайте клас
Account, който представлява банкова сметка- Той трябва да има следните полета:
balance: текущия баланс на сметката.pin: PIN кодът на сметката.accountNumber: номер на сметката.
- Трябва да има методи за:
getBalance(): връща текущия баланс на сметката.deposit(amount): депозира суматаamountв сметката.withdraw(amount): тегли суматаamountот сметката.checkPin(pin): проверява далиpinсъвпада с PIN кода на сметката.
- Трябва да има конструктор, който инициализира всички полета на класа.
- Той трябва да има следните полета:
-
Създайте енумерация
Commandsсъс следните стойности:WELCOME: съобщение за добре дошли.ASK_ACCOUNT_NUMBER: съобщение за въвеждане на номер на сметка.ACCOUNT_NUMBER: номер на сметка.ASK_PIN: съобщение за въвеждане на PIN код.PIN: PIN код.WITHDRAW: съобщение за теглене на средства.DEPOSIT: съобщение за депозиране на средства.GET_BALANCE: съобщение за проверка на баланса.ERROR: съобщение за грешка.EXIT: съобщение за изход от приложението.
-
Създайте енумерация
Dataсъс следните стойности:ACCOUNT_NUMBER: съобщение за въвеждане на номер на сметка.ACCOUNT: Сметка на потребителя.
-
Създайте енумерация
Statusсъс следните стойности:OK: съобщение за успешна транзакция.ERROR: съобщение за неуспешна транзакция.
-
Създайте клас
ServerThread, който наследяваRunnableи представлява сървър за банкомат.- Той трябва да има следните полета:
accounts: списък с всички сметки.sessionData: данни за текущата сесия, представлява HashMap с ключове от типDataи стойности от типObject.socket: сокет за връзка с клиента.reader:Scannerчетец на вход от клиента.writer:PrintStreamписател на изход към клиента.
- Трябва да има конструктор, който получава сокет и го инициализира, инициализира списъка с всички аканти и инициализира
sessionData. - Трябва да има метод
run(), който се изпълнява при стартиране на нишката.- Той трябва да изпълнява следните стъпки:
- Инициализира
readerиwriterсъс съответните потоци от сокета. - Изпълнява метода
ServerLogic(). - Затваря сокета.
- Инициализира
- Той трябва да изпълнява следните стъпки:
- Трябва да има следните методи:
SendMessage- изпраща съобщение към клиента. Приема един аргумент от типCommandsи съобщение от типString. Съобщението трябва да е командата, последвана от съобщението, разделени със:.SendStatus- изпраща съобщение за статус към клиента. Приема един аргумент от типCommandsи статус от типStatus. Съобщението трябва да е командата, последван от статуса, разделени със:.GetMessage- Служи за обработка на вход от клиента. Чака вход от клиента, разделя го на команда и съобщение и принтира командата и съобщението, след което извиква метод за обработка на командата.ProcessMessage- Служи за обработка на команди от клиента. Приема един аргумент от типCommandsи съобщение от типString. Използваswitchконструкция за да извика съответния метод за обработка на командата.ServerLogic- Входяща точка която еднократно изпраща съобщение за добре дошли и след това извикваGetMessage. Тук добавяме и последователност от стъпки за тестване на цялата функционалност на приложението.
- Той трябва да има следните полета:
-
Създайте клас
Serverс методmain(), който създава сървър за банкомат и го стартира.- Сървърът трябва да слуша на порт 8080.
- Създаваме нов ExecutorService с 3 нишки и изпълняваме сървъра в него. Това ни позволява да обработваме 3 клиента едновременно. При нужда можем да увеличим броя на нишките.
ExecutorService executor = Executors.newFixedThreadPool(3); - В безкраен цикъл приемаме нови клиенти и стартираме нова нишка за всяка една от тях.
executor.execute(new ServerThread(socket));
-
Създайте клас
Clientс методmain(), който създава клиент за банкомат и го стартира.- Той трябва да има следните полета:
socket: сокет за връзка със сървъра.reader:Scannerчетец на вход от сървъра.writer:PrintStreamписател на изход към сървъра.scanner:Scannerчетец на вход от конзолата.
mainметода трябва да изпълнява следните стъпки:- Инициализира
socketсъс сървъра на порт 8080 и IP адрес127.0.0.1. - Инициализира
readerиwriterсъс съответните потоци от сокета. - Инициализира
scannerсъс стандартния вход. - Изпълнява метода
RunLogic(). - Затваря сокета.
- Инициализира
- Трябва да има следните методи:
PerformAction- Служи за обработка на командите от сървъра. Получава като аргумент цял ред от типStringи го разделя на команда и съобщение,:. Използваswitchконструкция за да извика съответния метод за обработка на командата.SendMessage- изпраща съобщение към сървъра. Приема един аргумент от типCommandsи съобщение от типString. Съобщението трябва да е командата, последвана от съобщението, разделени със:.SendStatus- изпраща съобщение за статус към сървъра. Приема един аргумент от типCommandsи статус от типStatus. Съобщението трябва да е командата, последван от статуса, разделени със:.RunLogic- Входяща точка която в безкраен цикъл чака за входящо съобщение от сървъра и го обработва, чрез извикване наPerformAction.
- Той трябва да има следните полета:
- Вход и Изход: Използването на
Scannerкласа в Java за четене на вход от конзолата и PrintStream за извеждане на съобщения. - Обработка на Изключения: Проверка за валидност на въведените данни и обработка на потенциални грешки.
