diff --git a/README.md b/README.md index ab5f572ca..1472fdb81 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ # Readable Code +고정석인 경우 추가금을 내면 사물함 이용 가능. +선택한 이용권과 사물함 여부에 따른 최종 금액을 계산해준다. +선택한 이용권이 2주권 이상일 경우 10%, 12주권 이상일 경우 15% 할인을 진행한다 \ No newline at end of file diff --git a/src/main/java/cleancode/minesweeper/tobe/MinesweeperGame.java b/src/main/java/cleancode/minesweeper/tobe/MinesweeperGame.java index dd85c3ce0..17bb55b95 100644 --- a/src/main/java/cleancode/minesweeper/tobe/MinesweeperGame.java +++ b/src/main/java/cleancode/minesweeper/tobe/MinesweeperGame.java @@ -5,175 +5,233 @@ public class MinesweeperGame { - private static String[][] board = new String[8][10]; - private static Integer[][] landMineCounts = new Integer[8][10]; - private static boolean[][] landMines = new boolean[8][10]; + public static final int BOARD_ROW_SIZE = 8; + public static final int BOARD_COLUMN_SIZE = 8; + public static final int LAND_MINE_COUNT = 10; + public static final String FLAG_SIGN = "⚑"; + public static final String LAND_MINE_SIGN = "☼"; + + private static final String[][] BOARD = new String[BOARD_ROW_SIZE][BOARD_COLUMN_SIZE]; + private static final Integer[][] NEARBY_LAND_MINE_COUNTS = new Integer[BOARD_ROW_SIZE][BOARD_COLUMN_SIZE]; + private static final boolean[][] LAND_MINES = new boolean[BOARD_ROW_SIZE][BOARD_COLUMN_SIZE]; + + public static final String CLOSED_CELL_SIGN = "□"; + public static final String OPENED_CELL_SIGN = "■"; + + // 얘는 ENUM이야 private static int gameStatus = 0; // 0: 게임 중, 1: 승리, -1: 패배 public static void main(String[] args) { - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println("지뢰찾기 게임 시작!"); - System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + showGameStartComments(); Scanner scanner = new Scanner(System.in); - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 10; j++) { - board[i][j] = "□"; + initializeGame(); + while (true) { + showBoard(); + // 게임이 이기는 건데, 나같으면 메서드로 추출을 하거나 gamestatus == WIN 뭐 이런식으로 + if (doesUserWinTheGame()) { + System.out.println("지뢰를 모두 찾았습니다. GAME CLEAR!"); + break; + } + if (doesUserLoseTheGame()) { + System.out.println("지뢰를 밟았습니다. GAME OVER!"); + break; + } + String cellInput = getCellInputFromUser(scanner); + String userActionInput = getUserActionInputUser(scanner); + + int selectedColIndex = getSelectedColIndex(cellInput); + int selectedRowIndex = getSelectedRowIndex(cellInput); + + if (doesUserChooseToPlantFlag(userActionInput)) { + BOARD[selectedRowIndex][selectedColIndex] = FLAG_SIGN; + checkIfAllCellIsOpened(); + } else if (doesUserChooseToOpenCell(userActionInput)) { + if (LAND_MINES[selectedRowIndex][selectedColIndex]) { + BOARD[selectedRowIndex][selectedColIndex] = LAND_MINE_SIGN; + changeGameStatusToLost(); + continue; // 여기더 early return + } else { + open(selectedRowIndex, selectedColIndex); + } + checkIfAllCellIsOpened(); + } else { + System.out.println("잘못된 번호를 선택하셨습니다."); + } + } + } + + private static void changeGameStatusToLost() { + gameStatus = -1; + } + + private static boolean doesUserChooseToOpenCell(String userActionInput) { + return userActionInput.equals("1"); + } + + private static boolean doesUserChooseToPlantFlag(String userActionInput) { + return userActionInput.equals("2"); + } + + private static int getSelectedRowIndex(String cellInput) { + char cellInputRow = cellInput.charAt(1); + return convertRowFrom(cellInputRow); + } + + private static int getSelectedColIndex(String cellInput) { + char cellInputCol = cellInput.charAt(0); + return convertColFrom(cellInputCol); + } + + private static String getUserActionInputUser(Scanner scanner) { + System.out.println("선택한 셀에 대한 행위를 선택하세요. (1: 오픈, 2: 깃발 꽂기)"); + return scanner.nextLine(); + } + + private static String getCellInputFromUser(Scanner scanner) { + System.out.println(); + System.out.println("선택할 좌표를 입력하세요. (예: a1)"); + return getUserActionInputUser(scanner); + } + + private static boolean doesUserLoseTheGame() { + return gameStatus == -1; + } + + private static boolean doesUserWinTheGame() { + return gameStatus == 1; + } + + private static void checkIfAllCellIsOpened() { + boolean isAllOpened = isAllOpened(); + if (isAllOpened) { + changeGameStatusToWin(); + } + } + + private static void changeGameStatusToWin() { + gameStatus = 1; + } + + private static boolean isAllOpened() { + boolean isAllOpend = true; + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 10; col++) { + if (BOARD[row][col].equals(CLOSED_CELL_SIGN)) { + isAllOpend = false; + } + } + } + return isAllOpend; + } + + private static int convertRowFrom(char cellInputRow) { + return Character.getNumericValue(cellInputRow) - 1; + } + + private static int convertColFrom(char cellInputCol) { + return switch (cellInputCol) { + case 'a' -> +// selectedColIndex = 0; +// break; + 0; + case 'b' -> 1; + case 'c' -> 2; + case 'd' -> 3; + case 'e' -> 4; + case 'f' -> 5; + case 'g' -> 6; + case 'h' -> 7; + case 'i' -> 8; + case 'j' -> 9; + default -> -1; + };// defualt에서 에러를 던져주는 것으로 바꿔줨 + } + + private static void showBoard() { + System.out.println(" a b c d e f g h i j"); + for (int row = 0; row < 8; row++) { + System.out.printf("%d ", row + 1); + for (int col = 0; col < 10; col++) { + System.out.print(BOARD[row][col] + " "); } + System.out.println(); } - for (int i = 0; i < 10; i++) { + } + + private static void initializeGame() { + for (int row = 0; row < BOARD_ROW_SIZE; row++) { + for (int col = 0; col < BOARD_COLUMN_SIZE; col++) { + BOARD[row][col] = CLOSED_CELL_SIGN; + } + } + // for문의 row, col로 변경, 그리고 밑에 메서드명 지뢰심기? + for (int i = 0; i < LAND_MINE_COUNT; i++) { int col = new Random().nextInt(10); int row = new Random().nextInt(8); - landMines[row][col] = true; + LAND_MINES[row][col] = true; } - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 10; j++) { + + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 10; col++) { int count = 0; - if (!landMines[i][j]) { - if (i - 1 >= 0 && j - 1 >= 0 && landMines[i - 1][j - 1]) { + if (!LAND_MINES[row][col]) { + // 내 위치 기준으로 왼쪽 대각선위로 지뢰가 있다면 count 증가 + if (row - 1 >= 0 && col - 1 >= 0 && LAND_MINES[row - 1][col - 1]) { count++; } - if (i - 1 >= 0 && landMines[i - 1][j]) { + if (row - 1 >= 0 && LAND_MINES[row - 1][col]) { count++; } - if (i - 1 >= 0 && j + 1 < 10 && landMines[i - 1][j + 1]) { + if (row - 1 >= 0 && col + 1 < 10 && LAND_MINES[row - 1][col + 1]) { count++; } - if (j - 1 >= 0 && landMines[i][j - 1]) { + if (col - 1 >= 0 && LAND_MINES[row][col - 1]) { count++; } - if (j + 1 < 10 && landMines[i][j + 1]) { + if (col + 1 < 10 && LAND_MINES[row][col + 1]) { count++; } - if (i + 1 < 8 && j - 1 >= 0 && landMines[i + 1][j - 1]) { + if (row + 1 < 8 && col - 1 >= 0 && LAND_MINES[row + 1][col - 1]) { count++; } - if (i + 1 < 8 && landMines[i + 1][j]) { + if (row + 1 < 8 && LAND_MINES[row + 1][col]) { count++; } - if (i + 1 < 8 && j + 1 < 10 && landMines[i + 1][j + 1]) { + if (row + 1 < 8 && col + 1 < 10 && LAND_MINES[row + 1][col + 1]) { count++; } - landMineCounts[i][j] = count; + NEARBY_LAND_MINE_COUNTS[row][col] = count; continue; } - landMineCounts[i][j] = 0; - } - } - while (true) { - System.out.println(" a b c d e f g h i j"); - for (int i = 0; i < 8; i++) { - System.out.printf("%d ", i + 1); - for (int j = 0; j < 10; j++) { - System.out.print(board[i][j] + " "); - } - System.out.println(); - } - if (gameStatus == 1) { - System.out.println("지뢰를 모두 찾았습니다. GAME CLEAR!"); - break; - } - if (gameStatus == -1) { - System.out.println("지뢰를 밟았습니다. GAME OVER!"); - break; - } - System.out.println(); - System.out.println("선택할 좌표를 입력하세요. (예: a1)"); - String input = scanner.nextLine(); - System.out.println("선택한 셀에 대한 행위를 선택하세요. (1: 오픈, 2: 깃발 꽂기)"); - String input2 = scanner.nextLine(); - char c = input.charAt(0); - char r = input.charAt(1); - int col; - switch (c) { - case 'a': - col = 0; - break; - case 'b': - col = 1; - break; - case 'c': - col = 2; - break; - case 'd': - col = 3; - break; - case 'e': - col = 4; - break; - case 'f': - col = 5; - break; - case 'g': - col = 6; - break; - case 'h': - col = 7; - break; - case 'i': - col = 8; - break; - case 'j': - col = 9; - break; - default: - col = -1; - break; - } - int row = Character.getNumericValue(r) - 1; - if (input2.equals("2")) { - board[row][col] = "⚑"; - boolean open = true; - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 10; j++) { - if (board[i][j].equals("□")) { - open = false; - } - } - } - if (open) { - gameStatus = 1; - } - } else if (input2.equals("1")) { - if (landMines[row][col]) { - board[row][col] = "☼"; - gameStatus = -1; - continue; - } else { - open(row, col); - } - boolean open = true; - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 10; j++) { - if (board[i][j].equals("□")) { - open = false; - } - } - } - if (open) { - gameStatus = 1; - } - } else { - System.out.println("잘못된 번호를 선택하셨습니다."); + NEARBY_LAND_MINE_COUNTS[row][col] = 0; } } } + private static void showGameStartComments() { + System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + System.out.println("지뢰찾기 게임 시작!"); + System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + } + private static void open(int row, int col) { if (row < 0 || row >= 8 || col < 0 || col >= 10) { return; } - if (!board[row][col].equals("□")) { + // 여기서도 뭐 메서드로 추출한다거나, 아니면 if문의 조건을 메서드로 추출 + if (!BOARD[row][col].equals(CLOSED_CELL_SIGN)) { return; } - if (landMines[row][col]) { + if (LAND_MINES[row][col]) { return; } - if (landMineCounts[row][col] != 0) { - board[row][col] = String.valueOf(landMineCounts[row][col]); + if (NEARBY_LAND_MINE_COUNTS[row][col] != 0) { + BOARD[row][col] = String.valueOf(NEARBY_LAND_MINE_COUNTS[row][col]); return; } else { - board[row][col] = "■"; + BOARD[row][col] = OPENED_CELL_SIGN; } + // 이것 또한 while문이라던가 for문 혹은 stream으로 재귀호출할 수 있도록 변경 가능하지 않나? open(row - 1, col - 1); open(row - 1, col); open(row - 1, col + 1); diff --git a/src/main/java/cleancode/studycafe/asis/StudyCafePassMachine.java b/src/main/java/cleancode/studycafe/asis/StudyCafePassMachine.java index 1e910a5f2..0f2cf5188 100644 --- a/src/main/java/cleancode/studycafe/asis/StudyCafePassMachine.java +++ b/src/main/java/cleancode/studycafe/asis/StudyCafePassMachine.java @@ -22,10 +22,9 @@ public void run() { outputHandler.askPassTypeSelection(); StudyCafePassType studyCafePassType = inputHandler.getPassTypeSelectingUserAction(); - if (studyCafePassType == StudyCafePassType.HOURLY) { StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler(); - List studyCafePasses = studyCafeFileHandler.readStudyCafePasses(); + List studyCafePasses = studyCafeFileHandler.readStudyCafePasses(); // 모든 정보를 다 끌고옴 List hourlyPasses = studyCafePasses.stream() .filter(studyCafePass -> studyCafePass.getPassType() == StudyCafePassType.HOURLY) .toList(); diff --git a/src/main/java/cleancode/studycafe/asis/exception/AppException.java b/src/main/java/cleancode/studycafe/asis/exception/AppException.java index e4853a647..db57b3417 100644 --- a/src/main/java/cleancode/studycafe/asis/exception/AppException.java +++ b/src/main/java/cleancode/studycafe/asis/exception/AppException.java @@ -1,6 +1,7 @@ package cleancode.studycafe.asis.exception; -public class AppException extends RuntimeException { +public class +AppException extends RuntimeException { public AppException(String message) { super(message); diff --git a/src/main/java/cleancode/studycafe/asis/io/OutputHandler.java b/src/main/java/cleancode/studycafe/asis/io/OutputHandler.java index 7c00b98ba..5b6d152b6 100644 --- a/src/main/java/cleancode/studycafe/asis/io/OutputHandler.java +++ b/src/main/java/cleancode/studycafe/asis/io/OutputHandler.java @@ -4,6 +4,7 @@ import cleancode.studycafe.asis.model.StudyCafePass; import java.util.List; +import java.util.logging.Logger; public class OutputHandler { diff --git a/src/main/java/cleancode/studycafe/asis/model/StudyCafePass.java b/src/main/java/cleancode/studycafe/asis/model/StudyCafePass.java index 76ba12ecf..5d51c8f53 100644 --- a/src/main/java/cleancode/studycafe/asis/model/StudyCafePass.java +++ b/src/main/java/cleancode/studycafe/asis/model/StudyCafePass.java @@ -1,5 +1,6 @@ package cleancode.studycafe.asis.model; + public class StudyCafePass { private final StudyCafePassType passType; @@ -14,6 +15,16 @@ private StudyCafePass(StudyCafePassType passType, int duration, int price, doubl this.discountRate = discountRate; } + @Override + public String toString() { + return "StudyCafePass{" + + "passType=" + passType + + ", duration=" + duration + + ", price=" + price + + ", discountRate=" + discountRate + + '}'; + } + public static StudyCafePass of(StudyCafePassType passType, int duration, int price, double discountRate) { return new StudyCafePass(passType, duration, price, discountRate); } diff --git a/src/main/java/cleancode/studycafe/asis/model/StudyCafePassType.java b/src/main/java/cleancode/studycafe/asis/model/StudyCafePassType.java index 8903a51ab..f23b73b58 100644 --- a/src/main/java/cleancode/studycafe/asis/model/StudyCafePassType.java +++ b/src/main/java/cleancode/studycafe/asis/model/StudyCafePassType.java @@ -8,6 +8,13 @@ public enum StudyCafePassType { private final String description; + @Override + public String toString() { + return "StudyCafePassType{" + + "description='" + description + '\'' + + '}'; + } + StudyCafePassType(String description) { this.description = description; } diff --git a/src/main/java/cleancode/studycafe/tobe/StudyCafeApplication.java b/src/main/java/cleancode/studycafe/tobe/StudyCafeApplication.java deleted file mode 100644 index a60afb3f3..000000000 --- a/src/main/java/cleancode/studycafe/tobe/StudyCafeApplication.java +++ /dev/null @@ -1,10 +0,0 @@ -package cleancode.studycafe.tobe; - -public class StudyCafeApplication { - - public static void main(String[] args) { - StudyCafePassMachine studyCafePassMachine = new StudyCafePassMachine(); - studyCafePassMachine.run(); - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/StudyCafePassMachine.java b/src/main/java/cleancode/studycafe/tobe/StudyCafePassMachine.java deleted file mode 100644 index 3d34d9eef..000000000 --- a/src/main/java/cleancode/studycafe/tobe/StudyCafePassMachine.java +++ /dev/null @@ -1,81 +0,0 @@ -package cleancode.studycafe.tobe; - -import cleancode.studycafe.tobe.exception.AppException; -import cleancode.studycafe.tobe.io.InputHandler; -import cleancode.studycafe.tobe.io.OutputHandler; -import cleancode.studycafe.tobe.io.StudyCafeFileHandler; -import cleancode.studycafe.tobe.model.StudyCafeLockerPass; -import cleancode.studycafe.tobe.model.StudyCafePass; -import cleancode.studycafe.tobe.model.StudyCafePassType; - -import java.util.List; - -public class StudyCafePassMachine { - - private final InputHandler inputHandler = new InputHandler(); - private final OutputHandler outputHandler = new OutputHandler(); - - public void run() { - try { - outputHandler.showWelcomeMessage(); - outputHandler.showAnnouncement(); - - outputHandler.askPassTypeSelection(); - StudyCafePassType studyCafePassType = inputHandler.getPassTypeSelectingUserAction(); - - if (studyCafePassType == StudyCafePassType.HOURLY) { - StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler(); - List studyCafePasses = studyCafeFileHandler.readStudyCafePasses(); - List hourlyPasses = studyCafePasses.stream() - .filter(studyCafePass -> studyCafePass.getPassType() == StudyCafePassType.HOURLY) - .toList(); - outputHandler.showPassListForSelection(hourlyPasses); - StudyCafePass selectedPass = inputHandler.getSelectPass(hourlyPasses); - outputHandler.showPassOrderSummary(selectedPass, null); - } else if (studyCafePassType == StudyCafePassType.WEEKLY) { - StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler(); - List studyCafePasses = studyCafeFileHandler.readStudyCafePasses(); - List weeklyPasses = studyCafePasses.stream() - .filter(studyCafePass -> studyCafePass.getPassType() == StudyCafePassType.WEEKLY) - .toList(); - outputHandler.showPassListForSelection(weeklyPasses); - StudyCafePass selectedPass = inputHandler.getSelectPass(weeklyPasses); - outputHandler.showPassOrderSummary(selectedPass, null); - } else if (studyCafePassType == StudyCafePassType.FIXED) { - StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler(); - List studyCafePasses = studyCafeFileHandler.readStudyCafePasses(); - List fixedPasses = studyCafePasses.stream() - .filter(studyCafePass -> studyCafePass.getPassType() == StudyCafePassType.FIXED) - .toList(); - outputHandler.showPassListForSelection(fixedPasses); - StudyCafePass selectedPass = inputHandler.getSelectPass(fixedPasses); - - List lockerPasses = studyCafeFileHandler.readLockerPasses(); - StudyCafeLockerPass lockerPass = lockerPasses.stream() - .filter(option -> - option.getPassType() == selectedPass.getPassType() - && option.getDuration() == selectedPass.getDuration() - ) - .findFirst() - .orElse(null); - - boolean lockerSelection = false; - if (lockerPass != null) { - outputHandler.askLockerPass(lockerPass); - lockerSelection = inputHandler.getLockerSelection(); - } - - if (lockerSelection) { - outputHandler.showPassOrderSummary(selectedPass, lockerPass); - } else { - outputHandler.showPassOrderSummary(selectedPass, null); - } - } - } catch (AppException e) { - outputHandler.showSimpleMessage(e.getMessage()); - } catch (Exception e) { - outputHandler.showSimpleMessage("알 수 없는 오류가 발생했습니다."); - } - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/exception/AppException.java b/src/main/java/cleancode/studycafe/tobe/exception/AppException.java deleted file mode 100644 index 4920bcba4..000000000 --- a/src/main/java/cleancode/studycafe/tobe/exception/AppException.java +++ /dev/null @@ -1,9 +0,0 @@ -package cleancode.studycafe.tobe.exception; - -public class AppException extends RuntimeException { - - public AppException(String message) { - super(message); - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/io/InputHandler.java b/src/main/java/cleancode/studycafe/tobe/io/InputHandler.java deleted file mode 100644 index 2f1ceb64d..000000000 --- a/src/main/java/cleancode/studycafe/tobe/io/InputHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package cleancode.studycafe.tobe.io; - -import cleancode.studycafe.tobe.exception.AppException; -import cleancode.studycafe.tobe.model.StudyCafePass; -import cleancode.studycafe.tobe.model.StudyCafePassType; - -import java.util.List; -import java.util.Scanner; - -public class InputHandler { - - private static final Scanner SCANNER = new Scanner(System.in); - - public StudyCafePassType getPassTypeSelectingUserAction() { - String userInput = SCANNER.nextLine(); - - if ("1".equals(userInput)) { - return StudyCafePassType.HOURLY; - } - if ("2".equals(userInput)) { - return StudyCafePassType.WEEKLY; - } - if ("3".equals(userInput)) { - return StudyCafePassType.FIXED; - } - throw new AppException("잘못된 입력입니다."); - } - - public StudyCafePass getSelectPass(List passes) { - String userInput = SCANNER.nextLine(); - int selectedIndex = Integer.parseInt(userInput) - 1; - return passes.get(selectedIndex); - } - - public boolean getLockerSelection() { - String userInput = SCANNER.nextLine(); - return "1".equals(userInput); - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/io/OutputHandler.java b/src/main/java/cleancode/studycafe/tobe/io/OutputHandler.java deleted file mode 100644 index d8e0181a4..000000000 --- a/src/main/java/cleancode/studycafe/tobe/io/OutputHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -package cleancode.studycafe.tobe.io; - -import cleancode.studycafe.tobe.model.StudyCafeLockerPass; -import cleancode.studycafe.tobe.model.StudyCafePass; - -import java.util.List; - -public class OutputHandler { - - public void showWelcomeMessage() { - System.out.println("*** 프리미엄 스터디카페 ***"); - } - - public void showAnnouncement() { - System.out.println("* 사물함은 고정석 선택 시 이용 가능합니다. (추가 결제)"); - System.out.println("* !오픈 이벤트! 2주권 이상 결제 시 10% 할인, 12주권 결제 시 15% 할인! (결제 시 적용)"); - System.out.println(); - } - - public void askPassTypeSelection() { - System.out.println("사용하실 이용권을 선택해 주세요."); - System.out.println("1. 시간 이용권(자유석) | 2. 주단위 이용권(자유석) | 3. 1인 고정석"); - } - - public void showPassListForSelection(List passes) { - System.out.println(); - System.out.println("이용권 목록"); - for (int index = 0; index < passes.size(); index++) { - StudyCafePass pass = passes.get(index); - System.out.println(String.format("%s. ", index + 1) + pass.display()); - } - } - - public void askLockerPass(StudyCafeLockerPass lockerPass) { - System.out.println(); - String askMessage = String.format( - "사물함을 이용하시겠습니까? (%s)", - lockerPass.display() - ); - - System.out.println(askMessage); - System.out.println("1. 예 | 2. 아니오"); - } - - public void showPassOrderSummary(StudyCafePass selectedPass, StudyCafeLockerPass lockerPass) { - System.out.println(); - System.out.println("이용 내역"); - System.out.println("이용권: " + selectedPass.display()); - if (lockerPass != null) { - System.out.println("사물함: " + lockerPass.display()); - } - - double discountRate = selectedPass.getDiscountRate(); - int discountPrice = (int) (selectedPass.getPrice() * discountRate); - if (discountPrice > 0) { - System.out.println("이벤트 할인 금액: " + discountPrice + "원"); - } - - int totalPrice = selectedPass.getPrice() - discountPrice + (lockerPass != null ? lockerPass.getPrice() : 0); - System.out.println("총 결제 금액: " + totalPrice + "원"); - System.out.println(); - } - - public void showSimpleMessage(String message) { - System.out.println(message); - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/io/StudyCafeFileHandler.java b/src/main/java/cleancode/studycafe/tobe/io/StudyCafeFileHandler.java deleted file mode 100644 index 920a27e59..000000000 --- a/src/main/java/cleancode/studycafe/tobe/io/StudyCafeFileHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -package cleancode.studycafe.tobe.io; - -import cleancode.studycafe.tobe.model.StudyCafeLockerPass; -import cleancode.studycafe.tobe.model.StudyCafePass; -import cleancode.studycafe.tobe.model.StudyCafePassType; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -public class StudyCafeFileHandler { - - public List readStudyCafePasses() { - try { - List lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/pass-list.csv")); - List studyCafePasses = new ArrayList<>(); - for (String line : lines) { - String[] values = line.split(","); - StudyCafePassType studyCafePassType = StudyCafePassType.valueOf(values[0]); - int duration = Integer.parseInt(values[1]); - int price = Integer.parseInt(values[2]); - double discountRate = Double.parseDouble(values[3]); - - StudyCafePass studyCafePass = StudyCafePass.of(studyCafePassType, duration, price, discountRate); - studyCafePasses.add(studyCafePass); - } - - return studyCafePasses; - } catch (IOException e) { - throw new RuntimeException("파일을 읽는데 실패했습니다.", e); - } - } - - public List readLockerPasses() { - try { - List lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/locker.csv")); - List lockerPasses = new ArrayList<>(); - for (String line : lines) { - String[] values = line.split(","); - StudyCafePassType studyCafePassType = StudyCafePassType.valueOf(values[0]); - int duration = Integer.parseInt(values[1]); - int price = Integer.parseInt(values[2]); - - StudyCafeLockerPass lockerPass = StudyCafeLockerPass.of(studyCafePassType, duration, price); - lockerPasses.add(lockerPass); - } - - return lockerPasses; - } catch (IOException e) { - throw new RuntimeException("파일을 읽는데 실패했습니다.", e); - } - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/model/StudyCafePass.java b/src/main/java/cleancode/studycafe/tobe/model/StudyCafePass.java deleted file mode 100644 index 0749f41b8..000000000 --- a/src/main/java/cleancode/studycafe/tobe/model/StudyCafePass.java +++ /dev/null @@ -1,50 +0,0 @@ -package cleancode.studycafe.tobe.model; - -public class StudyCafePass { - - private final StudyCafePassType passType; - private final int duration; - private final int price; - private final double discountRate; - - private StudyCafePass(StudyCafePassType passType, int duration, int price, double discountRate) { - this.passType = passType; - this.duration = duration; - this.price = price; - this.discountRate = discountRate; - } - - public static StudyCafePass of(StudyCafePassType passType, int duration, int price, double discountRate) { - return new StudyCafePass(passType, duration, price, discountRate); - } - - public StudyCafePassType getPassType() { - return passType; - } - - public int getDuration() { - return duration; - } - - public int getPrice() { - return price; - } - - public double getDiscountRate() { - return discountRate; - } - - public String display() { - if (passType == StudyCafePassType.HOURLY) { - return String.format("%s시간권 - %d원", duration, price); - } - if (passType == StudyCafePassType.WEEKLY) { - return String.format("%s주권 - %d원", duration, price); - } - if (passType == StudyCafePassType.FIXED) { - return String.format("%s주권 - %d원", duration, price); - } - return ""; - } - -} diff --git a/src/main/java/cleancode/studycafe/tobe/model/StudyCafePassType.java b/src/main/java/cleancode/studycafe/tobe/model/StudyCafePassType.java deleted file mode 100644 index bac959b4f..000000000 --- a/src/main/java/cleancode/studycafe/tobe/model/StudyCafePassType.java +++ /dev/null @@ -1,15 +0,0 @@ -package cleancode.studycafe.tobe.model; - -public enum StudyCafePassType { - - HOURLY("시간 단위 이용권"), - WEEKLY("주 단위 이용권"), - FIXED("1인 고정석"); - - private final String description; - - StudyCafePassType(String description) { - this.description = description; - } - -} diff --git a/src/main/java/cleancode/test/asis/StudyCafeApplication.java b/src/main/java/cleancode/test/asis/StudyCafeApplication.java new file mode 100644 index 000000000..8462dd298 --- /dev/null +++ b/src/main/java/cleancode/test/asis/StudyCafeApplication.java @@ -0,0 +1,17 @@ +package cleancode.test.asis; + + +import cleancode.test.asis.io.provider.BasicUsingPassFileReader; +import cleancode.test.asis.io.provider.LockerPassFileReader; + +public class StudyCafeApplication { + + public static void main(String[] args) { + StudyCafePassMachine studyCafePassMachine = + new StudyCafePassMachine( + new BasicUsingPassFileReader(), + new LockerPassFileReader() + ); + studyCafePassMachine.run(); + } +} diff --git a/src/main/java/cleancode/test/asis/StudyCafePassMachine.java b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java new file mode 100644 index 000000000..acc442b53 --- /dev/null +++ b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java @@ -0,0 +1,82 @@ +package cleancode.test.asis; + +import cleancode.test.asis.exception.AppException; +import cleancode.test.asis.io.InputHandler; +import cleancode.test.asis.io.OutputHandler; +import cleancode.test.asis.model.StudyCafeLockerPass; +import cleancode.test.asis.model.StudyCafePassType; +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.service.StudyCafeLockerPassService; +import cleancode.test.asis.service.StudyCafePassService; +import cleancode.test.asis.service.provider.BasicUsingPassProvider; +import cleancode.test.asis.service.provider.LockerPassProvider; + +import java.util.List; +import java.util.Scanner; + +public class StudyCafePassMachine { + + private static final Scanner SCANNER = new Scanner(System.in); + + private final InputHandler inputHandler = new InputHandler(); + private final OutputHandler outputHandler = new OutputHandler(); + + private final BasicUsingPassProvider basicUsingPassProvider; + private final LockerPassProvider lockerPassProvider; + + private final StudyCafePassService passService; + private final StudyCafeLockerPassService lockerPassService; + + public StudyCafePassMachine(BasicUsingPassProvider basicUsingPassProvider, LockerPassProvider lockerPassProvider) { + this.basicUsingPassProvider = basicUsingPassProvider; + this.lockerPassProvider = lockerPassProvider; + passService = new StudyCafePassService(basicUsingPassProvider.getStudyCafeUsingPass()); + lockerPassService = new StudyCafeLockerPassService(lockerPassProvider.getStudyCafeLockerPass()); + } + + public void run() { + try { + + outputHandler.showWelcomeMessage(); + outputHandler.showAnnouncement(); + + StudyCafePassType selectedPassType = selectPassType(); + StudyCafeUsingPass selectedPass = selectPass(selectedPassType); + handleLockerPass(selectedPass); + + } catch (AppException e) { + outputHandler.showSimpleMessage(e.getMessage()); + } catch (Exception e) { + outputHandler.showSimpleMessage("알 수 없는 오류가 발생했습니다."); + } + } + + private StudyCafeUsingPass selectPass(StudyCafePassType passType) { + List passes = passService.getPasses(passType); + outputHandler.showPassListForSelection(passes); + + String userInput = inputHandler.getUserAction(); + return passService.getPass(userInput, passes); + } + + private boolean selectLockerOption(StudyCafeLockerPass lockerPass) { + outputHandler.askLockerPass(lockerPass); + return inputHandler.getLockerSelection(inputHandler.getUserAction()); + } + + private StudyCafePassType selectPassType() { + outputHandler.askPassTypeSelection(); + String userInput = inputHandler.getUserAction(); + return StudyCafePassType.from(userInput); + } + + private void handleLockerPass(StudyCafeUsingPass selectedPass) { + lockerPassService.findLockerPassBy(selectedPass) + .filter(this::selectLockerOption) + .ifPresentOrElse( + lockerPass -> outputHandler.showPassOrderSummary(selectedPass, lockerPass), + () -> outputHandler.showPassOrderSummary(selectedPass) + ); + } +} + diff --git a/src/main/java/cleancode/test/asis/exception/AppException.java b/src/main/java/cleancode/test/asis/exception/AppException.java new file mode 100644 index 000000000..2c93cb921 --- /dev/null +++ b/src/main/java/cleancode/test/asis/exception/AppException.java @@ -0,0 +1,10 @@ +package cleancode.test.asis.exception; + +public class +AppException extends RuntimeException { + + public AppException(String message) { + super(message); + } + +} diff --git a/src/main/java/cleancode/test/asis/io/InputHandler.java b/src/main/java/cleancode/test/asis/io/InputHandler.java new file mode 100644 index 000000000..bda5e7efb --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/InputHandler.java @@ -0,0 +1,17 @@ +package cleancode.test.asis.io; + +import java.util.Scanner; + +public class InputHandler { + + private final Scanner scanner = new Scanner(System.in); + private static final String LOCKER_OPTION = "1"; + + public String getUserAction() { + return scanner.nextLine(); + } + + public boolean getLockerSelection(String input) { + return LOCKER_OPTION.equals(input); + } +} diff --git a/src/main/java/cleancode/test/asis/io/OutputHandler.java b/src/main/java/cleancode/test/asis/io/OutputHandler.java new file mode 100644 index 000000000..4895a3f48 --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/OutputHandler.java @@ -0,0 +1,97 @@ +package cleancode.test.asis.io; + +import cleancode.test.asis.service.StudyCafePass; +import cleancode.test.asis.model.StudyCafeLockerPass; +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.model.StudyCafePassType; + +import java.util.List; + +public class OutputHandler { + + public void showWelcomeMessage() { + System.out.println("*** 프리미엄 스터디카페 ***"); + } + + public void showAnnouncement() { + System.out.println("* 사물함은 고정석 선택 시 이용 가능합니다. (추가 결제)"); + System.out.println("* !오픈 이벤트! 2주권 이상 결제 시 10% 할인, 12주권 결제 시 15% 할인! (결제 시 적용)"); + newLine(); + } + + public void askPassTypeSelection() { + System.out.println("사용하실 이용권을 선택해 주세요."); + System.out.println("1. 시간 이용권(자유석) | 2. 주단위 이용권(자유석) | 3. 1인 고정석"); + } + + public void showPassListForSelection(List passes) { + newLine(); + System.out.println("이용권 목록"); + for (int index = 0; index < passes.size(); index++) { + StudyCafeUsingPass pass = passes.get(index); + System.out.println(String.format("%s. ", index + 1) + display(pass)); + } + } + + public void askLockerPass(StudyCafeLockerPass lockerPass) { + newLine(); + String askMessage = String.format( + "사물함을 이용하시겠습니까? (%s)", + display(lockerPass) + ); + + System.out.println(askMessage); + System.out.println("1. 예 | 2. 아니오"); + } + + public void showPassOrderSummary(StudyCafeUsingPass basicPass) { + showPassOrderSummary(basicPass, null); + } + + public void showPassOrderSummary(StudyCafeUsingPass basicPass, StudyCafeLockerPass lockerPass) { + newLine(); + System.out.println("이용 내역"); + System.out.println("이용권: " + display(basicPass)); + if (lockerPass != null) { + System.out.println("사물함: " + display(lockerPass)); + } + + int discountPrice = basicPass.getDiscountPrice(); + if (isHigherThanZero(discountPrice)) { + System.out.println("이벤트 할인 금액: " + discountPrice + "원"); + } + + int totalPrice = basicPass.getTotalPrice(discountPrice, lockerPass); + System.out.println("총 결제 금액: " + totalPrice + "원"); + newLine(); + } + + private boolean isHigherThanZero(double discountPrice) { + return discountPrice > 0; + } + + public void showSimpleMessage(String message) { + System.out.println(message); + } + + public String display(StudyCafePass selectedPass) { + StudyCafePassType passType = selectedPass.getPassType(); + int duration = selectedPass.getDuration(); + int price = selectedPass.getPrice(); + + if (passType == StudyCafePassType.HOURLY) { + return String.format("%s시간권 - %d원", duration, price); + } + if (passType == StudyCafePassType.WEEKLY) { + return String.format("%s주권 - %d원", duration, price); + } + if (passType == StudyCafePassType.FIXED) { + return String.format("%s주권 - %d원", duration, price); + } + return ""; + } + + private void newLine() { + System.out.println(); + } +} diff --git a/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java b/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java new file mode 100644 index 000000000..5d4a8773b --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java @@ -0,0 +1,35 @@ +package cleancode.test.asis.io.provider; + +import cleancode.test.asis.model.StudyCafePassType; +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.service.provider.BasicUsingPassProvider; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class BasicUsingPassFileReader implements BasicUsingPassProvider { + + @Override + public List getStudyCafeUsingPass() { + try { + List lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/pass-list.csv")); + List studyCafeUsingPasses = new ArrayList<>(); + for (String line : lines) { + String[] values = line.split(","); + StudyCafePassType studyCafePassType = StudyCafePassType.valueOf(values[0]); + int duration = Integer.parseInt(values[1]); + int price = Integer.parseInt(values[2]); + double discountRate = Double.parseDouble(values[3]); + + StudyCafeUsingPass studyCafeUsingPass = StudyCafeUsingPass.of(studyCafePassType, duration, price, discountRate); + studyCafeUsingPasses.add(studyCafeUsingPass); + } + return studyCafeUsingPasses; + } catch (IOException e) { + throw new RuntimeException("파일을 읽는데 실패했습니다.", e); + } + } +} diff --git a/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java b/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java new file mode 100644 index 000000000..764d5a3ed --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java @@ -0,0 +1,34 @@ +package cleancode.test.asis.io.provider; + +import cleancode.test.asis.model.StudyCafeLockerPass; +import cleancode.test.asis.model.StudyCafePassType; +import cleancode.test.asis.service.provider.LockerPassProvider; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class LockerPassFileReader implements LockerPassProvider { + @Override + public List getStudyCafeLockerPass() { + try { + List lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/locker.csv")); + List lockerPasses = new ArrayList<>(); + for (String line : lines) { + String[] values = line.split(","); + StudyCafePassType studyCafePassType = StudyCafePassType.valueOf(values[0]); + int duration = Integer.parseInt(values[1]); + int price = Integer.parseInt(values[2]); + + StudyCafeLockerPass lockerPass = StudyCafeLockerPass.of(studyCafePassType, duration, price); + lockerPasses.add(lockerPass); + } + + return lockerPasses; + } catch (IOException e) { + throw new RuntimeException("파일을 읽는데 실패했습니다.", e); + } + } +} diff --git a/src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java similarity index 56% rename from src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java rename to src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java index 6512ec0a8..59e008f7f 100644 --- a/src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java +++ b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java @@ -1,6 +1,10 @@ -package cleancode.studycafe.tobe.model; +package cleancode.test.asis.model; -public class StudyCafeLockerPass { +import cleancode.test.asis.service.StudyCafePass; + +import java.util.Objects; + +public class StudyCafeLockerPass implements StudyCafePass { private final StudyCafePassType passType; private final int duration; @@ -16,29 +20,20 @@ public static StudyCafeLockerPass of(StudyCafePassType passType, int duration, i return new StudyCafeLockerPass(passType, duration, price); } - public StudyCafePassType getPassType() { - return passType; - } - - public int getDuration() { - return duration; + public boolean isCompatibleWith(StudyCafeUsingPass pass) { + return Objects.equals(this.passType, pass.getPassType()) && + Objects.equals(this.duration, pass.getDuration()); } public int getPrice() { return price; } - public String display() { - if (passType == StudyCafePassType.HOURLY) { - return String.format("%s시간권 - %d원", duration, price); - } - if (passType == StudyCafePassType.WEEKLY) { - return String.format("%s주권 - %d원", duration, price); - } - if (passType == StudyCafePassType.FIXED) { - return String.format("%s주권 - %d원", duration, price); - } - return ""; + public StudyCafePassType getPassType() { + return passType; } + public int getDuration() { + return duration; + } } diff --git a/src/main/java/cleancode/test/asis/model/StudyCafePassType.java b/src/main/java/cleancode/test/asis/model/StudyCafePassType.java new file mode 100644 index 000000000..8ec27a503 --- /dev/null +++ b/src/main/java/cleancode/test/asis/model/StudyCafePassType.java @@ -0,0 +1,31 @@ +package cleancode.test.asis.model; + +import cleancode.test.asis.exception.AppException; + +import java.util.Arrays; + +public enum StudyCafePassType { + + HOURLY("1", "시간 단위 이용권"), + WEEKLY("2", "주 단위 이용권"), + FIXED("3", "1인 고정석"); + + private final String type; + private final String description; + + StudyCafePassType(String type, String description) { + this.type = type; + this.description = description; + } + + public static StudyCafePassType from(String userInput) { + return Arrays.stream(values()) + .filter(cafePassType -> cafePassType.isEqualTo(userInput)) + .findFirst() + .orElseThrow(() -> new AppException("잘못된 입력입니다")); + } + + private boolean isEqualTo(String userInput) { + return this.type.equals(userInput); + } +} diff --git a/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java b/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java new file mode 100644 index 000000000..3d8d16a69 --- /dev/null +++ b/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java @@ -0,0 +1,52 @@ +package cleancode.test.asis.model; + +import cleancode.test.asis.service.StudyCafePass; + +public class StudyCafeUsingPass implements StudyCafePass { + + private final StudyCafePassType passType; + private final int duration; + private final int price; + private final double discountRate; + + private StudyCafeUsingPass(StudyCafePassType passType, int duration, int price, double discountRate) { + this.passType = passType; + this.duration = duration; + this.price = price; + this.discountRate = discountRate; + } + + public static StudyCafeUsingPass of(StudyCafePassType passType, int duration, int price, double discountRate) { + return new StudyCafeUsingPass(passType, duration, price, discountRate); + } + + public boolean isEqualTo(StudyCafePassType passType) { + return this.passType.equals(passType); + } + + public int getDuration() { + return duration; + } + + public int getPrice() { + return price; + } + + public double getDiscountRate() { + return discountRate; + } + + public int getDiscountPrice() { + return (int) (this.getPrice() * this.discountRate); + } + + public StudyCafePassType getPassType() { + return passType; + } + + public int getTotalPrice(int discountPrice, StudyCafeLockerPass lockerPass) { + int lockerPassPrice = lockerPass != null ? lockerPass.getPrice() : 0; + int totalPassPrice = this.price + lockerPassPrice; + return totalPassPrice - discountPrice; + } +} diff --git a/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java b/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java new file mode 100644 index 000000000..35f36a2ec --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java @@ -0,0 +1,26 @@ +package cleancode.test.asis.service; + +import cleancode.test.asis.model.StudyCafeLockerPass; +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.model.StudyCafePassType; + +import java.util.List; +import java.util.Optional; + +public class StudyCafeLockerPassService { + + private final List lockerPasses; + + public StudyCafeLockerPassService(List lockerPasses) { + this.lockerPasses = lockerPasses; + } + + public Optional findLockerPassBy(StudyCafeUsingPass selectedPass) { + if (selectedPass.isEqualTo(StudyCafePassType.FIXED)) { + return this.lockerPasses.stream() + .filter(lockerPass -> lockerPass.isCompatibleWith(selectedPass)) + .findFirst(); + } + return Optional.empty(); + } +} diff --git a/src/main/java/cleancode/test/asis/service/StudyCafePass.java b/src/main/java/cleancode/test/asis/service/StudyCafePass.java new file mode 100644 index 000000000..61e960dee --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/StudyCafePass.java @@ -0,0 +1,9 @@ +package cleancode.test.asis.service; + +import cleancode.test.asis.model.StudyCafePassType; + +public interface StudyCafePass { + StudyCafePassType getPassType(); + int getDuration(); + int getPrice(); +} diff --git a/src/main/java/cleancode/test/asis/service/StudyCafePassService.java b/src/main/java/cleancode/test/asis/service/StudyCafePassService.java new file mode 100644 index 000000000..2cf5531d1 --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/StudyCafePassService.java @@ -0,0 +1,28 @@ +package cleancode.test.asis.service; + +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.model.StudyCafePassType; + +import java.util.List; + +public class StudyCafePassService { + private final List studyCafeUsingPassList; + + public StudyCafePassService(List studyCafeUsingPassList) { + this.studyCafeUsingPassList = studyCafeUsingPassList; + } + + public List getPasses(StudyCafePassType passType) { + return this.studyCafeUsingPassList.stream() + .filter(studyCafePass -> studyCafePass.isEqualTo(passType)) + .toList(); + } + + public StudyCafeUsingPass getPass(String inputOfPass, List passes) { + return passes.get(selectedIndex(inputOfPass)); + } + + private int selectedIndex(String inputOfPass) { + return Integer.parseInt(inputOfPass) - 1; + } +} diff --git a/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java b/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java new file mode 100644 index 000000000..e14be8488 --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java @@ -0,0 +1,9 @@ +package cleancode.test.asis.service.provider; + +import cleancode.test.asis.model.StudyCafeUsingPass; + +import java.util.List; + +public interface BasicUsingPassProvider { + List getStudyCafeUsingPass(); +} diff --git a/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java b/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java new file mode 100644 index 000000000..bc7a91f22 --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java @@ -0,0 +1,9 @@ +package cleancode.test.asis.service.provider; + +import cleancode.test.asis.model.StudyCafeLockerPass; + +import java.util.List; + +public interface LockerPassProvider { + List getStudyCafeLockerPass(); +} diff --git a/src/test/java/cleancode/test/asis/io/InputHandlerTest.java b/src/test/java/cleancode/test/asis/io/InputHandlerTest.java new file mode 100644 index 000000000..e5fc45012 --- /dev/null +++ b/src/test/java/cleancode/test/asis/io/InputHandlerTest.java @@ -0,0 +1,34 @@ +package cleancode.test.asis.io; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class InputHandlerTest { + + + @Test + @DisplayName("사용자로부터 받은 입력이 LOCKER_OPTION과 같다면 true를 반환한다.") + void getLockerSelectionReturnTrue() { + //given + String lockerOption = "1"; + String input = "1"; + //when + boolean equals = lockerOption.equals(input); + //then + assertThat(equals).isTrue(); + } + + @Test + @DisplayName("사용자로부터 받은 입력이 LOCKER_OPTION과 다르다면 false를 반환한다.") + void getLockerSelectionReturnFalse() { + //given + String lockerOption = "2"; + String input = "1"; + //when + boolean equals = lockerOption.equals(input); + //then + assertThat(equals).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/java/cleancode/test/asis/model/StudyCafeLockerPassTest.java b/src/test/java/cleancode/test/asis/model/StudyCafeLockerPassTest.java new file mode 100644 index 000000000..3504e1498 --- /dev/null +++ b/src/test/java/cleancode/test/asis/model/StudyCafeLockerPassTest.java @@ -0,0 +1,34 @@ +package cleancode.test.asis.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class StudyCafeLockerPassTest { + + @Test + @DisplayName("사용자가 선택한 StudyCafeUsingPass 이용권이 LockerPass의 passType과 duration이 같으면 true를 반환한다.") + void isCompatibleWithTrue() { + //given + StudyCafeLockerPass lockerPass = StudyCafeLockerPass.of(StudyCafePassType.FIXED, 4, 250000); + StudyCafeUsingPass usingPass = StudyCafeUsingPass.of(StudyCafePassType.FIXED, 4, 250000, 0.0); + //when + boolean compatibleWith = lockerPass.isCompatibleWith(usingPass); + //then + assertThat(compatibleWith).isTrue(); + } + + @Test + @DisplayName("사용자가 선택한 StudyCafeUsingPass 이용권이 LockerPass의 passType과 duration이 다르면 false를 반환한다.") + void isCompatibleWithFalse() { + //given + StudyCafeLockerPass lockerPass = StudyCafeLockerPass.of(StudyCafePassType.FIXED, 4, 250000); + StudyCafeUsingPass usingPass = StudyCafeUsingPass.of(StudyCafePassType.HOURLY, 4, 250000, 0.0); + //when + boolean compatibleWith = lockerPass.isCompatibleWith(usingPass); + //then + assertThat(compatibleWith).isFalse(); + } + +} \ No newline at end of file diff --git a/src/test/java/cleancode/test/asis/model/StudyCafePassTypeTest.java b/src/test/java/cleancode/test/asis/model/StudyCafePassTypeTest.java new file mode 100644 index 000000000..da80ed8fe --- /dev/null +++ b/src/test/java/cleancode/test/asis/model/StudyCafePassTypeTest.java @@ -0,0 +1,47 @@ +package cleancode.test.asis.model; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StudyCafePassTypeTest { + + @Test + @DisplayName("사용자가 1을 입력하면 HOURLY(시간 단위 입력권)이 반환된다.") + void getHourly() { + //given + String userInput = "1"; + + //when + StudyCafePassType from = StudyCafePassType.from(userInput); + + //then + Assertions.assertThat(from).isEqualTo(StudyCafePassType.HOURLY); + } + @Test + @DisplayName("사용자가 2을 입력하면 WEEKLY(주 단위 이용권)이 반환된다.") + void getWeekly() { + //given + String userInput = "2"; + + //when + StudyCafePassType from = StudyCafePassType.from(userInput); + + //then + Assertions.assertThat(from).isEqualTo(StudyCafePassType.WEEKLY); + } + @Test + @DisplayName("사용자가 3을 입력하면 FIXED(1인 고정석)이 반환된다.") + void getFixed() { + //given + String userInput = "3"; + + //when + StudyCafePassType from = StudyCafePassType.from(userInput); + + //then + Assertions.assertThat(from).isEqualTo(StudyCafePassType.FIXED); + } +} \ No newline at end of file diff --git a/src/test/java/cleancode/test/asis/model/StudyCafeUsingPassTest.java b/src/test/java/cleancode/test/asis/model/StudyCafeUsingPassTest.java new file mode 100644 index 000000000..e3fe881e9 --- /dev/null +++ b/src/test/java/cleancode/test/asis/model/StudyCafeUsingPassTest.java @@ -0,0 +1,55 @@ +package cleancode.test.asis.model; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class StudyCafeUsingPassTest { + + + + + @Test + @DisplayName("사용자가 선택한 Pass의 할인된 금액을 반환한다.") + void getDiscountRateFixed() { + //given + StudyCafeUsingPass usingPass = StudyCafeUsingPass.of(StudyCafePassType.FIXED, 4, 250000, 0.1); + int result = (int) (usingPass.getPrice() * usingPass.getDiscountRate()); + //when + int discountPrice = usingPass.getDiscountPrice(); + + //then + assertThat(result).isEqualTo(discountPrice); + } + @Test + @DisplayName("사용자가 선택한 Pass의 할인된 금액이 적용된 총 금액을 반환한다.") + void getTotalPrice() { + //given + StudyCafeUsingPass usingPass = StudyCafeUsingPass.of(StudyCafePassType.FIXED, 4, 250000, 0.1); + StudyCafeLockerPass lockerPass = StudyCafeLockerPass.of(StudyCafePassType.FIXED, 4, 10000); + + int totalPassPrice = usingPass.getPrice() + lockerPass.getPrice(); + int result = totalPassPrice - usingPass.getDiscountPrice(); + //when + int totalPrice = usingPass.getTotalPrice(usingPass.getDiscountPrice(), lockerPass); + + + //then + Assertions.assertThat(result).isEqualTo(totalPrice); + } + @Test + @DisplayName("StudyCafeLockerPass가 null일 경우 0을 반환한다") + void getTotalPrice1() { + //given + StudyCafeUsingPass usingPass = StudyCafeUsingPass.of(StudyCafePassType.FIXED, 4, 100, 0.0); + + //when + int totalPrice = usingPass.getTotalPrice(20, null); + + //then + Assertions.assertThat(totalPrice).isEqualTo(80); + } +} \ No newline at end of file