diff --git a/README.md b/README.md
index bb0c84ebb..402df41c3 100644
--- a/README.md
+++ b/README.md
@@ -1,253 +1,81 @@
-# 지하철 노선도 경로 조회 미션
-- 등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다.
+3:10~8:10
-
+# 🚀 미션 - 지하철 노선도 경로 조회
-## 🚀 기능 요구사항
+등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다.
-> 프리코스 3주차 미션에서 사용한 코드를 참고해도 무관하다.
+# 📈 기능 목록
-### 초기 설정
-- 프로그램 시작 시 역, 노선, 구간 정보를 초기 설정 해야 한다.
-- 거리와 소요 시간은 양의 정수이며 단위는 km와 분을 의미한다.
-- 아래의 사전 등록 정보로 반드시 초기 설정을 한다.
+## 구현 기능 목록
-```
- 1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다.
- 2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
- 3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
- - 2호선: 교대역 - ( 2km / 3분 ) - 강남역 - ( 2km / 3분 ) - 역삼역
- - 3호선: 교대역 - ( 3km / 2분 ) - 남부터미널역 - ( 6km / 5분 ) - 양재역 - ( 1km / 1분 ) - 매봉역
- - 신분당선: 강남역 - ( 2km / 8분 ) - 양재역 - ( 10km / 3분 ) - 양재시민의숲역
- ```
-
-### 경로 조회 기능
-- 출발역과 도착역을 입력받아 경로를 조회한다.
-- 경로 조회 시 총 거리, 총 소요 시간도 함께 출력한다.
-- 경로 조회 기준은 `최단 거리` `최소 시간`이 있다.
-
-### 예외 처리
-- 경로 조회 시 출발역과 도착역이 같으면 에러를 출력한다.
-- 경로 조회 시 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다.
-- 그 외 정상적으로 프로그램이 수행되지 않은 경우 에러를 출력한다.
-
-
-
-## ✍🏻 입출력 요구사항
-- `프로그래밍 실행 결과 예시`와 동일하게 입출력을 구현한다.
-- 기대하는 출력 결과는 `[INFO]`를 붙여서 출력한다. 출력값의 형식은 예시와 동일하게 한다.
-- 에러 발생 시 `[ERROR]`를 붙여서 출력한다. 에러의 문구는 자유롭게 작성한다.
-
-### 💻 프로그래밍 실행 결과 예시
-#### 경로 조회
-```
-## 메인 화면
-1. 경로 조회
-Q. 종료
-
-## 원하는 기능을 선택하세요.
-1
-
-## 경로 기준
-1. 최단 거리
-2. 최소 시간
-B. 돌아가기
-
-## 원하는 기능을 선택하세요.
-1
-## 출발역을 입력하세요.
-교대역
+### 초기설정
-## 도착역을 입력하세요.
-양재역
+- [x] 역, 노선, 구간 정보 초기 설정
+- [x] 거리와 소요 시간은 양의 정수, 단위는 km와 분
-## 조회 결과
-[INFO] ---
-[INFO] 총 거리: 4km
-[INFO] 총 소요 시간: 11분
-[INFO] ---
-[INFO] 교대역
-[INFO] 강남역
-[INFO] 양재역
-
-## 메인 화면
-1. 경로 조회
-Q. 종료
-
-...
```
-
-#### 에러 출력 예시
-
+1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다.
+2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
+3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
+- 2호선: 교대역 - ( 2km / 3분 ) - 강남역 - ( 2km / 3분 ) - 역삼역
+- 3호선: 교대역 - ( 3km / 2분 ) - 남부터미널역 - ( 6km / 5분 ) - 양재역 - ( 1km / 1분 ) - 매봉역
+- 신분당선: 강남역 - ( 2km / 8분 ) - 양재역 - ( 10km / 3분 ) - 양재시민의숲역
```
-## 메인 화면
-1. 경로 조회
-Q. 종료
-
-## 원하는 기능을 선택하세요.
-1
-## 경로 기준
-1. 최단 거리
-2. 최소 시간
-B. 돌아가기
+### ✅ 최단 거리 경로 조회 기능
-## 원하는 기능을 선택하세요.
-1
+- [x] 출발역과 도착역을 받음
+- [x] 최단 거리 기준으로 경로를 조회
+ - [x] [예외] 출발역과 도착역이 같으면
+ - [x] [예외] 출발역과 도착역이 연결되어 있지 않으면
+ - [x] [예외] 출발역의 이름이 잘못됨
+ - [x] [예외] 도착역의 이름이 잘못됨
+ - [ ] [예외] 그 외
+- [x] 총 거리, 총 소요 시간 리턴
-## 출발역을 입력하세요.
-강남역
+### ✅ 최소 시간 경로 조회 기능
-## 도착역을 입력하세요.
-강남역
+- [x] 출발역과 도착역을 입력
+- [x] 최단 거리 기준으로 경로를 조회
+ - [x] [예외] 출발역과 도착역이 같으면
+ - [x] [예외] 출발역과 도착역이 연결되어 있지 않으면
+ - [ ] [예외] 그 외
+- [x] 총 거리, 총 소요 시간 리턴
-[ERROR] 출발역과 도착역이 동일합니다.
+### ✅ 컨트롤러
-## 경로 기준
-1. 최단 거리
-2. 최소 시간
-B. 돌아가기
+- [x] 메인화면 출력
+- [x] 기능 선택받기
+- [x] 경로기준 출력
+- [x] 기능 선택받기
+- [x] 출발역 입력받기
+- [x] 도착역 입력받기
+- [x] 경로조회 기능으로 조회결과 받기
+- [x] 조회결과 출력
-## 원하는 기능을 선택하세요.
+### ✅ 입출력
+- [x] 메인화면
+- [x] 경로 기준
+- [x] 원하는 기능을 선택하세요.
+- [x] 출발역 입력
+- [x] 도착역 입력
+- [x] 조회결과 출력
-...
+---
-```
-
-
-
-## 🎱 프로그래밍 요구사항
-- 자바 코드 컨벤션을 지키면서 프로그래밍한다.
- - 기본적으로 [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)을 원칙으로 한다.
- - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다.
-- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
- - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다.
-- 3항 연산자를 쓰지 않는다.
-- 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.
- - 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.
-- else 예약어를 쓰지 않는다.
- - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
- - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.
-- 프로그래밍 요구사항에서 별도로 변경 불가 안내가 없는 경우 파일 수정과 패키지 이동을 자유롭게 할 수 있다.
-- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 `[ERROR]` 로 시작해야 한다.
-
-### 프로그래밍 요구사항 - Application
-- Application 클래스를 활용해 구현해야 한다.
-- Application의 패키지 구조는 변경하지 않는다.
-- Application 클래스에 있는 Scanner를 사용하고 별도의 Scanner 객체를 만들지 않는다.
-```java
-public class Application {
- public static void main(String[] args) {
- final Scanner scanner = new Scanner(System.in);
- ...
- }
-}
-```
-
-### 프로그래밍 요구사항 - Station, Line
-- Station, Line 클래스를 활용하여 지하철역과 노선을 구현해야 한다.
-- 제공하는 각 클래스의 기본 생성자를 추가할 수 없다.
-- 필드(인스턴스 변수)인 name의 접근 제어자 private을 변경할 수 없다.
-- 가능하면 setter 메소드(ex. setXXX)를 추가하지 않고 구현한다.
-
-```java
-public class Station {
- private String name;
-
- public Station(String name) {
- this.name = name;
- }
+## 🔍구현 로직
- public String getName() {
- return name;
- }
+- ### Main diagram
- // 추가 기능 구현
-}
-```
-
-### 프로그래밍 요구사항 - StationRepository, LineRepository
-- Station과 Line의 상태를 저장할 수 있는 StationRepository, LineRepository를 제공한다.
-- 필요 시 StationRepository, LineRepository 이 외 추가로 Repository를 만들 수 있다.
-- 추가로 생성되는 객체에 대해서 XXXRepository 네이밍으로 저장 클래스를 추가한다.
-- 객체들의 상태를 관리하기 위해서 XXXRepository 클래스를 활용해 저장 로직을 구현해야 한다.
-- 작성된 메서드는 수정할 수 없고, 필요에 따라 메서드를 자유롭게 추가할 수 있다.
-
-```java
-public class StationRepository {
- private static final List stations = new ArrayList<>();
-
- public static List stations() {
- return Collections.unmodifiableList(stations);
- }
-
- public static void addStation(Station station) {
- stations.add(station);
- }
-
- public static boolean deleteStation(String name) {
- return stations.removeIf(station -> Objects.equals(station.getName(), name));
- }
-
- public static void deleteAll() {
- stations.clear();
- }
-}
-```
-
-
-
-## ❗️힌트
-### 최단 경로 라이브러리
-- jgrapht 라이브러리를 활용하면 간편하게 최단거리를 조회할 수 있음
-- Dijkstra 알고리즘을 반드시 이해할 필요는 없고 미션에 적용할 정도로만 이해하면 됨
-- JGraphtTest 클래스의 테스트를 활용하여 미션에 필요한 라이브러리의 기능을 학습할 수 있음
-- 정점(vertex)과 간선(edge), 그리고 가중치 개념을 이용
- - 정점: 지하철역
- - 간선: 지하철역 연결정보
- - 가중치: 거리 or 소요 시간
-- 최단 거리 기준 조회 시 가중치를 거리로 설정
-
-```java
-@Test
-public void getDijkstraShortestPath() {
- WeightedMultigraph graph
- = new WeightedMultigraph(DefaultWeightedEdge.class);
- graph.addVertex("v1");
- graph.addVertex("v2");
- graph.addVertex("v3");
- graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2);
- graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2);
- graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100);
-
- DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
- List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList();
-
- assertThat(shortestPath.size()).isEqualTo(3);
-}
-```
-#### 테스트 설명
+- ### Util diagram
-
-- 역 사이의 거리를 고려하지 않는 경우 V1->V3 경로가 최단 경로
-- 역 사이의 거리를 고려할 경우 V1->V3 경로의 거리는 100km, V1->V2->V3 경로의 거리는 4km이므로 최단 경로는 V1->V2->V3
-
+- ### View diagram
-## 📈 진행 요구사항
-- 미션은 [java-subway-path-precourse 저장소](https://github.com/woowacourse/java-subway-path-precourse) 를 fork/clone해 시작한다.
-- 기능을 구현하기 전에 java-subway-path-precourse/docs/README.md 파일에 구현할 기능 목록을 정리해 추가한다.
-- git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가한다.
- - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 참고해 commit log를 남긴다.
-- [프리코스 과제 제출 문서](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 절차를 따라 미션을 제출한다.
- - [프리코스 과제 FAQ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse/faq) 문서를 참고하여 진행할 수 있다.
-
-## 📝 License
-This project is [MIT](https://github.com/woowacourse/java-subway-path-precourse/blob/master/LICENSE.md) licensed.
+---
diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java
index 0bcf786cc..eec10ca3c 100644
--- a/src/main/java/subway/Application.java
+++ b/src/main/java/subway/Application.java
@@ -2,9 +2,11 @@
import java.util.Scanner;
+import subway.Controller.StationsController;
+
public class Application {
- public static void main(String[] args) {
- final Scanner scanner = new Scanner(System.in);
- // TODO: 프로그램 구현
- }
+ public static void main(String[] args) {
+ final Scanner scanner = new Scanner(System.in);
+ new StationsController(scanner);
+ }
}
diff --git a/src/main/java/subway/Controller/Run/Init.java b/src/main/java/subway/Controller/Run/Init.java
new file mode 100644
index 000000000..8179f53fb
--- /dev/null
+++ b/src/main/java/subway/Controller/Run/Init.java
@@ -0,0 +1,60 @@
+package subway.Controller.Run;
+
+import subway.Utils.Constants;
+import subway.domain.Line;
+import subway.domain.LineRepository;
+import subway.domain.Path.DistanceConnectionRepository;
+import subway.domain.Path.TimeConnectionRepository;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+
+public class Init {
+ public static void initiate() {
+ setStationRepository();
+ setLineRepository();
+ setConnectionRepository();
+ setDistanceConnectionRepository();
+ setTimeConnectionRepository();
+ }
+
+ private static void setStationRepository() {
+ for (String s : Constants.STATIONS) {
+ StationRepository.addStation(new Station(s));
+ }
+ DistanceConnectionRepository.addAllVertex();
+ TimeConnectionRepository.addAllVertex();
+ }
+
+ private static void setLineRepository() {
+ for (String s : Constants.LINES) {
+ LineRepository.addLine(new Line(s));
+ }
+ }
+
+ private static void setConnectionRepository() {
+ for (Object[] distances : Constants.DISTANCES) {
+ DistanceConnectionRepository.addConnection(
+ StationRepository.getStation((String)distances[0]),
+ StationRepository.getStation((String)distances[1]),
+ (Integer)distances[2]);
+ }
+ }
+
+ private static void setDistanceConnectionRepository() {
+ for (Object[] distances : Constants.DISTANCES) {
+ DistanceConnectionRepository.addConnection(
+ StationRepository.getStation((String)distances[0]),
+ StationRepository.getStation((String)distances[1]),
+ (Integer)distances[2]);
+ }
+ }
+
+ private static void setTimeConnectionRepository() {
+ for (Object[] times : Constants.TIMES) {
+ TimeConnectionRepository.addConnection(
+ StationRepository.getStation((String)times[0]),
+ StationRepository.getStation((String)times[1]),
+ (Integer)times[2]);
+ }
+ }
+}
diff --git a/src/main/java/subway/Controller/Run/InputController.java b/src/main/java/subway/Controller/Run/InputController.java
new file mode 100644
index 000000000..7193dce21
--- /dev/null
+++ b/src/main/java/subway/Controller/Run/InputController.java
@@ -0,0 +1,60 @@
+package subway.Controller.Run;
+
+import java.util.Scanner;
+
+import subway.Utils.Constants;
+import subway.View.InputView;
+import subway.domain.StationRepository;
+
+public class InputController {
+ public static String getStartStationInput(Scanner scanner) {
+ try {
+ String input = InputView.inputStartStation(scanner);
+ StationRepository.getStation(input);
+ return input;
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ return getStartStationInput(scanner);
+ }
+ }
+
+ public static String getFinishStationInput(Scanner scanner) {
+ try {
+ String input = InputView.inputFinishStation(scanner);
+ StationRepository.getStation(input);
+ return input;
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ return getFinishStationInput(scanner);
+ }
+ }
+
+ public static String getMainInput(Scanner scanner) {
+ try {
+ String input = InputView.inputMain(scanner);
+ if (!input.equals(Constants.MAIN_INPUT_START)
+ && !input.equals(Constants.MAIN_INPUT_QUIT)) {
+ throw new IllegalArgumentException(Constants.ERROR_WRONG_MAIN_INPUT);
+ }
+ return input;
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ return getMainInput(scanner);
+ }
+ }
+
+ public static String getStandardInput(Scanner scanner) {
+ try {
+ String input = InputView.inputStandard(scanner);
+ if (!input.equals(Constants.MAIN_STANDARD_DISTANCE)
+ && !input.equals(Constants.MAIN_STANDARD_TIME)
+ && !input.equals(Constants.MAIN_STANDARD_QUIT)) {
+ throw new IllegalArgumentException(Constants.ERROR_WRONG_STANDARD_INPUT);
+ }
+ return input;
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ return getStandardInput(scanner);
+ }
+ }
+}
diff --git a/src/main/java/subway/Controller/Run/OutputController.java b/src/main/java/subway/Controller/Run/OutputController.java
new file mode 100644
index 000000000..3bfd3051c
--- /dev/null
+++ b/src/main/java/subway/Controller/Run/OutputController.java
@@ -0,0 +1,37 @@
+package subway.Controller.Run;
+
+import java.util.List;
+
+import subway.View.OutputView;
+import subway.domain.Path.DistanceConnectionRepository;
+import subway.domain.Path.TimeConnectionRepository;
+import subway.domain.Station;
+
+public class OutputController {
+ public static void getOutput(List path) {
+ OutputView.printResult();
+ OutputView.printFullDistance(getFullDistance(path));
+ OutputView.printFullTime(getFullTime(path));
+ OutputView.printPath(path);
+ }
+
+ public static int getFullDistance(List path) {
+ int fullDistance = 0;
+ for (int i = 0; i < path.size() - 1; i++) {
+ fullDistance += DistanceConnectionRepository.findDistance(
+ path.get(i), path.get(i + 1)
+ );
+ }
+ return fullDistance;
+ }
+
+ public static int getFullTime(List path) {
+ int fullTime = 0;
+ for (int i = 0; i < path.size() - 1; i++) {
+ fullTime += TimeConnectionRepository.findTime(
+ path.get(i), path.get(i + 1)
+ );
+ }
+ return fullTime;
+ }
+}
diff --git a/src/main/java/subway/Controller/StationsController.java b/src/main/java/subway/Controller/StationsController.java
new file mode 100644
index 000000000..e162336d3
--- /dev/null
+++ b/src/main/java/subway/Controller/StationsController.java
@@ -0,0 +1,70 @@
+package subway.Controller;
+
+import java.util.List;
+import java.util.Scanner;
+
+import subway.Controller.Run.Init;
+import subway.Controller.Run.InputController;
+import subway.Controller.Run.OutputController;
+import subway.Utils.Constants;
+import subway.domain.Path.ShortestPath;
+import subway.domain.Station;
+
+public class StationsController {
+ private final Scanner scanner;
+ private List path = null;
+
+ public StationsController(Scanner scanner) {
+ this.scanner = scanner;
+ start();
+ }
+
+ public void start() {
+ Init.initiate();
+ mainInput();
+
+ boolean go = pathInput();
+ if (!go) {
+ return;
+ }
+ OutputController.getOutput(path);
+ start();
+ }
+
+ private void mainInput() {
+ String input = InputController.getMainInput(scanner);
+ if (input.equals(Constants.MAIN_INPUT_QUIT)) {
+ System.exit(0);
+ }
+ }
+
+ private boolean pathInput() {
+ String input = InputController.getStandardInput(scanner);
+ if (input.equals(Constants.MAIN_STANDARD_QUIT)) {
+ start();
+ return false;
+ }
+
+ String start = InputController.getStartStationInput(scanner);
+ String finish = InputController.getFinishStationInput(scanner);
+
+ try {
+ path = getPath(input, start, finish);
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ return pathInput();
+ }
+ return true;
+ }
+
+ public List getPath(String input, String start, String finish) {
+ List path = null;
+ if (input.equals(Constants.MAIN_STANDARD_DISTANCE)) {
+ path = new ShortestPath(start, finish).getDistancePath();
+ }
+ if (input.equals(Constants.MAIN_STANDARD_TIME)) {
+ path = new ShortestPath(start, finish).getTimePath();
+ }
+ return path;
+ }
+}
diff --git a/src/main/java/subway/Utils/Constants.java b/src/main/java/subway/Utils/Constants.java
new file mode 100644
index 000000000..8e637dee8
--- /dev/null
+++ b/src/main/java/subway/Utils/Constants.java
@@ -0,0 +1,42 @@
+package subway.Utils;
+
+public class Constants {
+ public static final String[] STATIONS = {"교대역", "강남역", "역삼역", "남부터미널역", "양재역", "양재시민의숲역", "매봉역"};
+ public static final String[] LINES = {"2호선", "3호선", "신분당선"};
+
+ public static final Object[][] DISTANCES = new Object[][] {
+ {"교대역", "강남역", 2},
+ {"강남역", "역삼역", 2},
+ {"교대역", "남부터미널역", 3},
+ {"남부터미널역", "양재역", 6},
+ {"양재역", "매봉역", 1},
+ {"강남역", "양재역", 2},
+ {"양재역", "양재시민의숲역", 10}
+
+ };
+ public static final Object[][] TIMES = new Object[][] {
+ {"교대역", "강남역", 3},
+ {"강남역", "역삼역", 3},
+ {"교대역", "남부터미널역", 2},
+ {"남부터미널역", "양재역", 5},
+ {"양재역", "매봉역", 1},
+ {"강남역", "양재역", 8},
+ {"양재역", "양재시민의숲역", 3}
+
+ };
+
+ public static final String ERROR = "\n[ERROR] ";
+ public static final String ERROR_SAME_NAME = ERROR + "출발역과 도착역이 동일합니다.";
+ public static final String ERROR_WRONG_MAIN_INPUT = ERROR + "1 혹은 Q를 입력하시오.\n";
+ public static final String ERROR_WRONG_STANDARD_INPUT = ERROR + "1,2 혹은 B를 입력하시오.";
+ public static final String ERROR_NOT_CONNECTED = ERROR + "두 노선은 연결되어있지 않습니다.";
+ public static final String ERROR_NAME_NOT_FOUNDED = ERROR + "해당 이름을 찾을 수 없습니다.";
+
+ public static final String MAIN_INPUT_START = "1";
+ public static final String MAIN_INPUT_QUIT = "Q";
+
+ public static final String MAIN_STANDARD_DISTANCE = "1";
+ public static final String MAIN_STANDARD_TIME = "2";
+ public static final String MAIN_STANDARD_QUIT = "B";
+
+}
diff --git a/src/main/java/subway/Utils/Validator/PathValidator.java b/src/main/java/subway/Utils/Validator/PathValidator.java
new file mode 100644
index 000000000..f7a8330de
--- /dev/null
+++ b/src/main/java/subway/Utils/Validator/PathValidator.java
@@ -0,0 +1,31 @@
+package subway.Utils.Validator;
+
+import subway.Utils.Constants;
+import subway.domain.StationRepository;
+
+public class PathValidator {
+ private final String name1;
+ private final String name2;
+
+ public PathValidator(String name1, String name2) {
+ this.name1 = name1;
+ this.name2 = name2;
+ validate();
+ }
+
+ private void validate() {
+ isStation(name1);
+ isStation(name2);
+ isSameName();
+ }
+
+ private void isStation(String name) {
+ StationRepository.getStation(name);
+ }
+
+ private void isSameName() {
+ if (name1.equals(name2)) {
+ throw new IllegalArgumentException(Constants.ERROR_SAME_NAME);
+ }
+ }
+}
diff --git a/src/main/java/subway/View/InputView.java b/src/main/java/subway/View/InputView.java
new file mode 100644
index 000000000..4533d88fe
--- /dev/null
+++ b/src/main/java/subway/View/InputView.java
@@ -0,0 +1,33 @@
+package subway.View;
+
+import java.util.Scanner;
+
+public class InputView {
+ public static String inputMain(Scanner scanner) {
+ System.out.println("## 메인 화면");
+ System.out.println("1. 경로 조회");
+ System.out.println("Q. 종료\n");
+ System.out.println("## 원하는 기능을 선택하세요.");
+ return scanner.nextLine();
+ }
+
+ public static String inputStandard(Scanner scanner) {
+ System.out.println("\n## 경로 기준");
+ System.out.println("1. 최단 거리");
+ System.out.println("2. 최소 시간");
+ System.out.println("B. 돌아가기");
+
+ System.out.println("\n## 원하는 기능을 선택하세요.");
+ return scanner.nextLine();
+ }
+
+ public static String inputStartStation(Scanner scanner) {
+ System.out.println("\n## 출발역을 입력하세요.");
+ return scanner.nextLine();
+ }
+
+ public static String inputFinishStation(Scanner scanner) {
+ System.out.println("\n## 도착역을 입력하세요.");
+ return scanner.nextLine();
+ }
+}
diff --git a/src/main/java/subway/View/OutputView.java b/src/main/java/subway/View/OutputView.java
new file mode 100644
index 000000000..42f4c5244
--- /dev/null
+++ b/src/main/java/subway/View/OutputView.java
@@ -0,0 +1,24 @@
+package subway.View;
+
+import java.util.List;
+import subway.domain.Station;
+
+public class OutputView {
+ public static void printResult() {
+ System.out.println("\n## 조회 결과");
+ System.out.println("[INFO] ---");
+ }
+ public static void printPath(List path) {
+ path.forEach(station -> System.out.println("[INFO] " + station.getName()));
+ System.out.println();
+ }
+
+ public static void printFullDistance(int fullDistance) {
+ System.out.printf("[INFO] 총 거리: %dkm\n", fullDistance);
+ }
+
+ public static void printFullTime(int fullTime) {
+ System.out.printf("[INFO] 총 소요 시간: %d분\n",fullTime);
+ System.out.println("[INFO] ---");
+ }
+}
diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java
index 2c4a723c9..82c081bf9 100644
--- a/src/main/java/subway/domain/LineRepository.java
+++ b/src/main/java/subway/domain/LineRepository.java
@@ -6,21 +6,21 @@
import java.util.Objects;
public class LineRepository {
- private static final List lines = new ArrayList<>();
+ private static final List lines = new ArrayList<>();
- public static List lines() {
- return Collections.unmodifiableList(lines);
- }
+ public static List lines() {
+ return Collections.unmodifiableList(lines);
+ }
- public static void addLine(Line line) {
- lines.add(line);
- }
+ public static void addLine(Line line) {
+ lines.add(line);
+ }
- public static boolean deleteLineByName(String name) {
- return lines.removeIf(line -> Objects.equals(line.getName(), name));
- }
+ public static boolean deleteLineByName(String name) {
+ return lines.removeIf(line -> Objects.equals(line.getName(), name));
+ }
- public static void deleteAll() {
- lines.clear();
- }
+ public static void deleteAll() {
+ lines.clear();
+ }
}
diff --git a/src/main/java/subway/domain/Path/DistanceConnectionRepository.java b/src/main/java/subway/domain/Path/DistanceConnectionRepository.java
new file mode 100644
index 000000000..ff3a29429
--- /dev/null
+++ b/src/main/java/subway/domain/Path/DistanceConnectionRepository.java
@@ -0,0 +1,45 @@
+package subway.domain.Path;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import subway.Utils.Constants;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+
+public class DistanceConnectionRepository {
+ private static final WeightedMultigraph connections = new WeightedMultigraph<>(
+ DefaultWeightedEdge.class);
+
+ public static WeightedMultigraph connections() {
+ return connections;
+ }
+
+ public static void addStation(Station station) {
+ connections.addVertex(station);
+ }
+
+ public static void addConnection(Station station1, Station station2, int weight) {
+ connections.setEdgeWeight(connections.addEdge(station1, station2), weight);
+ }
+
+ public static void addAllVertex() {
+ StationRepository.stations()
+ .forEach(
+ DistanceConnectionRepository::addStation
+ );
+ }
+
+ public static int findDistance(Station station1, Station station2) {
+ for (Object[] connection : Constants.DISTANCES) {
+ ArrayList stations = new ArrayList(Arrays.asList(connection));
+ if (stations.contains(station1.getName()) && stations.contains(station2.getName())) {
+ return (int)connection[2];
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/subway/domain/Path/ShortestPath.java b/src/main/java/subway/domain/Path/ShortestPath.java
new file mode 100644
index 000000000..ee10c4ca7
--- /dev/null
+++ b/src/main/java/subway/domain/Path/ShortestPath.java
@@ -0,0 +1,54 @@
+package subway.domain.Path;
+
+import java.util.List;
+
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+
+import subway.Utils.Constants;
+import subway.Utils.Validator.PathValidator;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+
+public class ShortestPath {
+ private List path;
+ private final String name1;
+ private final String name2;
+
+ public ShortestPath(String name1, String name2) {
+ this.name1 = name1;
+ this.name2 = name2;
+ new PathValidator(name1, name2);
+ }
+
+ public List getDistancePath() {
+ makeDistancePath();
+ if (path.isEmpty()) {
+ throw new IllegalArgumentException(Constants.ERROR_NOT_CONNECTED);
+ }
+ return path;
+ }
+
+ public List getTimePath() {
+ makeTimePath();
+ if (path.isEmpty()) {
+ throw new IllegalArgumentException(Constants.ERROR_NOT_CONNECTED);
+ }
+ return path;
+ }
+
+ private void makeTimePath() {
+ path = new DijkstraShortestPath(TimeConnectionRepository.connections())
+ .getPath(
+ StationRepository.getStation(name1),
+ StationRepository.getStation(name2)
+ ).getVertexList();
+ }
+
+ private void makeDistancePath() {
+ path = new DijkstraShortestPath(DistanceConnectionRepository.connections())
+ .getPath(
+ StationRepository.getStation(name1),
+ StationRepository.getStation(name2)
+ ).getVertexList();
+ }
+}
diff --git a/src/main/java/subway/domain/Path/TimeConnectionRepository.java b/src/main/java/subway/domain/Path/TimeConnectionRepository.java
new file mode 100644
index 000000000..5d2b8885a
--- /dev/null
+++ b/src/main/java/subway/domain/Path/TimeConnectionRepository.java
@@ -0,0 +1,45 @@
+package subway.domain.Path;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import subway.Utils.Constants;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+
+public class TimeConnectionRepository {
+ private static final WeightedMultigraph connections = new WeightedMultigraph<>(
+ DefaultWeightedEdge.class);
+
+ public static WeightedMultigraph connections() {
+ return connections;
+ }
+
+ public static void addStation(Station station) {
+ connections.addVertex(station);
+ }
+
+ public static void addConnection(Station station1, Station station2, int weight) {
+ connections.setEdgeWeight(connections.addEdge(station1, station2), weight);
+ }
+
+ public static void addAllVertex() {
+ StationRepository.stations()
+ .forEach(
+ TimeConnectionRepository::addStation
+ );
+ }
+
+ public static int findTime(Station station1, Station station2) {
+ for (Object[] connection : Constants.TIMES) {
+ ArrayList stations = new ArrayList(Arrays.asList(connection));
+ if (stations.contains(station1.getName()) && stations.contains(station2.getName())) {
+ return (int)connection[2];
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java
index 8ed9d103f..4a916d448 100644
--- a/src/main/java/subway/domain/StationRepository.java
+++ b/src/main/java/subway/domain/StationRepository.java
@@ -5,22 +5,33 @@
import java.util.List;
import java.util.Objects;
+import subway.Utils.Constants;
+
public class StationRepository {
- private static final List stations = new ArrayList<>();
+ private static final List stations = new ArrayList<>();
+
+ public static List stations() {
+ return Collections.unmodifiableList(stations);
+ }
- public static List stations() {
- return Collections.unmodifiableList(stations);
- }
+ public static void addStation(Station station) {
+ stations.add(station);
+ }
- public static void addStation(Station station) {
- stations.add(station);
- }
+ public static boolean deleteStation(String name) {
+ return stations.removeIf(station -> Objects.equals(station.getName(), name));
+ }
- public static boolean deleteStation(String name) {
- return stations.removeIf(station -> Objects.equals(station.getName(), name));
- }
+ public static void deleteAll() {
+ stations.clear();
+ }
- public static void deleteAll() {
- stations.clear();
- }
+ public static Station getStation(String name) {
+ for (Station station : stations) {
+ if (station.getName().equals(name)) {
+ return station;
+ }
+ }
+ throw new IllegalArgumentException(Constants.ERROR_NAME_NOT_FOUNDED);
+ }
}
diff --git a/src/test/java/subway/JGraphtTest.java b/src/test/java/subway/JGraphtTest.java
index 4f5f76536..c07e3d94c 100644
--- a/src/test/java/subway/JGraphtTest.java
+++ b/src/test/java/subway/JGraphtTest.java
@@ -10,19 +10,19 @@
import static org.assertj.core.api.Assertions.assertThat;
public class JGraphtTest {
- @Test
- public void getDijkstraShortestPath() {
- WeightedMultigraph graph = new WeightedMultigraph(DefaultWeightedEdge.class);
- graph.addVertex("v1");
- graph.addVertex("v2");
- graph.addVertex("v3");
- graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2);
- graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2);
- graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100);
+ @Test
+ public void getDijkstraShortestPath() {
+ WeightedMultigraph graph = new WeightedMultigraph(DefaultWeightedEdge.class);
+ graph.addVertex("v1");
+ graph.addVertex("v2");
+ graph.addVertex("v3");
+ graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2);
+ graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2);
+ graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100);
- DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
- List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList();
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
+ List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList();
- assertThat(shortestPath.size()).isEqualTo(3);
- }
+ assertThat(shortestPath.size()).isEqualTo(3);
+ }
}
diff --git a/src/test/java/subway/MainTest.java b/src/test/java/subway/MainTest.java
new file mode 100644
index 000000000..6579de275
--- /dev/null
+++ b/src/test/java/subway/MainTest.java
@@ -0,0 +1,10 @@
+package subway;
+
+import org.junit.jupiter.api.Test;
+
+public class MainTest {
+ @Test
+ public void afs() {
+
+ }
+}