Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## ✏️ 구현할 기능 목록

___

## 초기 설정

- [X] 프로그램 시작 시 역, 노선, 구간 정보를 초기 설정 해야 한다.
- 거리와 소요 시간은 양의 정수이며 단위는 km와 분을 의미한다.

## 입력

- [X] `메인 화면 : 원하는 기능 선택` 입력
- 비기능적 요구사항
- null 값이거나 빈 값인지 확인한다.
- `1`, `Q`가 아니면 예외가 발생한다.

- 기능적 요구사항
- `1` : 경로 조회
- `Q` : 종료

- [X] `경로 기준 : 원하는 기능 선택` 입력
- 비기능적 요구사항
```
1. 최단 거리
2. 최소 시간
B. 돌아가기
```
- null 값이거나 빈 값인지 확인한다.
- `1`, `2`, `B`가 아니면 예외가 발생한다.

- 기능적 요구사항
- `1` : 최단 거리
- `2` : 최소 시간
- `B` : 돌아가기

- [X] `출발역` 입력
- 비기능적 요구사항
- null 값이거나 빈 값인지 확인한다.

- 기능적 요구사항
- 등록된 지하철 역인지 확인한다. (`교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역`)

- [X] `도착역` 입력

- 비기능적 요구사항
- null 값이거나 빈 값인지 확인한다.

- 기능적 요구사항
- 등록된 지하철 역인지 확인한다. (`교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역`)
- 출발역과 도착역이 같으면 예외가 발생한다.

## 조회 결과

- [X] 경로 조회 시 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다.
- 경로 조회 시 총 거리, 총 소요 시간도 함께 출력한다.

## 출력

- [X] `## 메인 화면` 출력
```
1. 경로 조회
Q. 종료
```

- [X] `## 원하는 기능을 선택하세요.` 출력


- [X] `## 경로 기준` 출력
```
1. 최단 거리
2. 최소 시간
B. 돌아가기
```

- [X] `## 출발역을 입력하세요.` 출력

- [X] `## 도착역을 입력하세요.` 출력

- [X] `## 조회 결과` 출력
- 기대하는 출력 결과는 `[INFO]`를 붙여서 출력한다.

---

## 공통 검증

- [X] 에러 발생 시 `[ERROR]`를 붙여서 출력한다. 에러의 문구는 자유롭게 작성한다.
105 changes: 104 additions & 1 deletion src/main/java/subway/Application.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,113 @@
package subway;

import java.util.Scanner;
import subway.controller.InitController;
import subway.controller.InputController;
import subway.controller.SubwayController;
import subway.domain.Station;
import subway.repository.LineRepository;
import subway.repository.StationRepository;
import subway.service.LineService;
import subway.service.MinimumTimeService;
import subway.service.ShortestPathService;
import subway.service.StationService;
import subway.validation.EndStationValidation;
import subway.validation.MainFunctionValidation;
import subway.validation.SelectRouteValidation;
import subway.validation.StartStationValidation;
import subway.view.Input.InputView;
import subway.view.output.OutputView;

public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현

// 객체 생성

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

움 여기도 로또와 같군요! 만약 controller와 service에 대한 객체 생성하는 관심사를 특정 클래스에서 하고싶다면 Configuration클래스를 만드는건 어떨까요? 스프링부트에서 @configuration이 Bean을 등록해주는 어노테이션이니까요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최종 코테에서 사용할 템플릿을 만들다보니 같은 형식으로 만들어졌군요 ㅜㅜ
다시 고민해봐야겠습니다!!

InputView inputView = createInputView();
OutputView outputView = new OutputView();

StationService stationService = createStationService(new StationRepository());
LineService lineService = createLineService(new LineRepository());
ShortestPathService shortestPathService = new ShortestPathService();
MinimumTimeService minimumTimeService = new MinimumTimeService();

InitController initController = createInitController(stationService, lineService);
InputController inputController = createInputController(inputView, outputView, scanner);
SubwayController subwayController = createSubwayController(shortestPathService, minimumTimeService, outputView);

// 메서드 호출
executeControllers(initController, inputController, subwayController);
}

private static InputView createInputView() {
MainFunctionValidation mainFunctionValidation = new MainFunctionValidation();
SelectRouteValidation selectRouteValidation = new SelectRouteValidation();
StartStationValidation startStationValidation = new StartStationValidation();
EndStationValidation endStationValidation = new EndStationValidation();
return new InputView(mainFunctionValidation, selectRouteValidation, startStationValidation,
endStationValidation);
}

private static StationService createStationService(StationRepository stationRepository) {
return StationService.createStationService(stationRepository);
}

private static LineService createLineService(LineRepository lineRepository) {
return LineService.createLineService(lineRepository);
}


private static InitController createInitController(StationService stationService, LineService lineService) {
return InitController.createInitController(stationService, lineService);
}

private static InputController createInputController(InputView inputView, OutputView outputView, Scanner scanner) {
return InputController.createInputController(inputView, outputView, scanner);
}

private static SubwayController createSubwayController(ShortestPathService shortestPathService,
MinimumTimeService minimumTimeService,
OutputView outputView) {
return SubwayController.createSubwayController(shortestPathService, minimumTimeService, outputView);
}


private static void executeControllers(InitController initController, InputController inputController,
SubwayController subwayController) {
initController.init();

while (true) {
String mainFunc = inputController.inputMainFunc();
if (mainFunc.equals("Q")) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q나 1같은 값은 Function enum클래스로 접근해서 작성하셨을 수 있을 것 같아요!

System.exit(0);
}

if (mainFunc.equals("1")) {
executeRouteSelection(inputController, subwayController);
}
}
}

private static void executeRouteSelection(InputController inputController, SubwayController subwayController) {
String selectRouteFunc = inputController.inputSelectRoute();
if (selectRouteFunc.equals("B")) {
return;
}

Station start = inputStartStation(inputController);
Station end = inputEndStation(inputController, start);

subwayController.calculateAndPrintRoute(selectRouteFunc, start, end);
}

private static Station inputStartStation(InputController inputController) {
String stationName = inputController.inputStartStation();
return new Station(stationName);
}

private static Station inputEndStation(InputController inputController, Station start) {
String stationName = inputController.inputEndStation(start.getName());
return new Station(stationName);
}
}

13 changes: 13 additions & 0 deletions src/main/java/subway/constant/Function.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package subway.constant;

public enum Function {
SEARCHING_ROUTE("1. 경로 조회"),
QUIT("Q. 종료");

public final String message;

Function(String message) {
this.message = message;
}

}
50 changes: 50 additions & 0 deletions src/main/java/subway/constant/PrintOutMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package subway.constant;

import java.util.List;

public enum PrintOutMessage {
MAIN("메인 화면"),
PLZ_INPUT_FUNCTION("원하는 기능을 선택하세요."),
PLZ_INPUT_PATH_STANDARD("경로 기준"),
PLZ_INPUT_START_STATION("출발역을 입력하세요."),
PLZ_INPUT_END_STATION("도착역을 입력하세요."),
SEARCHING_RESULT("조회 결과"),
TOTAL_DISTANCE("총 거리: "),
TOTAL_TIME("총 소요 시간: "),
KILOMETER("km"),
MINUTE("분"),
EMPTY_LINE("\n"),
DASH("---");

public final String message;
private final String decorate = "## ";
private static String info = "[INFO] ";

PrintOutMessage(String message) {
this.message = message;
}

public String getMessage() {
return decorate + message;
}

public static String getDash() {
return info + DASH.message;
}

public static String printTotalDistance(int distance) {
return info + TOTAL_DISTANCE.message + distance + KILOMETER.message;
}

public static String printTotalTime(int time) {
return info + TOTAL_TIME.message + time + MINUTE.message;
}

public static String getRoutes(List<String> routes) {
StringBuilder sb = new StringBuilder();
for (String route : routes) {
sb.append(info).append(route).append("\n");
}
return sb.toString();
}
}
14 changes: 14 additions & 0 deletions src/main/java/subway/constant/SelectRoute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package subway.constant;

public enum SelectRoute {
SHORTEST_PATH("1. 최단 거리"),
MINIMUM_TIME("2. 최소 시간"),
BACK("B. 돌아가기");

public final String message;

SelectRoute(String message) {
this.message = message;
}

}
23 changes: 23 additions & 0 deletions src/main/java/subway/controller/InitController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package subway.controller;

import subway.service.LineService;
import subway.service.StationService;

public class InitController {
private final StationService stationService;
private final LineService lineService;

private InitController(StationService stationService, LineService lineService) {
this.stationService = stationService;
this.lineService = lineService;
}

public static InitController createInitController(StationService stationService, LineService lineService) {
return new InitController(stationService, lineService);
}

public void init() {
stationService.registerStation();
lineService.registerLine();
}
}
68 changes: 68 additions & 0 deletions src/main/java/subway/controller/InputController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package subway.controller;

import java.util.Scanner;
import subway.exception.ErrorInputException;
import subway.view.Input.InputView;
import subway.view.output.OutputView;

public class InputController {
private final InputView inputView;
private final OutputView outputView;
private final Scanner scanner;

private InputController(InputView inputView, OutputView outputView, Scanner scanner) {
this.inputView = inputView;
this.outputView = outputView;
this.scanner = scanner;
}

public static InputController createInputController(InputView inputView, OutputView outputView, Scanner scanner) {
return new InputController(inputView, outputView, scanner);
}

public String inputMainFunc() {
while (true) {
try {
outputView.printMain();
outputView.printSelectFunc();
return inputView.readMainFunc(scanner.next());
} catch (ErrorInputException e) {
outputView.printError(e.getMessage());
}
}
}

public String inputSelectRoute() {
while (true) {
try {
outputView.printSelectPath();
outputView.printSelectFunc();
return inputView.readSelectRoute(scanner.next());
} catch (ErrorInputException e) {
outputView.printError(e.getMessage());
}
}
}

public String inputStartStation() {
while (true) {
try {
outputView.printStartStation();
return inputView.readStartStation(scanner.next());
} catch (ErrorInputException e) {
outputView.printError(e.getMessage());
}
}
}

public String inputEndStation(String start) {
while (true) {
try {
outputView.printEndStation();
return inputView.readEndStation(start, scanner.next());
} catch (ErrorInputException e) {
outputView.printError(e.getMessage());
}
}
}
}
Loading