From 50bbdb3698547220702e67ba4b5934ab8f5d418b Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Mon, 10 Mar 2025 20:26:39 +0900 Subject: [PATCH 01/10] =?UTF-8?q?to-be=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../studycafe/tobe/StudyCafeApplication.java | 10 --- .../studycafe/tobe/StudyCafePassMachine.java | 81 ------------------- .../tobe/exception/AppException.java | 9 --- .../studycafe/tobe/io/InputHandler.java | 40 --------- .../studycafe/tobe/io/OutputHandler.java | 68 ---------------- .../tobe/io/StudyCafeFileHandler.java | 56 ------------- .../tobe/model/StudyCafeLockerPass.java | 44 ---------- .../studycafe/tobe/model/StudyCafePass.java | 50 ------------ .../tobe/model/StudyCafePassType.java | 15 ---- 9 files changed, 373 deletions(-) delete mode 100644 src/main/java/cleancode/studycafe/tobe/StudyCafeApplication.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/StudyCafePassMachine.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/exception/AppException.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/io/InputHandler.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/io/OutputHandler.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/io/StudyCafeFileHandler.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/model/StudyCafePass.java delete mode 100644 src/main/java/cleancode/studycafe/tobe/model/StudyCafePassType.java 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/StudyCafeLockerPass.java b/src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java deleted file mode 100644 index 6512ec0a8..000000000 --- a/src/main/java/cleancode/studycafe/tobe/model/StudyCafeLockerPass.java +++ /dev/null @@ -1,44 +0,0 @@ -package cleancode.studycafe.tobe.model; - -public class StudyCafeLockerPass { - - private final StudyCafePassType passType; - private final int duration; - private final int price; - - private StudyCafeLockerPass(StudyCafePassType passType, int duration, int price) { - this.passType = passType; - this.duration = duration; - this.price = price; - } - - public static StudyCafeLockerPass of(StudyCafePassType passType, int duration, int price) { - return new StudyCafeLockerPass(passType, duration, price); - } - - public StudyCafePassType getPassType() { - return passType; - } - - public int getDuration() { - return duration; - } - - 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 ""; - } - -} 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; - } - -} From 3c7bb3932fd7e760b1a94c54c241979ccb0595f0 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Tue, 11 Mar 2025 20:48:04 +0900 Subject: [PATCH 02/10] =?UTF-8?q?refactor=20:=20StudyCafeMachine=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 + .../minesweeper/tobe/MinesweeperGame.java | 310 +++++++++++------- .../studycafe/asis/StudyCafePassMachine.java | 3 +- .../asis/exception/AppException.java | 3 +- .../studycafe/asis/io/OutputHandler.java | 1 + .../studycafe/asis/model/StudyCafePass.java | 11 + .../asis/model/StudyCafePassType.java | 7 + .../service/StudyCafeLockerPassService.java | 26 ++ .../asis/service/StudyCafePassService.java | 28 ++ 9 files changed, 263 insertions(+), 129 deletions(-) create mode 100644 src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java create mode 100644 src/main/java/cleancode/test/asis/service/StudyCafePassService.java 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/test/asis/service/StudyCafeLockerPassService.java b/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java new file mode 100644 index 000000000..f8537445c --- /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.StudyCafePass; +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(StudyCafePass 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/StudyCafePassService.java b/src/main/java/cleancode/test/asis/service/StudyCafePassService.java new file mode 100644 index 000000000..301b77907 --- /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.StudyCafePass; +import cleancode.test.asis.model.StudyCafePassType; + +import java.util.List; + +public class StudyCafePassService { + private final List studyCafePassList; + + public StudyCafePassService(List studyCafePassList) { + this.studyCafePassList = studyCafePassList; + } + + public List getPasses(StudyCafePassType passType) { + return this.studyCafePassList.stream() + .filter(studyCafePass -> studyCafePass.isEqualTo(passType)) + .toList(); + } + + public StudyCafePass getPass(String inputOfPass, List passes) { + return passes.get(selectedIndex(inputOfPass)); + } + + private int selectedIndex(String inputOfPass) { + return Integer.parseInt(inputOfPass) - 1; + } +} From cc4e2a31ed0cd87b954fa9145990a30d599b3ae5 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Tue, 11 Mar 2025 21:47:50 +0900 Subject: [PATCH 03/10] =?UTF-8?q?=ED=99=94=EC=9A=94=EC=9D=BC=20refactoring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cleancode/test/asis/StudyCafePass.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/cleancode/test/asis/StudyCafePass.java diff --git a/src/main/java/cleancode/test/asis/StudyCafePass.java b/src/main/java/cleancode/test/asis/StudyCafePass.java new file mode 100644 index 000000000..098a69ffe --- /dev/null +++ b/src/main/java/cleancode/test/asis/StudyCafePass.java @@ -0,0 +1,4 @@ +package cleancode.test.asis; + +public class StudyCafePass { +} From ecc5af698024e79ee4ff7e910226dbf48a357805 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Tue, 11 Mar 2025 22:33:53 +0900 Subject: [PATCH 04/10] =?UTF-8?q?refactor=20:=202=EC=B0=A8=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cleancode/test/asis/StudyCafePass.java | 4 ---- .../asis/service/StudyCafeLockerPassService.java | 4 ++-- .../cleancode/test/asis/service/StudyCafePass.java | 9 +++++++++ .../test/asis/service/StudyCafePassService.java | 14 +++++++------- 4 files changed, 18 insertions(+), 13 deletions(-) delete mode 100644 src/main/java/cleancode/test/asis/StudyCafePass.java create mode 100644 src/main/java/cleancode/test/asis/service/StudyCafePass.java diff --git a/src/main/java/cleancode/test/asis/StudyCafePass.java b/src/main/java/cleancode/test/asis/StudyCafePass.java deleted file mode 100644 index 098a69ffe..000000000 --- a/src/main/java/cleancode/test/asis/StudyCafePass.java +++ /dev/null @@ -1,4 +0,0 @@ -package cleancode.test.asis; - -public class StudyCafePass { -} diff --git a/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java b/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java index f8537445c..35f36a2ec 100644 --- a/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java +++ b/src/main/java/cleancode/test/asis/service/StudyCafeLockerPassService.java @@ -1,7 +1,7 @@ package cleancode.test.asis.service; import cleancode.test.asis.model.StudyCafeLockerPass; -import cleancode.test.asis.model.StudyCafePass; +import cleancode.test.asis.model.StudyCafeUsingPass; import cleancode.test.asis.model.StudyCafePassType; import java.util.List; @@ -15,7 +15,7 @@ public StudyCafeLockerPassService(List lockerPasses) { this.lockerPasses = lockerPasses; } - public Optional findLockerPassBy(StudyCafePass selectedPass) { + public Optional findLockerPassBy(StudyCafeUsingPass selectedPass) { if (selectedPass.isEqualTo(StudyCafePassType.FIXED)) { return this.lockerPasses.stream() .filter(lockerPass -> lockerPass.isCompatibleWith(selectedPass)) 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 index 301b77907..2cf5531d1 100644 --- a/src/main/java/cleancode/test/asis/service/StudyCafePassService.java +++ b/src/main/java/cleancode/test/asis/service/StudyCafePassService.java @@ -1,24 +1,24 @@ package cleancode.test.asis.service; -import cleancode.test.asis.model.StudyCafePass; +import cleancode.test.asis.model.StudyCafeUsingPass; import cleancode.test.asis.model.StudyCafePassType; import java.util.List; public class StudyCafePassService { - private final List studyCafePassList; + private final List studyCafeUsingPassList; - public StudyCafePassService(List studyCafePassList) { - this.studyCafePassList = studyCafePassList; + public StudyCafePassService(List studyCafeUsingPassList) { + this.studyCafeUsingPassList = studyCafeUsingPassList; } - public List getPasses(StudyCafePassType passType) { - return this.studyCafePassList.stream() + public List getPasses(StudyCafePassType passType) { + return this.studyCafeUsingPassList.stream() .filter(studyCafePass -> studyCafePass.isEqualTo(passType)) .toList(); } - public StudyCafePass getPass(String inputOfPass, List passes) { + public StudyCafeUsingPass getPass(String inputOfPass, List passes) { return passes.get(selectedIndex(inputOfPass)); } From b7a94c4fb029214f2215434f177bb961a6f7ae08 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Wed, 12 Mar 2025 11:46:15 +0900 Subject: [PATCH 05/10] =?UTF-8?q?2=EC=B0=A8=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/asis/io/provider/BasicUsingPassFileReader.java | 4 ++++ .../cleancode/test/asis/io/provider/LockerPassFileReader.java | 4 ++++ .../test/asis/service/provider/BasicUsingPassProvider.java | 4 ++++ .../test/asis/service/provider/LockerPassProvider.java | 4 ++++ 4 files changed, 16 insertions(+) create mode 100644 src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java create mode 100644 src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java create mode 100644 src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java create mode 100644 src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java 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..6503b32c7 --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java @@ -0,0 +1,4 @@ +package cleancode.test.asis.io.provider; + +public class UsingPassFileReader { +} 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..cc9dba4e4 --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java @@ -0,0 +1,4 @@ +package cleancode.test.asis.io.provider; + +public class LockerPassReader { +} 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..66f56fdb8 --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java @@ -0,0 +1,4 @@ +package cleancode.test.asis.service.provider; + +public class BasicUsingPassProvider { +} 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..b6caec8a8 --- /dev/null +++ b/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java @@ -0,0 +1,4 @@ +package cleancode.test.asis.service.provider; + +public class LockerPassProvider { +} From 23c753718c709dcee39641e42587653f92dcf308 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Sun, 16 Mar 2025 23:52:55 +0900 Subject: [PATCH 06/10] first commit --- .../test/asis/StudyCafeApplication.java | 17 ++++ .../test/asis/StudyCafePassMachine.java | 79 +++++++++++++++ .../test/asis/exception/AppException.java | 10 ++ .../cleancode/test/asis/io/InputHandler.java | 18 ++++ .../cleancode/test/asis/io/OutputHandler.java | 97 +++++++++++++++++++ .../io/provider/BasicUsingPassFileReader.java | 33 ++++++- .../io/provider/LockerPassFileReader.java | 32 +++++- .../test/asis/model/StudyCafeLockerPass.java | 38 ++++++++ .../test/asis/model/StudyCafePassType.java | 31 ++++++ .../test/asis/model/StudyCafeUsingPass.java | 48 +++++++++ .../provider/BasicUsingPassProvider.java | 7 +- .../service/provider/LockerPassProvider.java | 7 +- .../StudyCafeUsingPassesServiceTest.java | 36 +++++++ 13 files changed, 449 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cleancode/test/asis/StudyCafeApplication.java create mode 100644 src/main/java/cleancode/test/asis/StudyCafePassMachine.java create mode 100644 src/main/java/cleancode/test/asis/exception/AppException.java create mode 100644 src/main/java/cleancode/test/asis/io/InputHandler.java create mode 100644 src/main/java/cleancode/test/asis/io/OutputHandler.java create mode 100644 src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java create mode 100644 src/main/java/cleancode/test/asis/model/StudyCafePassType.java create mode 100644 src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java create mode 100644 src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java 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..4c76eb617 --- /dev/null +++ b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java @@ -0,0 +1,79 @@ +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; + +public class StudyCafePassMachine { + + 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(); + } + + 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..8b47e1871 --- /dev/null +++ b/src/main/java/cleancode/test/asis/io/InputHandler.java @@ -0,0 +1,18 @@ +package cleancode.test.asis.io; + +import java.util.Scanner; + +public class InputHandler { + + private static final Scanner SCANNER = new Scanner(System.in); + private static final String LOCKER_OPTION = "1"; + + public String getUserAction() { + return SCANNER.nextLine(); + } + + public boolean getLockerSelection() { + String userInput = SCANNER.nextLine(); + return LOCKER_OPTION.equals(userInput); + } +} 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 index 6503b32c7..5d4a8773b 100644 --- a/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java +++ b/src/main/java/cleancode/test/asis/io/provider/BasicUsingPassFileReader.java @@ -1,4 +1,35 @@ package cleancode.test.asis.io.provider; -public class UsingPassFileReader { +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 index cc9dba4e4..764d5a3ed 100644 --- a/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java +++ b/src/main/java/cleancode/test/asis/io/provider/LockerPassFileReader.java @@ -1,4 +1,34 @@ package cleancode.test.asis.io.provider; -public class LockerPassReader { +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/test/asis/model/StudyCafeLockerPass.java b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java new file mode 100644 index 000000000..6dfbe154f --- /dev/null +++ b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java @@ -0,0 +1,38 @@ +package cleancode.test.asis.model; + +import cleancode.test.asis.service.StudyCafePass; + +import java.util.Objects; + +public class StudyCafeLockerPass implements StudyCafePass { + + private final StudyCafePassType passType; + private final int duration; + private final int price; + + private StudyCafeLockerPass(StudyCafePassType passType, int duration, int price) { + this.passType = passType; + this.duration = duration; + this.price = price; + } + + public static StudyCafeLockerPass of(StudyCafePassType passType, int duration, int price) { + return new StudyCafeLockerPass(passType, duration, price); + } + + public boolean isCompatibleWith(StudyCafeUsingPass pass) { + return Objects.equals(this.passType, pass.getPassType()) && Objects.equals(this.duration, pass.getDuration()); + } + + public int getPrice() { + return price; + } + + 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..1a6a91447 --- /dev/null +++ b/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java @@ -0,0 +1,48 @@ +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 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/provider/BasicUsingPassProvider.java b/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java index 66f56fdb8..e14be8488 100644 --- a/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java +++ b/src/main/java/cleancode/test/asis/service/provider/BasicUsingPassProvider.java @@ -1,4 +1,9 @@ package cleancode.test.asis.service.provider; -public class BasicUsingPassProvider { +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 index b6caec8a8..bc7a91f22 100644 --- a/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java +++ b/src/main/java/cleancode/test/asis/service/provider/LockerPassProvider.java @@ -1,4 +1,9 @@ package cleancode.test.asis.service.provider; -public class LockerPassProvider { +import cleancode.test.asis.model.StudyCafeLockerPass; + +import java.util.List; + +public interface LockerPassProvider { + List getStudyCafeLockerPass(); } diff --git a/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java b/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java new file mode 100644 index 000000000..0e4656449 --- /dev/null +++ b/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java @@ -0,0 +1,36 @@ +package cleancode.test.asis.service; + +import cleancode.test.asis.model.StudyCafeUsingPass; +import cleancode.test.asis.model.StudyCafePassType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +class StudyCafeUsingPassesServiceTest { + List studyCafeUsingPassList = StudyCafeFileHandler.readStudyCafePasses(); + + StudyCafePassType hourly = StudyCafePassType.HOURLY; + StudyCafePassType weekly = StudyCafePassType.WEEKLY; + StudyCafePassType fixed = StudyCafePassType.FIXED; + + List hourlyList = this.studyCafeUsingPassList.stream() + .filter(studyCafePass -> studyCafePass.isEqualTo(hourly)) + .toList(); + + List weeklyList = this.studyCafeUsingPassList.stream() + .filter(studyCafePass -> studyCafePass.isEqualTo(weekly)) + .toList(); + + List fixedList = this.studyCafeUsingPassList.stream() + .filter(studyCafePass -> studyCafePass.isEqualTo(fixed)) + .toList(); + + @Test + @DisplayName("") + void getPasses() { + //then + StudyCafeUsingPass studyCafeUsingPass = weeklyList.get(Integer.parseInt("3") - 1); + System.out.println("studyCafePass = " + studyCafeUsingPass); + } +} \ No newline at end of file From 4a3ee3ce58ac30d3c0e3d56c154b7da423471051 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Mon, 17 Mar 2025 00:06:52 +0900 Subject: [PATCH 07/10] =?UTF-8?q?style=20:=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StudyCafeUsingPassesServiceTest.java | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java diff --git a/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java b/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java deleted file mode 100644 index 0e4656449..000000000 --- a/src/test/java/cleancode/test/asis/service/StudyCafeUsingPassesServiceTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package cleancode.test.asis.service; - -import cleancode.test.asis.model.StudyCafeUsingPass; -import cleancode.test.asis.model.StudyCafePassType; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; - -class StudyCafeUsingPassesServiceTest { - List studyCafeUsingPassList = StudyCafeFileHandler.readStudyCafePasses(); - - StudyCafePassType hourly = StudyCafePassType.HOURLY; - StudyCafePassType weekly = StudyCafePassType.WEEKLY; - StudyCafePassType fixed = StudyCafePassType.FIXED; - - List hourlyList = this.studyCafeUsingPassList.stream() - .filter(studyCafePass -> studyCafePass.isEqualTo(hourly)) - .toList(); - - List weeklyList = this.studyCafeUsingPassList.stream() - .filter(studyCafePass -> studyCafePass.isEqualTo(weekly)) - .toList(); - - List fixedList = this.studyCafeUsingPassList.stream() - .filter(studyCafePass -> studyCafePass.isEqualTo(fixed)) - .toList(); - - @Test - @DisplayName("") - void getPasses() { - //then - StudyCafeUsingPass studyCafeUsingPass = weeklyList.get(Integer.parseInt("3") - 1); - System.out.println("studyCafePass = " + studyCafeUsingPass); - } -} \ No newline at end of file From fc10ec07e4b35316decf519425c34c454efb174e Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Mon, 17 Mar 2025 00:07:38 +0900 Subject: [PATCH 08/10] =?UTF-8?q?refactor=20:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9D=98=20=EA=B0=84=ED=8E=B8=ED=95=A8=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=EC=84=9C=20Scanner=EB=A5=BC=20=EC=99=B8?= =?UTF-8?q?=EB=B6=80=EC=97=90=EC=84=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cleancode/test/asis/io/InputHandler.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/cleancode/test/asis/io/InputHandler.java b/src/main/java/cleancode/test/asis/io/InputHandler.java index 8b47e1871..702e1d4e5 100644 --- a/src/main/java/cleancode/test/asis/io/InputHandler.java +++ b/src/main/java/cleancode/test/asis/io/InputHandler.java @@ -1,18 +1,14 @@ package cleancode.test.asis.io; -import java.util.Scanner; - public class InputHandler { - private static final Scanner SCANNER = new Scanner(System.in); private static final String LOCKER_OPTION = "1"; - public String getUserAction() { - return SCANNER.nextLine(); + public String getUserAction(String input) { + return input; } - public boolean getLockerSelection() { - String userInput = SCANNER.nextLine(); - return LOCKER_OPTION.equals(userInput); + public boolean getLockerSelection(String input) { + return LOCKER_OPTION.equals(input); } } From 75998b57475fad8538f8945370aae25f337b7425 Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Mon, 17 Mar 2025 00:07:49 +0900 Subject: [PATCH 09/10] =?UTF-8?q?refactor=20:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9D=98=20=EA=B0=84=ED=8E=B8=ED=95=A8=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=EC=84=9C=20Scanner=EB=A5=BC=20=EC=99=B8?= =?UTF-8?q?=EB=B6=80=EC=97=90=EC=84=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/asis/StudyCafePassMachine.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/cleancode/test/asis/StudyCafePassMachine.java b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java index 4c76eb617..49e07a187 100644 --- a/src/main/java/cleancode/test/asis/StudyCafePassMachine.java +++ b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java @@ -12,9 +12,12 @@ 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(); @@ -37,8 +40,8 @@ public void run() { outputHandler.showWelcomeMessage(); outputHandler.showAnnouncement(); - StudyCafePassType selectedPassType = selectPassType(); - StudyCafeUsingPass selectedPass = selectPass(selectedPassType); + StudyCafePassType selectedPassType = selectPassType(SCANNER.nextLine()); + StudyCafeUsingPass selectedPass = selectPass(selectedPassType, SCANNER.nextLine()); handleLockerPass(selectedPass); } catch (AppException e) { @@ -48,22 +51,22 @@ public void run() { } } - private StudyCafeUsingPass selectPass(StudyCafePassType passType) { + private StudyCafeUsingPass selectPass(StudyCafePassType passType, String input) { List passes = passService.getPasses(passType); outputHandler.showPassListForSelection(passes); - String userInput = inputHandler.getUserAction(); + String userInput = inputHandler.getUserAction(input); return passService.getPass(userInput, passes); } private boolean selectLockerOption(StudyCafeLockerPass lockerPass) { outputHandler.askLockerPass(lockerPass); - return inputHandler.getLockerSelection(); + return inputHandler.getLockerSelection(SCANNER.nextLine()); } - private StudyCafePassType selectPassType() { + private StudyCafePassType selectPassType(String input) { outputHandler.askPassTypeSelection(); - String userInput = inputHandler.getUserAction(); + String userInput = inputHandler.getUserAction(input); return StudyCafePassType.from(userInput); } From 960c30c49aa3f3f92d19f6d9596cc672580913db Mon Sep 17 00:00:00 2001 From: chulhyun96 Date: Mon, 17 Mar 2025 15:21:28 +0900 Subject: [PATCH 10/10] =?UTF-8?q?test=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/asis/StudyCafePassMachine.java | 14 ++--- .../cleancode/test/asis/io/InputHandler.java | 7 ++- .../test/asis/model/StudyCafeLockerPass.java | 3 +- .../test/asis/model/StudyCafeUsingPass.java | 4 ++ .../test/asis/io/InputHandlerTest.java | 34 ++++++++++++ .../asis/model/StudyCafeLockerPassTest.java | 34 ++++++++++++ .../asis/model/StudyCafePassTypeTest.java | 47 ++++++++++++++++ .../asis/model/StudyCafeUsingPassTest.java | 55 +++++++++++++++++++ 8 files changed, 188 insertions(+), 10 deletions(-) create mode 100644 src/test/java/cleancode/test/asis/io/InputHandlerTest.java create mode 100644 src/test/java/cleancode/test/asis/model/StudyCafeLockerPassTest.java create mode 100644 src/test/java/cleancode/test/asis/model/StudyCafePassTypeTest.java create mode 100644 src/test/java/cleancode/test/asis/model/StudyCafeUsingPassTest.java diff --git a/src/main/java/cleancode/test/asis/StudyCafePassMachine.java b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java index 49e07a187..acc442b53 100644 --- a/src/main/java/cleancode/test/asis/StudyCafePassMachine.java +++ b/src/main/java/cleancode/test/asis/StudyCafePassMachine.java @@ -40,8 +40,8 @@ public void run() { outputHandler.showWelcomeMessage(); outputHandler.showAnnouncement(); - StudyCafePassType selectedPassType = selectPassType(SCANNER.nextLine()); - StudyCafeUsingPass selectedPass = selectPass(selectedPassType, SCANNER.nextLine()); + StudyCafePassType selectedPassType = selectPassType(); + StudyCafeUsingPass selectedPass = selectPass(selectedPassType); handleLockerPass(selectedPass); } catch (AppException e) { @@ -51,22 +51,22 @@ public void run() { } } - private StudyCafeUsingPass selectPass(StudyCafePassType passType, String input) { + private StudyCafeUsingPass selectPass(StudyCafePassType passType) { List passes = passService.getPasses(passType); outputHandler.showPassListForSelection(passes); - String userInput = inputHandler.getUserAction(input); + String userInput = inputHandler.getUserAction(); return passService.getPass(userInput, passes); } private boolean selectLockerOption(StudyCafeLockerPass lockerPass) { outputHandler.askLockerPass(lockerPass); - return inputHandler.getLockerSelection(SCANNER.nextLine()); + return inputHandler.getLockerSelection(inputHandler.getUserAction()); } - private StudyCafePassType selectPassType(String input) { + private StudyCafePassType selectPassType() { outputHandler.askPassTypeSelection(); - String userInput = inputHandler.getUserAction(input); + String userInput = inputHandler.getUserAction(); return StudyCafePassType.from(userInput); } diff --git a/src/main/java/cleancode/test/asis/io/InputHandler.java b/src/main/java/cleancode/test/asis/io/InputHandler.java index 702e1d4e5..bda5e7efb 100644 --- a/src/main/java/cleancode/test/asis/io/InputHandler.java +++ b/src/main/java/cleancode/test/asis/io/InputHandler.java @@ -1,11 +1,14 @@ 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(String input) { - return input; + public String getUserAction() { + return scanner.nextLine(); } public boolean getLockerSelection(String input) { diff --git a/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java index 6dfbe154f..59e008f7f 100644 --- a/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java +++ b/src/main/java/cleancode/test/asis/model/StudyCafeLockerPass.java @@ -21,7 +21,8 @@ public static StudyCafeLockerPass of(StudyCafePassType passType, int duration, i } public boolean isCompatibleWith(StudyCafeUsingPass pass) { - return Objects.equals(this.passType, pass.getPassType()) && Objects.equals(this.duration, pass.getDuration()); + return Objects.equals(this.passType, pass.getPassType()) && + Objects.equals(this.duration, pass.getDuration()); } public int getPrice() { diff --git a/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java b/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java index 1a6a91447..3d8d16a69 100644 --- a/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java +++ b/src/main/java/cleancode/test/asis/model/StudyCafeUsingPass.java @@ -32,6 +32,10 @@ public int getPrice() { return price; } + public double getDiscountRate() { + return discountRate; + } + public int getDiscountPrice() { return (int) (this.getPrice() * this.discountRate); } 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