본문으로 바로가기

간단한 은행 계좌 관리 프로그램

category Java/Java 2020. 8. 30. 12:05
/*
 * @author : Charlie Lee
 * @date   : 2020-08-31
 * @email  : find1086@gmail.com
 * @conf   : openJDK 11.0.2
 *
 * @comment: simple national bank account management program.
 *           UUID.randomUUID() logically equals account number in this program.
 * @to-do  : save data to RDB or some place.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

enum BankList {
    AMERICA, INDIA, SINGAPORE, CHINA, KOREA
}

public class BankService {
    private final static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private final static Map<String, List<Account>> map = new HashMap<>();
    private final static List<User> users = new ArrayList<>();
    private static final BankService bankService = getInstance();
    private BankService() {}
    public static BankService getInstance() {
        if(bankService == null) return new BankService();
        return bankService;
    }

    private static Long accountId = 0L;

    public static void main(String[] args) throws IOException {
        runBankService();
    }

    public static void runBankService() throws IOException {
        createUsers();
        createAccounts();
        printInformation();
        manageAccount();
    }

    private static void createUsers() throws IOException {
        System.out.print("how many user you want to create? : ");
        int n = parseToInt(br.readLine());
        for (int i = 0; i < n; i++) {
            createUser();
        }
    }

    private static void createAccounts() throws IOException {
        System.out.print("how many account you want to create? : ");
        int m = parseToInt(br.readLine());
        for (User user : users) {
            for (int j = 0; j < m; j++) {
                createAccount(user);
            }
            System.out.println("complete creating account.");
        }
    }

    private static void createUser() throws IOException {
        System.out.print("type username to create: ");
        String username = br.readLine();
        users.add(new User(username));
    }

    private static void createAccount(User user) throws IOException {
        System.out.println("Which bank account would you like to create?");
        printBanksList();
        chooseBankName(user);
    }

    private static void printBanksList() {
        System.out.print("[ ");
        String banks = Arrays.stream(BankList.values())
                             .map(String::valueOf)
                             .collect(Collectors.joining(", "));
        System.out.print(banks);
        System.out.println(" ]");
    }

    private static void chooseBankName(User user) throws IOException {
        System.out.print("choose bankname you want to create: ");
        String src = (br.readLine()).toUpperCase();
        boolean isValidBankName = checkValidBankName(src);
        if (isValidBankName) {
            Account account = new Account(++accountId, src, String.valueOf(UUID.randomUUID()));
            checkDuplicateAccount(user, account);
            user.addAccount(account);
            map.put(user.getUsername(), user.getAccountList());
        } else {
            throw new Error("sorry. could not find bank in the list. please try later.");
        }
    }

    private static boolean checkValidBankName(String src) {
        for (BankList bank : BankList.values()) {
            if (src.equals(bank.toString())) return true;
        }
        return false;
    }

    private static void checkDuplicateAccount(User user, Account account) {
        if (map.isEmpty()) return;
        if (map.get(user.getUsername()) == null || map.get(user.getUsername()).size() <= 0) return;
        boolean check = findDuplicatedAccount(user, account);
        if (check) throw new Error("this account already exists. please check right account registration.");
    }

    private static boolean findDuplicatedAccount(User user, Account account) {
       return map.get(user.getUsername())
                 .stream()
                 .anyMatch(acc -> acc.equals(account));
    }

    private static void printInformation() {
        Set<String> key = map.keySet();
        for (User u : users) {
            for (Iterator<String> iterator = key.iterator(); iterator.hasNext(); ) {
                System.out.println("username: " + iterator.next() + ", account: " + map.get(u.getUsername()));
            }
        }
    }

    private static boolean validateRegisteredUser(String name) {
        if (!map.containsKey(name)) {
            System.out.println("this user seems not registered yet. check your query right please.");
            return false;
        }
        return true;
    }

    private static void manageAccount() throws IOException {
        boolean flag = true;
        while (flag) {
            String name = chooseUserAccount();
            List<Account> accountsOfanUser = map.get(name);
            printUserAccount(accountsOfanUser);
            // 4-1. specify which account state change.
            Account account = chooseOneAccount(accountsOfanUser);
            controlAccount(account);
            flag = continueToManage();
        }
    }

    private static boolean continueToManage() throws IOException {
        System.out.println("would you like to continue to manage account? (y/n)");
        String value = br.readLine();
        if (value.equals("n")) {
            System.out.println("okay. program will be shut down.");
            return false;
        }
        return true;
    }

    private static Account chooseOneAccount(List<Account> accountsOfanUser) throws IOException {
        System.out.println("which account's balance do you want to change?");
        System.out.print("please choose number in [], not account id : ");
        int accountId = parseToInt(br.readLine()) - 1;
        return accountsOfanUser.get(accountId);
    }

    private static void printUserAccount(List<Account> accountsOfanUser) {
        System.out.println("The user has : ");
        for (int i = 1; i <= accountsOfanUser.size(); i++) {
            System.out.println("[" + i + "] " + accountsOfanUser.get(i - 1));
        }
    }

    private static String chooseUserAccount() throws IOException {
        String name;
        do {
            System.out.println("::: user account list :::");
            Set<String> key = map.keySet();
            for (String o : key) {
                System.out.print(o + " ");
            }
            System.out.println("\nwhich users account do you want manage? : ");
            name = br.readLine();
        } while (!validateRegisteredUser(name));
        return name;
    }

    private static void controlAccount(Account account) throws IOException {
        boolean changeMoneyProcess = true;
        int chooseNum;
        while (changeMoneyProcess) {
            System.out.println("what would you want to do? choose number please.");
            System.out.println("[1] deposit [2] withdraw [3] show money balance");
            chooseNum = parseToInt(br.readLine());
            switch (chooseNum) {
                case 1: {
                    System.out.println("how much money do you want to deposit ?");
                    account.depositMoney(parseToDouble(br.readLine()));
                    break;
                }
                case 2: {
                    System.out.println("how much money do you want to withdraw ?");
                    account.withdrawMoney(parseToDouble(br.readLine()));
                    break;
                }
                case 3:
                    break;
                default:
                    System.out.println("not service this number yet.");
            }
            System.out.printf("money balance : %5.2f\n", account.getMoney());
            changeMoneyProcess = wantToContinueChangeMoney();
        }
    }

    private static Integer parseToInt(String text) throws IOException {
        boolean isAbleToParseInt = false;
        int parsedInt = 0;
        while (!isAbleToParseInt) {
            try {
                parsedInt = Integer.parseInt(text);
                isAbleToParseInt = true;
            } catch (NumberFormatException nfe) {
                System.out.println("it seems not number! please check again.");
                System.out.print("how many user you want to create? : ");
                text = br.readLine();
            }
        }
        return parsedInt;
    }

    private static Double parseToDouble(String text) throws IOException {
        boolean isAbleToParseDouble = false;
        double parsedDouble = 0;
        while (!isAbleToParseDouble) {
            try {
                parsedDouble = Double.parseDouble(text);
                isAbleToParseDouble = true;
            } catch (NumberFormatException nfe) {
                System.out.println("it seems not number! please check again.");
                System.out.print("how many user you want to create? : ");
                text = br.readLine();
            }
        }
        return parsedDouble;
    }

    private static boolean wantToContinueChangeMoney() throws IOException {
        System.out.println("would you want to continue changing money balance ? (y/n)");
        return !(br.readLine()).equals("n");
    }
}

class User {
    private final String username;
    private final List<Account> accountList;

    public User(String username) {
        this.username = username;
        accountList = new ArrayList<>();
    }

    public String getUsername() {
        return username;
    }

    public void addAccount(Account account) {
        accountList.add(account);
    }

    public List<Account> getAccountList() {
        return accountList;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", accountList=" + accountList +
                '}';
    }
}

class Account {
    private final Long id;
    private final String bankName;
    private final String accountNumber;
    private double money;

    public Account(Long id, String bankName, String accountNumber) {
        this.id = id;
        this.bankName = bankName;
        this.accountNumber = accountNumber;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Account)) return false;
        Account account = (Account) o;
        return Objects.equals(id, account.id) &&
                Objects.equals(bankName, account.bankName) &&
                Objects.equals(accountNumber, account.accountNumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, bankName, accountNumber);
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", bankName='" + bankName + '\'' +
                ", accountNumber='" + accountNumber + '\'' +
                '}';
    }

    public double getMoney() {
        return money;
    }

    public void depositMoney(double money) {
        this.money += money;
    }

    public void withdrawMoney(double money) {
        if ((this.money -= money) < 0) {
            throw new Error("you can't withdraw that money.");
        }
        this.money -= money;
    }
}

//  http://colorscripter.com/s/YX09IfQ

'Java > Java' 카테고리의 다른 글

java 슈퍼 타입 토큰을 활용한 map 및 list 구현  (1) 2021.07.29
은행 계좌 관리 프로그램 ver 1.1  (0) 2020.09.03
Java enum 활용법  (0) 2020.07.29