Skip to content
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package cleancode.studycafe.tobe;

import cleancode.studycafe.tobe.io.StudyCafeFileHandler;
import cleancode.studycafe.tobe.model.StudyCafePassRepository;

public class StudyCafeApplication {

public static void main(String[] args) {
StudyCafePassMachine studyCafePassMachine = new StudyCafePassMachine();
StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler();
StudyCafePassRepository repository = StudyCafePassRepository.from(studyCafeFileHandler);
StudyCafePassMachine studyCafePassMachine = new StudyCafePassMachine(repository);
studyCafePassMachine.run();
}

Expand Down
75 changes: 24 additions & 51 deletions src/main/java/cleancode/studycafe/tobe/StudyCafePassMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,52 @@
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 cleancode.studycafe.tobe.model.*;

import java.util.List;

public class StudyCafePassMachine {

private final InputHandler inputHandler = new InputHandler();
private final OutputHandler outputHandler = new OutputHandler();
private final StudyCafePassRepository passRepository;

public StudyCafePassMachine(StudyCafePassRepository passRepository) {
this.passRepository = passRepository;
}

public void run() {
try {
outputHandler.showWelcomeMessage();
outputHandler.showAnnouncement();

outputHandler.askPassTypeSelection();
StudyCafePassType studyCafePassType = inputHandler.getPassTypeSelectingUserAction();

if (studyCafePassType == StudyCafePassType.HOURLY) {
StudyCafeFileHandler studyCafeFileHandler = new StudyCafeFileHandler();
List<StudyCafePass> studyCafePasses = studyCafeFileHandler.readStudyCafePasses();
List<StudyCafePass> 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<StudyCafePass> studyCafePasses = studyCafeFileHandler.readStudyCafePasses();
List<StudyCafePass> 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<StudyCafePass> studyCafePasses = studyCafeFileHandler.readStudyCafePasses();
List<StudyCafePass> fixedPasses = studyCafePasses.stream()
.filter(studyCafePass -> studyCafePass.getPassType() == StudyCafePassType.FIXED)
.toList();
outputHandler.showPassListForSelection(fixedPasses);
StudyCafePass selectedPass = inputHandler.getSelectPass(fixedPasses);
//입장권 조회
StudyCafePassType studyCafePassType = inputHandler.getPassTypeSelectingUserAction();
List<StudyCafePass> hourlyPasses = passRepository.find(studyCafePassType);

List<StudyCafeLockerPass> lockerPasses = studyCafeFileHandler.readLockerPasses();
StudyCafeLockerPass lockerPass = lockerPasses.stream()
.filter(option ->
option.getPassType() == selectedPass.getPassType()
&& option.getDuration() == selectedPass.getDuration()
)
.findFirst()
.orElse(null);
//입장권 선택
outputHandler.showPassListForSelection(hourlyPasses);
StudyCafePass selectedPass = inputHandler.getSelectPass(hourlyPasses);

boolean lockerSelection = false;
if (lockerPass != null) {
outputHandler.askLockerPass(lockerPass);
lockerSelection = inputHandler.getLockerSelection();
}
//사물함 이용
askForUsingLockerPass(selectedPass);

if (lockerSelection) {
outputHandler.showPassOrderSummary(selectedPass, lockerPass);
} else {
outputHandler.showPassOrderSummary(selectedPass, null);
}
}
//금액 출력
outputHandler.showPassOrderSummary(selectedPass);
} catch (AppException e) {
outputHandler.showSimpleMessage(e.getMessage());
} catch (Exception e) {
outputHandler.showSimpleMessage("알 수 없는 오류가 발생했습니다.");
}
}

private void askForUsingLockerPass(StudyCafePass pass) {
assert pass != null;
if (pass.isNotUsingLocker()) return;
outputHandler.askLockerPass(pass);
if (inputHandler.getLockerSelection()) {
pass.selectLocker();
}
}
}
28 changes: 10 additions & 18 deletions src/main/java/cleancode/studycafe/tobe/io/OutputHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cleancode.studycafe.tobe.io;

import cleancode.studycafe.tobe.model.StudyCafeLockerPass;
import cleancode.studycafe.tobe.model.StudyCafePass;

import java.util.List;
Expand All @@ -27,42 +26,35 @@ public void showPassListForSelection(List<StudyCafePass> passes) {
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());
System.out.println(String.format("%s. ", index + 1) + pass.getMenuString());
}
}

public void askLockerPass(StudyCafeLockerPass lockerPass) {
public void askLockerPass(StudyCafePass pass) {
System.out.println();
String askMessage = String.format(
"사물함을 이용하시겠습니까? (%s)",
lockerPass.display()
"사물함을 이용하시겠습니까? (%s)",
pass.getLockerMenuString()
);

System.out.println(askMessage);
System.out.println("1. 예 | 2. 아니오");
}

public void showPassOrderSummary(StudyCafePass selectedPass, StudyCafeLockerPass lockerPass) {
public void showPassOrderSummary(StudyCafePass selectedPass) {
assert selectedPass != null;
System.out.println();
System.out.println("이용 내역");
System.out.println("이용권: " + selectedPass.display());
if (lockerPass != null) {
System.out.println("사물함: " + lockerPass.display());
System.out.println("이용권: " + selectedPass.getMenuString());
if (selectedPass.isLockerSelected()) {
System.out.println("사물함: " + selectedPass.getLockerMenuString());
}

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);
int totalPrice = selectedPass.getTotalPrice();
System.out.println("총 결제 금액: " + totalPrice + "원");
System.out.println();
}

public void showSimpleMessage(String message) {
System.out.println(message);
}

}
38 changes: 10 additions & 28 deletions src/main/java/cleancode/studycafe/tobe/io/StudyCafeFileHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,34 @@

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<StudyCafePass> readStudyCafePasses() {
List<StudyCafeLockerPass> lockerPasses = readLockerPasses();
try {
List<String> lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/pass-list.csv"));
List<StudyCafePass> 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;
return lines.stream().map(line -> line.split(","))
.map(values -> {
int duration = Integer.parseInt(values[1]);
StudyCafeLockerPass locker = lockerPasses.stream().filter((lockerPass -> lockerPass.isCompatible(duration))).findFirst().orElse(null);
return StudyCafePass.of(values, locker);
}).toList();
} catch (IOException e) {
throw new RuntimeException("파일을 읽는데 실패했습니다.", e);
}
}

public List<StudyCafeLockerPass> readLockerPasses() {
private List<StudyCafeLockerPass> readLockerPasses() {
try {
List<String> lines = Files.readAllLines(Paths.get("src/main/resources/cleancode/studycafe/locker.csv"));
List<StudyCafeLockerPass> 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;
return lines.stream().map(line -> line.split(","))
.map(StudyCafeLockerPass::fromValues).toList();
} catch (IOException e) {
throw new RuntimeException("파일을 읽는데 실패했습니다.", e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cleancode.studycafe.tobe.model;

class FixedStudyCafePass extends StudyCafePass{
private final StudyCafeLockerPass lockerPass;
protected FixedStudyCafePass(int duration, int price, double discountRate, StudyCafeLockerPass lockerPass) {
super(StudyCafePassType.FIXED, duration, price, discountRate);
this.lockerPass = lockerPass;
}


@Override
public boolean isNotUsingLocker() {
return false;
}

@Override
public int getLockerPrice() {
return lockerPass.getPrice();
}

@Override
public String getLockerMenuString() {
return lockerPass.toMenuString();
}

@Override
public void selectLocker() {
lockerPass.select();
}

@Override
public boolean isLockerSelected() {
return lockerPass.isSelected();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package cleancode.studycafe.tobe.model;

class HourlyStudyCafePass extends StudyCafePass{
protected HourlyStudyCafePass(int duration, int price, double discountRate) {
super(StudyCafePassType.HOURLY, duration, price, discountRate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,42 @@

public class StudyCafeLockerPass {

private final StudyCafePassType passType;
private final int duration;
private final int price;
private boolean selected;

private StudyCafeLockerPass(StudyCafePassType passType, int duration, int price) {
this.passType = passType;
private StudyCafeLockerPass(int duration, int price) {
this.duration = duration;
this.price = price;
}

public static StudyCafeLockerPass of(StudyCafePassType passType, int duration, int price) {
return new StudyCafeLockerPass(passType, duration, price);
private static StudyCafeLockerPass of(int duration, int price) {
return new StudyCafeLockerPass(duration, price);
}

public StudyCafePassType getPassType() {
return passType;
public static StudyCafeLockerPass fromValues(String[] values) {
int duration = Integer.parseInt(values[1]);
int price = Integer.parseInt(values[2]);
return StudyCafeLockerPass.of(duration, price);
}

public int getDuration() {
return duration;
int getPrice() {
return selected ? price : 0;
}

public int getPrice() {
return price;
public boolean isCompatible(int passDuration) {
return duration == passDuration;
}

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 "";
void select() {
selected = true;
}

boolean isSelected() {
return selected;
}

String toMenuString() {
return StudyCafePassType.FIXED.toMenuString(duration, price);
}
}
Loading