diff --git a/README.md b/README.md
index d6299154c..d50ab8feb 100644
--- a/README.md
+++ b/README.md
@@ -1,253 +1,33 @@
# 지하철 노선도 경로 조회 미션
- 등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다.
-
-
-## 🚀 기능 요구사항
-
-> 프리코스 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
-
-## 출발역을 입력하세요.
-교대역
-
-## 도착역을 입력하세요.
-양재역
-
-## 조회 결과
-[INFO] ---
-[INFO] 총 거리: 6km
-[INFO] 총 소요 시간: 14분
-[INFO] ---
-[INFO] 교대역
-[INFO] 강남역
-[INFO] 양재역
-
-## 메인 화면
-1. 경로 조회
-Q. 종료
-
-...
-```
-
-#### 에러 출력 예시
-
-```
-## 메인 화면
-1. 경로 조회
-Q. 종료
-
-## 원하는 기능을 선택하세요.
-1
-
-## 경로 기준
-1. 최단 거리
-2. 최소 시간
-B. 돌아가기
-
-## 원하는 기능을 선택하세요.
-1
-
-## 출발역을 입력하세요.
-강남역
-
-## 도착역을 입력하세요.
-강남역
-
-[ERROR] 출발역과 도착역이 동일합니다.
-
-## 경로 기준
-1. 최단 거리
-2. 최소 시간
-B. 돌아가기
-
-## 원하는 기능을 선택하세요.
-
-...
-
-```
-
-
-
-## 🎱 프로그래밍 요구사항
-- 자바 코드 컨벤션을 지키면서 프로그래밍한다.
- - 기본적으로 [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;
- }
-
- // 추가 기능 구현
-}
-
-```
-
-### 프로그래밍 요구사항 - 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);
-}
-```
-
-#### 테스트 설명
-
-
-
-- 역 사이의 거리를 고려하지 않는 경우 V1->V3 경로가 최단 경로
-- 역 사이의 거리를 고려할 경우 V1->V3 경로의 거리는 100km, V1->V2->V3 경로의 거리는 4km이므로 최단 경로는 V1->V2->V3
-
-
-
-## 📈 진행 요구사항
-- 미션은 [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.
+## 초기 설정
+ - 프로그램 시작 시 역, 노선, 구간 정보를 설정
+ - 거리와 소요 시간은 양의 정수(단위는 km와 분)
+ - 2호선: 교대역 - ( 2km / 3분 ) - 강남역 - ( 2km / 3분 ) - 역삼역
+ - 3호선: 교대역 - ( 3km / 2분 ) - 남부터미널역 - ( 6km / 5분 ) - 양재역 - ( 1km / 1분 ) - 매봉역
+ - 신분당선: 강남역 - ( 2km / 8분 ) - 양재역 - ( 10km / 3분 ) - 양재시민의숲역
+
+## 경로 조회 기능
+ - 출발역과 도착역을 입력받아 경로를 조회한다.
+ - 경로 조회 시 총 거리, 총 소요 시간도 함께 출력한다.
+ - 경로 조회 기준은 '최단 거리' '최소 시간'
+
+## 구현기능 목록
+ - 구간의 정보(역과 역을 연결하고 거리와 시간정보)을 가지는 Section 클래스 추가
+ - 구간의 정보를 저장하는 Repository 추가
+ - 노선 안에 구간을 추가하는 기능 추가
+ - 역 안에 구간의 정보(Section)를 담는 기능 추가
+ - 초기 설정값 세팅하는 기능 추가
+ - 메인메뉴 view 화면 추가
+ - 경로 조회 메뉴 view 화면 추가
+ - 출발역과 도착역을 입력받는 기능을 추가
+ - 경로를 어느 기준으로 선택할지 보는 화면 추가
+ - 최단 거리를 기준으로 조회하는 기능 추가
+ - 최소 시간 기준으로 조회하는 기능 추가
+
+
+## 고려할 사항
+ - 이동은 양측방향이 다 가능함
+ - 환승은 허용됨
+ - 역이 이어져 있는지 어떻게 증명할것인가
diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java
index 0bcf786cc..5a4f7f105 100644
--- a/src/main/java/subway/Application.java
+++ b/src/main/java/subway/Application.java
@@ -1,10 +1,15 @@
package subway;
+import subway.util.DefaultSetting;
+import subway.view.MainMenu;
+
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
+ DefaultSetting.defaultSetting();
+ new MainMenu(scanner).startMainMENU();
}
}
diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java
index f4d738d5a..feeccfeaf 100644
--- a/src/main/java/subway/domain/Line.java
+++ b/src/main/java/subway/domain/Line.java
@@ -1,5 +1,10 @@
package subway.domain;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
public class Line {
private String name;
@@ -12,4 +17,20 @@ public String getName() {
}
// 추가 기능 구현
+
+ private List stationList = new ArrayList<>();
+
+ public List stations() {
+ return Collections.unmodifiableList(stationList);
+ }
+
+ public void addStation(String stationName) {
+ Station station = StationRepository.findStationByName(stationName);
+ station.addLine(this.name);
+ stationList.add(station);
+ }
+
+ public boolean deleteStation(String name) {
+ return stationList.removeIf(station -> station.getName().equals(name));
+ }
}
diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java
index 2c4a723c9..c3f66e140 100644
--- a/src/main/java/subway/domain/LineRepository.java
+++ b/src/main/java/subway/domain/LineRepository.java
@@ -20,7 +20,12 @@ public static boolean deleteLineByName(String name) {
return lines.removeIf(line -> Objects.equals(line.getName(), name));
}
- public static void deleteAll() {
- lines.clear();
+ public static Line findLineByName(String lineName) {
+ for (Line line : lines) {
+ if (line.getName().equals(lineName)) {
+ return line;
+ }
+ }
+ return null;
}
}
diff --git a/src/main/java/subway/domain/Section.java b/src/main/java/subway/domain/Section.java
new file mode 100644
index 000000000..51c65cd01
--- /dev/null
+++ b/src/main/java/subway/domain/Section.java
@@ -0,0 +1,25 @@
+package subway.domain;
+
+public class Section {
+ private String linkedStationName;
+ private int distance;
+ private int time;
+
+ public Section(String linkedStationName, int distance, int time) {
+ this.linkedStationName = linkedStationName;
+ this.distance = distance;
+ this.time = time;
+ }
+
+ public String getLinkedStationName() {
+ return linkedStationName;
+ }
+
+ public int getDistance() {
+ return distance;
+ }
+
+ public int getTime() {
+ return time;
+ }
+}
diff --git a/src/main/java/subway/domain/SectionRepository.java b/src/main/java/subway/domain/SectionRepository.java
new file mode 100644
index 000000000..b7493856c
--- /dev/null
+++ b/src/main/java/subway/domain/SectionRepository.java
@@ -0,0 +1,26 @@
+package subway.domain;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+public class SectionRepository {
+ private static final List sections = new ArrayList<>();
+
+ public static List sections() {
+ return Collections.unmodifiableList(sections);
+ }
+
+ public static void addSetion(Section section) {
+ sections.add(section);
+ }
+
+ public static boolean deleteSectionByName(String name) {
+ return sections.removeIf(line -> Objects.equals(line.getLinkedStationName(), name));
+ }
+
+ public static void deleteAll() {
+ sections.clear();
+ }
+}
diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java
index bdb142590..c6022790c 100644
--- a/src/main/java/subway/domain/Station.java
+++ b/src/main/java/subway/domain/Station.java
@@ -1,5 +1,9 @@
package subway.domain;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
public class Station {
private String name;
@@ -12,4 +16,42 @@ public String getName() {
}
// 추가 기능 구현
+ private List lineList = new ArrayList<>();
+
+ public void addLine(String lineName) {
+ lineList.add(lineName);
+ }
+
+ public boolean includedLine(String lineName) {
+ return lineList.contains(lineName);
+ }
+
+ private List sectionList = new ArrayList<>();
+
+ public Station addSection(String linkedStationName, int distance, int time) {
+ sectionList.add(new Section(linkedStationName, distance, time));
+ return this;
+ }
+
+ public List sections() {
+ return Collections.unmodifiableList(sectionList);
+ }
+
+ public int getSectionDistance(String stationName) {
+ for (Section section : sectionList) {
+ if (section.getLinkedStationName().equals(stationName)) {
+ return section.getDistance();
+ }
+ }
+ return 0;
+ }
+
+ public int getSectionTime(String stationName) {
+ for (Section section : sectionList) {
+ if (section.getLinkedStationName().equals(stationName)) {
+ return section.getTime();
+ }
+ }
+ return 0;
+ }
}
diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java
index 8ed9d103f..ae0194700 100644
--- a/src/main/java/subway/domain/StationRepository.java
+++ b/src/main/java/subway/domain/StationRepository.java
@@ -1,5 +1,8 @@
package subway.domain;
+import subway.util.DistanceRouteSearch;
+import subway.util.TimeRouteSearch;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -14,6 +17,8 @@ public static List stations() {
public static void addStation(Station station) {
stations.add(station);
+ DistanceRouteSearch.addVertex(station.getName());
+ TimeRouteSearch.addVertex(station.getName());
}
public static boolean deleteStation(String name) {
@@ -23,4 +28,13 @@ public static boolean deleteStation(String name) {
public static void deleteAll() {
stations.clear();
}
+
+ public static Station findStationByName(String name) {
+ for (Station station : stations()) {
+ if (station.getName().equals(name)) {
+ return station;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/main/java/subway/service/RouteSearchService.java b/src/main/java/subway/service/RouteSearchService.java
new file mode 100644
index 000000000..fdccc4ba7
--- /dev/null
+++ b/src/main/java/subway/service/RouteSearchService.java
@@ -0,0 +1,4 @@
+package subway.service;
+
+public class RouteSearchService {
+}
diff --git a/src/main/java/subway/util/CalculatorRoute.java b/src/main/java/subway/util/CalculatorRoute.java
new file mode 100644
index 000000000..7096887d4
--- /dev/null
+++ b/src/main/java/subway/util/CalculatorRoute.java
@@ -0,0 +1,31 @@
+package subway.util;
+
+import subway.domain.Station;
+import subway.domain.StationRepository;
+
+import java.util.List;
+
+public class CalculatorRoute {
+
+ public static int calculatorRoutDistance(List stationList) {
+ int result = 0;
+ String tempStataion = stationList.get(0);
+ for (int i = 1; i < stationList.size(); i++) {
+ Station station = StationRepository.findStationByName(tempStataion);
+ result += station.getSectionDistance(stationList.get(i));
+ tempStataion = stationList.get(i);
+ }
+ return result;
+ }
+
+ public static int calculatorRouteTime(List stationList) {
+ int result = 0;
+ String tempStataion = stationList.get(0);
+ for (int i = 1; i < stationList.size(); i++) {
+ Station station = StationRepository.findStationByName(tempStataion);
+ result += station.getSectionTime(stationList.get(i));
+ tempStataion = stationList.get(i);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/subway/util/DefaultSetting.java b/src/main/java/subway/util/DefaultSetting.java
new file mode 100644
index 000000000..387479395
--- /dev/null
+++ b/src/main/java/subway/util/DefaultSetting.java
@@ -0,0 +1,85 @@
+package subway.util;
+
+import subway.domain.Line;
+import subway.domain.LineRepository;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+import subway.util.enums.DefaultLines;
+import subway.util.enums.DefaultStations;
+
+public class DefaultSetting {
+ private static final String KYODAE = "교대역";
+ private static final String GANGNAM = "강남역";
+ private static final String YEOKSAM = "역삼역";
+ private static final String NORTH_TERMINAL = "남부터미널역";
+ private static final String YANGJAE = "양재역";
+ private static final String YANGJAE_CITIZEN_FOREST = "양재시민의숲역";
+ private static final String MAEBONG = "매봉역";
+ private static final String LINE2 = "2호선";
+ private static final String LINE3 = "3호선";
+ private static final String SINBUNDANG_LINE = "신분당선";
+
+ public static void defaultSetting() {
+ for (DefaultStations ds : DefaultStations.values()) {
+ StationRepository.addStation(new Station(ds.getName()));
+ }
+
+ for (DefaultLines dl : DefaultLines.values()) {
+ LineRepository.addLine(new Line(dl.getName()));
+ }
+
+ Line line2 = LineRepository.findLineByName(LINE2);
+ line2.addStation(KYODAE);
+ line2.addStation(GANGNAM);
+ line2.addStation(YEOKSAM);
+
+ Line line3 = LineRepository.findLineByName(LINE3);
+ line3.addStation(KYODAE);
+ line3.addStation(NORTH_TERMINAL);
+ line3.addStation(YANGJAE);
+ line3.addStation(MAEBONG);
+
+ Line sinBunDang = LineRepository.findLineByName(SINBUNDANG_LINE);
+ sinBunDang.addStation(GANGNAM);
+ sinBunDang.addStation(YANGJAE);
+ sinBunDang.addStation(YANGJAE_CITIZEN_FOREST);
+
+ StationRepository.findStationByName(KYODAE)
+ .addSection(GANGNAM, 2, 3)
+ .addSection(DefaultStations.NORTH_TERMINAL.getName(), 3, 2);
+ StationRepository.findStationByName(GANGNAM)
+ .addSection(KYODAE, 2, 3)
+ .addSection(YEOKSAM, 2, 3)
+ .addSection(YANGJAE, 2, 8);
+ StationRepository.findStationByName(YEOKSAM)
+ .addSection(GANGNAM, 2, 3);
+ StationRepository.findStationByName(NORTH_TERMINAL)
+ .addSection(KYODAE, 3, 2)
+ .addSection(YANGJAE, 6, 5);
+ StationRepository.findStationByName(YANGJAE)
+ .addSection(NORTH_TERMINAL, 6, 5)
+ .addSection(MAEBONG, 1, 1)
+ .addSection(GANGNAM, 2, 8)
+ .addSection(YANGJAE_CITIZEN_FOREST, 10, 3);
+ StationRepository.findStationByName(MAEBONG)
+ .addSection(YANGJAE, 1, 1);
+ StationRepository.findStationByName(YANGJAE_CITIZEN_FOREST)
+ .addSection(YANGJAE, 10, 3);
+
+ DistanceRouteSearch.addDistanceEdgeWeight(KYODAE, GANGNAM, 2);
+ DistanceRouteSearch.addDistanceEdgeWeight(GANGNAM, YEOKSAM, 2);
+ DistanceRouteSearch.addDistanceEdgeWeight(KYODAE, NORTH_TERMINAL, 3);
+ DistanceRouteSearch.addDistanceEdgeWeight(NORTH_TERMINAL, YANGJAE, 6);
+ DistanceRouteSearch.addDistanceEdgeWeight(YANGJAE, MAEBONG, 1);
+ DistanceRouteSearch.addDistanceEdgeWeight(GANGNAM, YANGJAE, 2);
+ DistanceRouteSearch.addDistanceEdgeWeight(YANGJAE, YANGJAE_CITIZEN_FOREST, 10);
+
+ TimeRouteSearch.addDistanceEdgeWeight(KYODAE, GANGNAM, 3);
+ TimeRouteSearch.addDistanceEdgeWeight(GANGNAM, YEOKSAM, 3);
+ TimeRouteSearch.addDistanceEdgeWeight(KYODAE, NORTH_TERMINAL, 2);
+ TimeRouteSearch.addDistanceEdgeWeight(NORTH_TERMINAL, YANGJAE, 5);
+ TimeRouteSearch.addDistanceEdgeWeight(YANGJAE, MAEBONG, 1);
+ TimeRouteSearch.addDistanceEdgeWeight(GANGNAM, YANGJAE, 8);
+ TimeRouteSearch.addDistanceEdgeWeight(YANGJAE, YANGJAE_CITIZEN_FOREST, 3);
+ }
+}
diff --git a/src/main/java/subway/util/DistanceRouteSearch.java b/src/main/java/subway/util/DistanceRouteSearch.java
new file mode 100644
index 000000000..8e92cfa31
--- /dev/null
+++ b/src/main/java/subway/util/DistanceRouteSearch.java
@@ -0,0 +1,25 @@
+package subway.util;
+
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import java.util.List;
+
+public class DistanceRouteSearch {
+ private static final WeightedMultigraph distanceGraph
+ = new WeightedMultigraph<>(DefaultWeightedEdge.class);
+
+ public static void addVertex(String stationName) {
+ distanceGraph.addVertex(stationName);
+ }
+
+ public static void addDistanceEdgeWeight(String station1, String station2, int distance) {
+ distanceGraph.setEdgeWeight(distanceGraph.addEdge(station1, station2), distance);
+ }
+
+ public static List getShortestRoute(String startStation, String arrivalStation) {
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(distanceGraph);
+ return dijkstraShortestPath.getPath(startStation, arrivalStation).getVertexList();
+ }
+}
diff --git a/src/main/java/subway/util/TimeRouteSearch.java b/src/main/java/subway/util/TimeRouteSearch.java
new file mode 100644
index 000000000..76c8a48de
--- /dev/null
+++ b/src/main/java/subway/util/TimeRouteSearch.java
@@ -0,0 +1,25 @@
+package subway.util;
+
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import java.util.List;
+
+public class TimeRouteSearch {
+ private static final WeightedMultigraph timeGraph
+ = new WeightedMultigraph<>(DefaultWeightedEdge.class);
+
+ public static void addVertex(String stationName) {
+ timeGraph.addVertex(stationName);
+ }
+
+ public static void addDistanceEdgeWeight(String station1, String station2, int distance) {
+ timeGraph.setEdgeWeight(timeGraph.addEdge(station1, station2), distance);
+ }
+
+ public static List getShortestRoute(String startStation, String arrivalStation) {
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(timeGraph);
+ return dijkstraShortestPath.getPath(startStation, arrivalStation).getVertexList();
+ }
+}
diff --git a/src/main/java/subway/util/enums/DefaultLines.java b/src/main/java/subway/util/enums/DefaultLines.java
new file mode 100644
index 000000000..e1bf14376
--- /dev/null
+++ b/src/main/java/subway/util/enums/DefaultLines.java
@@ -0,0 +1,17 @@
+package subway.util.enums;
+
+public enum DefaultLines {
+ LINE2("2호선"),
+ LINE3("3호선"),
+ SINBUNDANG_LINE("신분당선");
+
+ private String name;
+
+ private DefaultLines(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/subway/util/enums/DefaultStations.java b/src/main/java/subway/util/enums/DefaultStations.java
new file mode 100644
index 000000000..e5eedc533
--- /dev/null
+++ b/src/main/java/subway/util/enums/DefaultStations.java
@@ -0,0 +1,21 @@
+package subway.util.enums;
+
+public enum DefaultStations {
+ KYODAE("교대역"),
+ GANGNAM("강남역"),
+ YEOKSAM("역삼역"),
+ NORTH_TERMINAL("남부터미널역"),
+ YANGJAE("양재역"),
+ YANGJAE_CITIZEN_FOREST("양재시민의숲역"),
+ MAEBONG("매봉역");
+
+ private String name;
+
+ DefaultStations(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/subway/util/validator/MenuValidator.java b/src/main/java/subway/util/validator/MenuValidator.java
new file mode 100644
index 000000000..2959cc417
--- /dev/null
+++ b/src/main/java/subway/util/validator/MenuValidator.java
@@ -0,0 +1,24 @@
+package subway.util.validator;
+
+public class MenuValidator {
+ private static final String ERROR = "[ ERROR ] ";
+ private static final String MENU_ERROR = "존재하지않는 메뉴입니다.";
+
+ public static boolean isVailableMainMenu(String input) {
+ if (input.equals("1") || input.equals("Q")) {
+ return true;
+ }
+ System.out.println(ERROR + MENU_ERROR);
+ System.out.println();
+ return false;
+ }
+
+ public static boolean isVailableRouteSearchMenu(String input) {
+ if (input.equals("1") || input.equals("2") || input.equals("B")) {
+ return true;
+ }
+ System.out.println(ERROR + MENU_ERROR);
+ System.out.println();
+ return false;
+ }
+}
diff --git a/src/main/java/subway/util/validator/StationValidator.java b/src/main/java/subway/util/validator/StationValidator.java
new file mode 100644
index 000000000..d9f024d0b
--- /dev/null
+++ b/src/main/java/subway/util/validator/StationValidator.java
@@ -0,0 +1,42 @@
+package subway.util.validator;
+
+import subway.domain.StationRepository;
+
+public class StationValidator {
+ private static final String ERROR = "[ERROR] ";
+ private static final String DUPLICATE_MESSAGE = "출발역과 도착역이 동일합니다.";
+ private static final String AVAILABLE_STATION_MESSAGE = "연결되어있지 않은 역입니다.";
+ private static final String NONEEXIST_STATION = "존재하지 않는 역입니다.";
+
+ public static boolean checkVailableArrivalStation(String startStation, String arrivalStation) {
+ return isLinkedStation(startStation, arrivalStation) && ! duplicateStation(startStation, arrivalStation);
+
+ }
+
+ public static boolean haveStation(String name) {
+ if (StationRepository.findStationByName(name) != null) {
+ return true;
+ }
+ System.out.println(ERROR + NONEEXIST_STATION);
+ System.out.println();
+ return false;
+ }
+
+ public static boolean isLinkedStation(String startStation, String arrivalStation) {
+ if (StationRepository.findStationByName(arrivalStation) != null) {
+ return true;
+ }
+ System.out.println(ERROR + AVAILABLE_STATION_MESSAGE);
+ System.out.println();
+ return false;
+ }
+
+ public static boolean duplicateStation(String startStation, String arrivalStation) {
+ if (startStation.equals(arrivalStation)) {
+ System.out.println(ERROR + DUPLICATE_MESSAGE);
+ System.out.println();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/subway/view/MainMenu.java b/src/main/java/subway/view/MainMenu.java
new file mode 100644
index 000000000..f4f56aa67
--- /dev/null
+++ b/src/main/java/subway/view/MainMenu.java
@@ -0,0 +1,51 @@
+package subway.view;
+
+import subway.util.validator.MenuValidator;
+
+import java.util.Scanner;
+
+public class MainMenu {
+ private final String MAIN_TITLE = "## 메인 화면";
+ private final String MAINMENU_1 = "1. 경로 조회";
+ private final String QUIT_APP = "Q. 종료";
+ private final String ENTER = "\n";
+ private final String CHOICE_MENU = "## 원하는 기능을 선택하세요.";
+ private final String QUIT_MESSAGE = "프로그램을 종료합니다.";
+
+ private Scanner scanner;
+
+ public MainMenu(Scanner scanner) {
+ this.scanner = scanner;
+ }
+
+ public void startMainMENU() {
+ inputMenu();
+ }
+
+ private void inputMenu() {
+ while (true) {
+ outputMainMenu();
+ String input = scanner.nextLine();
+ System.out.println();
+ MenuValidator.isVailableMainMenu(input);
+ if (input.equals("1")) {
+ new RouteSearchMenu(scanner).startRouteSearchMenu();
+ }
+ if (input.equals("Q")) {
+ System.out.println(QUIT_MESSAGE);
+ return;
+ }
+ }
+ }
+
+
+ private void outputMainMenu() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(MAIN_TITLE).append(ENTER)
+ .append(MAINMENU_1).append(ENTER)
+ .append(QUIT_APP).append(ENTER)
+ .append(ENTER)
+ .append(CHOICE_MENU);
+ System.out.println(sb);
+ }
+}
diff --git a/src/main/java/subway/view/RouteSearchMenu.java b/src/main/java/subway/view/RouteSearchMenu.java
new file mode 100644
index 000000000..2f0e3223e
--- /dev/null
+++ b/src/main/java/subway/view/RouteSearchMenu.java
@@ -0,0 +1,119 @@
+package subway.view;
+
+import subway.util.CalculatorRoute;
+import subway.util.DistanceRouteSearch;
+import subway.util.validator.MenuValidator;
+import subway.util.validator.StationValidator;
+import subway.util.TimeRouteSearch;
+
+import java.util.List;
+import java.util.Scanner;
+
+public class RouteSearchMenu {
+ private final String ROUTE_SEARCH_TITLE = "## 경로 기준";
+ private final String MENU1 = "1. 최단 거리";
+ private final String MENU2 = "2. 최소 시간";
+ private final String BACK = "B. 돌아가기";
+ private final String ENTER = "\n";
+ private final String CHOICE_MENU = "## 원하는 기능을 선택하세요.";
+ private final String REQUEST_START = "## 출발역을 입력하세요.";
+ private final String REQUEST_ARRIVAL = "## 도착역을 입력하세요.";
+ private final String LINE = "---";
+ private final String INFO = "[ INFO ] ";
+
+ private Scanner scanner;
+ private String input;
+ private String startStationName;
+ private String arrivalStationName;
+
+ public RouteSearchMenu(Scanner scanner) {
+ this.scanner = scanner;
+ }
+
+ public void startRouteSearchMenu() {
+ inputMenu();
+ }
+
+ private void inputMenu() {
+ while (true) {
+ outputRouteSearchMenu();
+ this.input = scanner.nextLine();
+ System.out.println();
+ MenuValidator.isVailableRouteSearchMenu(input);
+ if (input.equals("1") || input.equals("2")) {
+ requestStartStation();
+ }
+ if (input.equals("B")) {
+ return;
+ }
+ }
+ }
+
+ private void requestStartStation() {
+ System.out.println(REQUEST_START);
+ this.startStationName = scanner.nextLine();
+ System.out.println();
+ if (StationValidator.haveStation(startStationName)) {
+ requestArrivalStation();
+ }
+ }
+
+ private void requestArrivalStation() {
+ System.out.println(REQUEST_ARRIVAL);
+ this.arrivalStationName = scanner.nextLine();
+ System.out.println();
+ if (StationValidator.checkVailableArrivalStation(startStationName, arrivalStationName)) {
+ checkSearchMethod();
+ }
+ }
+
+ private void checkSearchMethod() {
+ if (input.equals("1")) {
+ searchShortestDistanceRoute();
+ }
+ if (input.equals("2")) {
+ searchShortestTimeRoute();
+ }
+ }
+
+ private void searchShortestDistanceRoute() {
+ List list = DistanceRouteSearch.getShortestRoute(startStationName, arrivalStationName);
+ int time = CalculatorRoute.calculatorRouteTime(list);
+ int distance = CalculatorRoute.calculatorRoutDistance(list);
+ System.out.println("## 조회결과");
+ System.out.println(LINE);
+ System.out.println("총 거리: " + distance + "km");
+ System.out.println("총 소요 시간 : " + time + "분");
+ System.out.println(LINE);
+ for (String station : list) {
+ System.out.println(INFO + station);
+ }
+ System.out.println();
+ }
+
+ private void searchShortestTimeRoute() {
+ List list = TimeRouteSearch.getShortestRoute(startStationName, arrivalStationName);
+ int time = CalculatorRoute.calculatorRouteTime(list);
+ int distance = CalculatorRoute.calculatorRoutDistance(list);
+ System.out.println("## 조회결과");
+ System.out.println(LINE);
+ System.out.println("총 거리: " + distance + "km");
+ System.out.println("총 소요 시간 : " + time + "분");
+ System.out.println(LINE);
+ for (String station : list) {
+ System.out.println(INFO + station);
+ }
+ System.out.println();
+ }
+
+ private void outputRouteSearchMenu() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ROUTE_SEARCH_TITLE).append(ENTER)
+ .append(MENU1).append(ENTER)
+ .append(MENU2).append(ENTER)
+ .append(BACK).append(ENTER)
+ .append(ENTER)
+ .append(CHOICE_MENU);
+ System.out.println(sb);
+ }
+}
diff --git a/src/test/java/subway/DefaultSettingTest.java b/src/test/java/subway/DefaultSettingTest.java
new file mode 100644
index 000000000..73a6beacd
--- /dev/null
+++ b/src/test/java/subway/DefaultSettingTest.java
@@ -0,0 +1,48 @@
+package subway;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import subway.domain.Line;
+import subway.domain.LineRepository;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+import subway.util.DefaultSetting;
+import subway.util.enums.DefaultLines;
+import subway.util.enums.DefaultStations;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class DefaultSettingTest {
+
+ @BeforeAll
+ public static void 초기값_세팅() {
+ DefaultSetting.defaultSetting();
+ }
+
+ @Test
+ public void 이호선_만들어졌다() {
+ Line line2 = LineRepository.findLineByName(DefaultLines.LINE2.getName());
+ assertEquals(line2.getName(), DefaultLines.LINE2.getName());
+ }
+
+ @Test
+ public void 노선들_만들어졌다() {
+ List lineList= LineRepository.lines();
+ assertEquals(lineList.size(), 3);
+ }
+
+ @Test
+ public void 역들_만들어졌다() {
+ List stationList = StationRepository.stations();
+ assertEquals(stationList.size(), 7);
+ }
+
+ @Test
+ public void 구간_적용됐다() {
+ Station station = StationRepository.findStationByName(DefaultStations.KYODAE.getName());
+ assertEquals(station.sections().size(), 2);
+ }
+
+}