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
152 changes: 152 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
### 초기 설정
- [ ] 프로그램 시작 시 역, 노선, 구간 정보를 초기 설정 해야 한다.
- 거리와 소요 시간은 양의 정수이며 단위는 km와 분을 의미한다.
- 아래의 사전 등록 정보로 반드시 초기 설정을 한다.

```
1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다.
2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
- 2호선: 교대역 - ( 2km / 3분 ) - 강남역 - ( 2km / 3분 ) - 역삼역
- 3호선: 교대역 - ( 3km / 2분 ) - 남부터미널역 - ( 6km / 5분 ) - 양재역 - ( 1km / 1분 ) - 매봉역
- 신분당선: 강남역 - ( 2km / 8분 ) - 양재역 - ( 10km / 3분 ) - 양재시민의숲역
```

### 지하철 역 기능
- [x] 지하철 역을 생성할 수 있다.
- 지하철 역 생성 시 이름을 입력받는다.
- 예외 처리
- [x] 지하철 역 이름은 2글자 이상이어야 한다.

### 지하철 역 관리 기능
- [x] 지하철 역 저장소에 지하철 역을 등록할 수 있다.
- 예외 처리
- [x] 중복된 지하철 역 이름이 등록될 수 없다.

### 지하철 노선 기능
- [x] 지하철 노선을 생성할 수 있다.
- [x] 노선 생성 시 이름, 상행 종점역, 하행 종점역을 입력받는다.
- 예외 처리
- [x] 지하철 노선 이름은 2글자 이상이어야 한다.
- [x] 상행 종점역과 하행 종점역이 같을 수는 없다.

### 지하철 노선 관리 기능
- [x] 지하철 노선 저장소에 지하철 노선을 등록할 수 있다.
- 예외 처리
- [x] 중복된 지하철 노선 이름이 등록될 수 없다.

### 지하철 구간 기능
- [x] 지하철 구간을 생성할 수 있다.
- LineStation은 JGrapht의 Edge 정보(거리, 시간)를 생성자 인자로 받는다.
- 거리, 시간을 수정하면 거리, 시간 관리 그래프에도 반영되어야 한다.

### 지하철 구간 관리 기능
- [x] 지하철 노선 저장소에서 지하철 노선에 구간을 추가할 수 있다.
- [x] 해당 노선에 이미 존재하는 지하철 역은 추가할 수 없다.
- 순서
1. 거리 그래프 관리 객체에 추가할 역을 Vertex로 추가한다.
2. 거리 그래프 관리 객체에 해당 노선의 하행 끝 역과 추가할 역의 JGrapht Edge를 만든다.
3. 거리 그래프 관리 객체에 해당 JGrapht Edge에 weight을 설정해서 추가한다.
4. 시간 그래프 관리 객체에 추가할 역을 Vertex로 추가한다.
5. 시간 그래프 관리 객체에 해당 노선의 하행 끝 역과 추가할 역의 JGrapht Edge를 만든다.
6. 시간 그래프 관리 객체에 해당 JGrapht Edge에 weight을 설정해서 추가한다.
7. LineStation의 속성으로 위의 두 JGrapht Edge를 설정하여 생성한 뒤에 노선의 하행 끝 뒤에 추가한다.

### 경로 관리 기능
- [x] 거리 그래프 객체와 시간 그래프 객체를 가지고 있다.
- [x] 출발역과 도착역을 입력받아 최단 거리 경로를 조회한다.
- [x] 출발역과 도착역을 입력받아 최소 시간 경로를 조회한다.
- 경로 조회 시 총 거리, 총 소요 시간도 함께 출력한다.
- 예외 처리
- [x] 경로 조회 시 출발역이나 도착역이 존재하지 않으면 에러를 출력한다.
- [x] 경로 조회 시 출발역과 도착역이 같으면 에러를 출력한다.
- [x] 경로 조회 시 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다.


### 생각해보기
#### 구간 정보가 바뀌면 그래프가 자동으로 업데이트 되도록 하자!
구간 정보에 거리와 시간에 대한 JGrapht의 Edge 정보들을 저장하고 구간 정보가 바뀌어야 할 때 구간 관리 기능을 통해 해당 Edge를 업데이트 해준다.

<br>

## ✍🏻 입출력 요구사항
- `프로그래밍 실행 결과 예시`와 동일하게 입출력을 구현한다.
- 기대하는 출력 결과는 `[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. 돌아가기

## 원하는 기능을 선택하세요.

...

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

public enum ActionType {

SHORTEST_DISTANCE_PATH("최단 거리"),
SHORTEST_TIME_PATH("최소 시간"),
BACK("돌아가기");

private final String name;

ActionType(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
20 changes: 19 additions & 1 deletion src/main/java/subway/Application.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
package subway;

import java.util.Scanner;
import subway.utils.ErrorUtils;
import subway.view.InputView;
import subway.view.screen.MainScreen;
import subway.view.screen.ScreenManager;

public class Application {

public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
InputView inputView = InputView.of(scanner);
DummyData.load();
start(inputView);
}

public static void start(InputView inputView) {
ScreenManager.push(new MainScreen());

while (!ScreenManager.isEmpty()) {
ErrorUtils.screenGoBackWhenException(() -> {
ScreenManager.visualize();
ScreenManager.logic(inputView);
});
}
}
}
31 changes: 31 additions & 0 deletions src/main/java/subway/CategoryType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package subway;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public enum CategoryType {

STATION(
"경로 조회",
Arrays.asList(ActionType.SHORTEST_DISTANCE_PATH, ActionType.SHORTEST_TIME_PATH)),
EXIT(
"종료",
Collections.emptyList());

private final String name;
private final List<ActionType> actionOrder;

CategoryType(String name, List<ActionType> actionOrder) {
this.name = name;
this.actionOrder = actionOrder;
}

public String getName() {
return name;
}

public List<ActionType> getActionOrder() {
return actionOrder;
}
}
36 changes: 36 additions & 0 deletions src/main/java/subway/DummyData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package subway;

import java.util.Arrays;
import subway.domain.line.domain.Line;
import subway.domain.line.domain.LineRepository;
import subway.domain.station.domain.Station;
import subway.domain.station.domain.StationRepository;

public class DummyData {

public static void load() {
Station station1 = Station.from("교대역");
Station station2 = Station.from("강남역");
Station station3 = Station.from("역삼역");
Station station4 = Station.from("남부터미널역");
Station station5 = Station.from("양재역");
Station station6 = Station.from("양재시민의숲역");
Station station7 = Station.from("매봉역");

StationRepository.saveAll(
Arrays.asList(station1, station2, station3, station4, station5, station6, station7)
);

Line line1 = Line.of("2호선", station1, station2, 2, 3);
line1.addSection(station3, 2, 3);

Line line2 = Line.of("3호선", station1, station4, 3, 2);
line2.addSection(station5, 6, 5);
line2.addSection(station7, 1, 1);

Line line3 = Line.of("신분당선", station2, station5, 2, 8);
line3.addSection(station6, 10, 3);

LineRepository.saveAll(Arrays.asList(line1, line2, line3));
}
}
25 changes: 25 additions & 0 deletions src/main/java/subway/HandlerMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package subway;

import subway.view.screen.ScreenManager;
import subway.view.screen.action.path.ShortestDistancePathActionScreen;
import subway.view.screen.action.path.ShortestTimePathActionScreen;

public class HandlerMapping {

public static void mapping(CategoryType categoryType, ActionType actionType) {
if (categoryType == CategoryType.STATION) {
pathMapping(categoryType, actionType);
}
}

private static void pathMapping(CategoryType categoryType, ActionType actionType) {
if (actionType == ActionType.SHORTEST_DISTANCE_PATH) {
ScreenManager.push(new ShortestDistancePathActionScreen(categoryType));
return;
}

if (actionType == ActionType.SHORTEST_TIME_PATH) {
ScreenManager.push(new ShortestTimePathActionScreen(categoryType));
}
}
}
15 changes: 0 additions & 15 deletions src/main/java/subway/domain/Line.java

This file was deleted.

26 changes: 0 additions & 26 deletions src/main/java/subway/domain/LineRepository.java

This file was deleted.

31 changes: 31 additions & 0 deletions src/main/java/subway/domain/Path/domain/PathRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package subway.domain.Path.domain;

import org.jgrapht.graph.DefaultWeightedEdge;
import subway.domain.station.domain.Station;

public class PathRepository {

private static final WeightGraph distanceWeightGraph = new WeightGraph();
private static final WeightGraph timeWeightGraph = new WeightGraph();

public static WeightGraph getDistanceWeightGraph() {
return distanceWeightGraph;
}

public static WeightGraph getTimeWeightGraph() {
return timeWeightGraph;
}

public static DefaultWeightedEdge addDistanceWeightEdge(Station sourceStation, Station targetStation, double weight) {
return distanceWeightGraph.addEdge(sourceStation, targetStation, weight);
}

public static DefaultWeightedEdge addTimeWeightEdge(Station sourceStation, Station targetStation, double weight) {
return timeWeightGraph.addEdge(sourceStation, targetStation, weight);
}

public static void addVertex(Station station) {
distanceWeightGraph.addVertex(station);
timeWeightGraph.addVertex(station);
}
}
Loading