From 328478b4ff85c7a7d5c6993902b51fc503fbdda5 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 13:18:13 +0900 Subject: [PATCH 01/19] =?UTF-8?q?docs:=20=EA=B0=9D=EC=B2=B4=20=EC=97=AD?= =?UTF-8?q?=ED=95=A0&=EC=B1=85=EC=9E=84=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 객체의 역할&책임을 먼저 나눴음. --- docs/README.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..4fed8bf74 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,86 @@ +# 지하철 노선도 경로 조회 미션 +- 등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다. + +
+ +## 🚀 기능 요구사항 + +> 프리코스 3주차 미션에서 사용한 코드를 참고해도 무관하다. + +### 초기 설정 +- 프로그램 시작 시 역, 노선, 구간 정보를 초기 설정 해야 한다. +- 거리와 소요 시간은 양의 정수이며 단위는 km와 분을 의미한다. +- 아래의 사전 등록 정보로 반드시 초기 설정을 한다. + +``` + 1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다. + 2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다. + 3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점) + - 2호선: 교대역 - ( 2km / 3분 ) - 강남역 - ( 2km / 3분 ) - 역삼역 + - 3호선: 교대역 - ( 3km / 2분 ) - 남부터미널역 - ( 6km / 5분 ) - 양재역 - ( 1km / 1분 ) - 매봉역 + - 신분당선: 강남역 - ( 2km / 8분 ) - 양재역 - ( 10km / 3분 ) - 양재시민의숲역 + ``` + +## Livenow 프로그램 구현 +## 🚩 객체 책임 (아는 것과 하는 것) +### **지하철 역** +- 아는 것 + - 역 이름 + +
+ +- 하는 것 + + +### 지하철 역 저장소 +- 아는 것 + - 지하철 역 + +
+ +- 하는 것 + - 지하철 역 저장 + +### **거리(분)** +- 아는 것 + - 거리 + - 분 + +
+ +- 하는 것 + +### **역간 거리(분)** +- 아는 것 + - 앞선 지하철 역 + - 뒤의 지하철 역 + - 거리(분) + +
+ +- 하는 것 + +### **라인** +- 아는 것 + - 노선 이름 + - 지하철 역(들) + +
+ +- 하는 것 + +### **라인(들)** +- 아는 것 + - 라인 + +
+ +- 하는 것 +### 라인 저장소 +- 아는 것 + - 라인 + +
+ +- 하는 것 + - 라인저장 \ No newline at end of file From e657bdd0c0e6a5c2e3c8078636dc79eddb4cc0c5 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 13:24:50 +0900 Subject: [PATCH 02/19] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 4fed8bf74..75d694aa4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,7 +32,7 @@ - 하는 것 -### 지하철 역 저장소 +### **지하철 역 저장소** - 아는 것 - 지하철 역 @@ -76,11 +76,58 @@
- 하는 것 -### 라인 저장소 +### **라인 저장소** - 아는 것 - 라인
- 하는 것 - - 라인저장 \ No newline at end of file + - 라인저장 + + +## 🚩 구현할 기능 +### **메인 화면** +- [ ] 객체 모델링 +- [ ] 메인화면 출력 +- [ ] 보장된 숫자 입력 + - 보장된 숫자(1,Q 만을 허용) + - 보장된 숫자가 아닐 시 에러 출력 + - `에러 발생` +- [ ] Q가 입력될 시, 종료 + +### **경로 조회** +- [ ] 보장된 숫자 입력 + - 보장된 숫자(1,2,B 만을 허용) + - 보장된 숫자가 아닐 시 에러 출력 + - `에러 발생` +- [ ] 1을 입력시 최단 거리 조회 + - [ ] 출발역을 입력 + - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `에러 발생` + - [ ] 도착역 역을 입력 + - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `에러 발생` + - [ ] 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다 + - `에러 발생` + - [ ] 출발역과 도착역이 같으면 에러를 출력한다 + - `에러 발생` + - [ ] 최단 거리를 조회한다. 테스트 + - [ ] 최단 거리를 조회한다. + +- [ ] 2를 입력시 최소 시간 조회 + - [ ] 출발역을 입력 + - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `에러 발생` + - [ ] 도착역 역을 입력 + - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `에러 발생` + - [ ] 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다 + - `에러 발생` + - [ ] 출발역과 도착역이 같으면 에러를 출력한다 + - `에러 발생` + - [ ] 최소 시간을 조회한다. 테스트 + - [ ] 최소 시간를 조회한다. + +### **에러 발생해도 서비스가 죽지 않아야 한다** +- [ ] 에러 핸들링 From e13407fe5226992a670f94a88500aaaa9246354a Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 13:43:15 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat:=20=EA=B0=9D=EC=B2=B4=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 객체 초기 모델링을 진행함. --- docs/README.md | 17 +++++++++----- src/main/java/subway/SubwayManageApp.java | 14 +++++++++++ src/main/java/subway/domain/Distance.java | 15 ++++++++++++ src/main/java/subway/domain/DistanceTime.java | 11 +++++++++ src/main/java/subway/domain/Time.java | 15 ++++++++++++ .../java/subway/domain/{ => line}/Line.java | 2 +- .../domain/{ => line}/LineRepository.java | 2 +- src/main/java/subway/domain/line/Lines.java | 12 ++++++++++ .../subway/domain/{ => station}/Station.java | 2 +- .../{ => station}/StationRepository.java | 2 +- .../subway/domain/station/StationTime.java | 4 ++++ .../java/subway/domain/station/Stations.java | 12 ++++++++++ src/main/java/subway/view/InputView.java | 11 +++++++++ src/main/java/subway/view/OutputView.java | 9 ++++++++ src/main/java/subway/view/Prefix.java | 23 +++++++++++++++++++ .../java/subway/view/screen/MainView.java | 4 ++++ 16 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 src/main/java/subway/SubwayManageApp.java create mode 100644 src/main/java/subway/domain/Distance.java create mode 100644 src/main/java/subway/domain/DistanceTime.java create mode 100644 src/main/java/subway/domain/Time.java rename src/main/java/subway/domain/{ => line}/Line.java (87%) rename src/main/java/subway/domain/{ => line}/LineRepository.java (95%) create mode 100644 src/main/java/subway/domain/line/Lines.java rename src/main/java/subway/domain/{ => station}/Station.java (86%) rename src/main/java/subway/domain/{ => station}/StationRepository.java (95%) create mode 100644 src/main/java/subway/domain/station/StationTime.java create mode 100644 src/main/java/subway/domain/station/Stations.java create mode 100644 src/main/java/subway/view/InputView.java create mode 100644 src/main/java/subway/view/OutputView.java create mode 100644 src/main/java/subway/view/Prefix.java create mode 100644 src/main/java/subway/view/screen/MainView.java diff --git a/docs/README.md b/docs/README.md index 75d694aa4..2f55c2db0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,19 +41,24 @@ - 하는 것 - 지하철 역 저장 -### **거리(분)** +### **거리** +- 아는 것 + - 거리(km) + +
+ +- 하는 것 + +### **시간** - 아는 것 - - 거리 - 분
- 하는 것 -### **역간 거리(분)** +### **거리(분)** - 아는 것 - - 앞선 지하철 역 - - 뒤의 지하철 역 - 거리(분)
@@ -88,7 +93,7 @@ ## 🚩 구현할 기능 ### **메인 화면** -- [ ] 객체 모델링 +- [x] 객체 모델링 - [ ] 메인화면 출력 - [ ] 보장된 숫자 입력 - 보장된 숫자(1,Q 만을 허용) diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java new file mode 100644 index 000000000..33c032695 --- /dev/null +++ b/src/main/java/subway/SubwayManageApp.java @@ -0,0 +1,14 @@ +package subway; + +import subway.view.InputView; +import subway.view.OutputView; + +public class SubwayManageApp { + private final InputView inputView; + private final OutputView outputView; + + public SubwayManageApp(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } +} diff --git a/src/main/java/subway/domain/Distance.java b/src/main/java/subway/domain/Distance.java new file mode 100644 index 000000000..824153e08 --- /dev/null +++ b/src/main/java/subway/domain/Distance.java @@ -0,0 +1,15 @@ +package subway.domain; + +import java.math.BigDecimal; + +public class Distance { + private BigDecimal km; + + public Distance(BigDecimal km) { + this.km = km; + } + + public static Distance km(double km) { + return new Distance(BigDecimal.valueOf(km)); + } +} diff --git a/src/main/java/subway/domain/DistanceTime.java b/src/main/java/subway/domain/DistanceTime.java new file mode 100644 index 000000000..e4fec8f7d --- /dev/null +++ b/src/main/java/subway/domain/DistanceTime.java @@ -0,0 +1,11 @@ +package subway.domain; + +public class DistanceTime { + private final Distance distance; + private final Time time; + + public DistanceTime(Distance distance, Time time) { + this.distance = distance; + this.time = time; + } +} diff --git a/src/main/java/subway/domain/Time.java b/src/main/java/subway/domain/Time.java new file mode 100644 index 000000000..755da947f --- /dev/null +++ b/src/main/java/subway/domain/Time.java @@ -0,0 +1,15 @@ +package subway.domain; + +import java.math.BigDecimal; + +public class Time { + private BigDecimal minute; + + public Time(BigDecimal minute) { + this.minute = minute; + } + + public static Time minute(long minute) { + return new Time(BigDecimal.valueOf(minute)); + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/line/Line.java similarity index 87% rename from src/main/java/subway/domain/Line.java rename to src/main/java/subway/domain/line/Line.java index f4d738d5a..bb1a937bb 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/line/Line.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.line; public class Line { private String name; diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/line/LineRepository.java similarity index 95% rename from src/main/java/subway/domain/LineRepository.java rename to src/main/java/subway/domain/line/LineRepository.java index 2c4a723c9..89982c4d8 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/line/LineRepository.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.line; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/subway/domain/line/Lines.java b/src/main/java/subway/domain/line/Lines.java new file mode 100644 index 000000000..fbeecad44 --- /dev/null +++ b/src/main/java/subway/domain/line/Lines.java @@ -0,0 +1,12 @@ +package subway.domain.line; + +import java.util.ArrayList; +import java.util.List; + +public class Lines { + private final List lines; + + public Lines(List lines) { + this.lines = new ArrayList<>(lines); + } +} diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/station/Station.java similarity index 86% rename from src/main/java/subway/domain/Station.java rename to src/main/java/subway/domain/station/Station.java index bdb142590..ef99213b8 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/station/Station.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.station; public class Station { private String name; diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/station/StationRepository.java similarity index 95% rename from src/main/java/subway/domain/StationRepository.java rename to src/main/java/subway/domain/station/StationRepository.java index 8ed9d103f..fd8446b38 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/station/StationRepository.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.station; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/subway/domain/station/StationTime.java b/src/main/java/subway/domain/station/StationTime.java new file mode 100644 index 000000000..8806df1a6 --- /dev/null +++ b/src/main/java/subway/domain/station/StationTime.java @@ -0,0 +1,4 @@ +package subway.domain.station; + +public class StationTime { +} diff --git a/src/main/java/subway/domain/station/Stations.java b/src/main/java/subway/domain/station/Stations.java new file mode 100644 index 000000000..84f9d0215 --- /dev/null +++ b/src/main/java/subway/domain/station/Stations.java @@ -0,0 +1,12 @@ +package subway.domain.station; + +import java.util.ArrayList; +import java.util.List; + +public class Stations { + private final List stations; + + public Stations(List stations) { + this.stations = new ArrayList<>(stations); + } +} diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java new file mode 100644 index 000000000..2f4f171b6 --- /dev/null +++ b/src/main/java/subway/view/InputView.java @@ -0,0 +1,11 @@ +package subway.view; + +import java.util.Scanner; + +public class InputView { + private final Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } +} diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java new file mode 100644 index 000000000..a5009882e --- /dev/null +++ b/src/main/java/subway/view/OutputView.java @@ -0,0 +1,9 @@ +package subway.view; + +public class OutputView { + private final StringBuilder sb; + + public OutputView(StringBuilder sb) { + this.sb = sb; + } +} diff --git a/src/main/java/subway/view/Prefix.java b/src/main/java/subway/view/Prefix.java new file mode 100644 index 000000000..cf7628dfe --- /dev/null +++ b/src/main/java/subway/view/Prefix.java @@ -0,0 +1,23 @@ +package subway.view; + +public enum Prefix { + ERROR("[ERROR] "), + INFO("[INFO] "), + SHARP("## "), + ONE("1. "), + TWO("2. "), + QUIT("Q. "), + BACK("B. "), + ENTER("\n"), + CONTOUR("---"); + + private String prefix; + + Prefix(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } +} diff --git a/src/main/java/subway/view/screen/MainView.java b/src/main/java/subway/view/screen/MainView.java new file mode 100644 index 000000000..877c9e0b1 --- /dev/null +++ b/src/main/java/subway/view/screen/MainView.java @@ -0,0 +1,4 @@ +package subway.view.screen; + +public class MainView { +} From a3c6d5dd7d2ee357f6719a9b0dbc451c9e65246d Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 13:55:30 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/subway/Application.java | 5 ++++ src/main/java/subway/SubwayManageApp.java | 6 +++++ src/main/java/subway/view/OutputView.java | 26 +++++++++++++++++++ src/main/java/subway/view/Prefix.java | 4 ++- .../java/subway/view/screen/MainView.java | 15 +++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2f55c2db0..bd91c2419 100644 --- a/docs/README.md +++ b/docs/README.md @@ -94,7 +94,7 @@ ## 🚩 구현할 기능 ### **메인 화면** - [x] 객체 모델링 -- [ ] 메인화면 출력 +- [x] 메인화면 출력 - [ ] 보장된 숫자 입력 - 보장된 숫자(1,Q 만을 허용) - 보장된 숫자가 아닐 시 에러 출력 diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..8c14dfd7d 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,15 @@ package subway; +import subway.view.InputView; +import subway.view.OutputView; + import java.util.Scanner; public class Application { public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); // TODO: 프로그램 구현 + SubwayManageApp subwayManageApp = new SubwayManageApp(new InputView(scanner), new OutputView(new StringBuilder())); + subwayManageApp.startApp(); } } diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 33c032695..fe9ec6ba0 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -2,6 +2,7 @@ import subway.view.InputView; import subway.view.OutputView; +import subway.view.screen.MainView; public class SubwayManageApp { private final InputView inputView; @@ -11,4 +12,9 @@ public SubwayManageApp(InputView inputView, OutputView outputView) { this.inputView = inputView; this.outputView = outputView; } + + public void startApp() { + MainView mainView = new MainView(outputView); + mainView.showOptions(); + } } diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java index a5009882e..8ccc1d24b 100644 --- a/src/main/java/subway/view/OutputView.java +++ b/src/main/java/subway/view/OutputView.java @@ -1,9 +1,35 @@ package subway.view; public class OutputView { + private static final int START_INDEX = 0; + private final StringBuilder sb; public OutputView(StringBuilder sb) { this.sb = sb; } + + + public void printOptions(String[] strings) { + sb.append(Prefix.ENTER.getPrefix()); + for (String string : strings) { + sb.append(string).append(Prefix.ENTER.getPrefix()); + } + sb.append(Prefix.ENTER.getPrefix()); + sb.append(Prefix.CHOOSE_FUNCTION.getPrefix()); + System.out.println(sb.toString()); + clearSb(); + } + + public void printSharp(String text) { + sb.append(Prefix.ENTER.getPrefix()); + sb.append(text).append(Prefix.ENTER.getPrefix()); + + System.out.println(sb.toString()); + clearSb(); + } + + private void clearSb() { + sb.delete(START_INDEX, sb.length()); + } } diff --git a/src/main/java/subway/view/Prefix.java b/src/main/java/subway/view/Prefix.java index cf7628dfe..dbe7d9357 100644 --- a/src/main/java/subway/view/Prefix.java +++ b/src/main/java/subway/view/Prefix.java @@ -9,7 +9,9 @@ public enum Prefix { QUIT("Q. "), BACK("B. "), ENTER("\n"), - CONTOUR("---"); + CONTOUR("---"), + CHOOSE_FUNCTION(SHARP.getPrefix() + "원하는 기능을 선택하세요."); + private String prefix; diff --git a/src/main/java/subway/view/screen/MainView.java b/src/main/java/subway/view/screen/MainView.java index 877c9e0b1..7d38c5b8c 100644 --- a/src/main/java/subway/view/screen/MainView.java +++ b/src/main/java/subway/view/screen/MainView.java @@ -1,4 +1,19 @@ package subway.view.screen; +import subway.view.OutputView; +import subway.view.Prefix; + public class MainView { + private static final String MAIN = Prefix.SHARP.getPrefix() + "메인 화면"; + private static final String SEARCH = Prefix.ONE.getPrefix() + "경로 조회"; + private static final String QUIT = Prefix.QUIT.getPrefix() + "종료"; + private final OutputView outputView; + + public MainView(OutputView outputView) { + this.outputView = outputView; + } + + public void showOptions() { + outputView.printOptions(new String[]{MAIN, SEARCH, QUIT}); + } } From 06ab7368a362cb04b222648a5c75325f222b4dae Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 14:07:42 +0900 Subject: [PATCH 05/19] =?UTF-8?q?feat:=20=EB=B3=B4=EC=9E=A5=EB=90=9C=20?= =?UTF-8?q?=EA=B0=92=20=EC=9E=85=EB=A0=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 보장되지 않은 값일 시 에러발생 --- docs/README.md | 8 ++-- src/main/java/subway/SubwayManageApp.java | 3 ++ src/main/java/subway/exception/ErrorCode.java | 22 ++++++++++ .../subway/exception/SelectionException.java | 15 +++++++ src/main/java/subway/view/InputView.java | 4 ++ src/main/java/subway/view/MainSelection.java | 26 +++++++++++ src/main/java/subway/view/OutputView.java | 1 - .../java/subway/view/MainSelectionTest.java | 44 +++++++++++++++++++ 8 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 src/main/java/subway/exception/ErrorCode.java create mode 100644 src/main/java/subway/exception/SelectionException.java create mode 100644 src/main/java/subway/view/MainSelection.java create mode 100644 src/test/java/subway/view/MainSelectionTest.java diff --git a/docs/README.md b/docs/README.md index bd91c2419..4a17eecc2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -95,10 +95,10 @@ ### **메인 화면** - [x] 객체 모델링 - [x] 메인화면 출력 -- [ ] 보장된 숫자 입력 - - 보장된 숫자(1,Q 만을 허용) - - 보장된 숫자가 아닐 시 에러 출력 - - `에러 발생` +- [x] 보장된 값 입력 + - 보장된 값(1,Q 만을 허용) + - 보장된 값이 아닐 시 에러 출력 + - `SelectionException` - [ ] Q가 입력될 시, 종료 ### **경로 조회** diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index fe9ec6ba0..62a7d6cf8 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -1,6 +1,7 @@ package subway; import subway.view.InputView; +import subway.view.MainSelection; import subway.view.OutputView; import subway.view.screen.MainView; @@ -16,5 +17,7 @@ public SubwayManageApp(InputView inputView, OutputView outputView) { public void startApp() { MainView mainView = new MainView(outputView); mainView.showOptions(); + MainSelection mainSelection = new MainSelection(inputView.inputNextLine()); + } } diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java new file mode 100644 index 000000000..0a3e20928 --- /dev/null +++ b/src/main/java/subway/exception/ErrorCode.java @@ -0,0 +1,22 @@ +package subway.exception; + +public enum ErrorCode { + //Selection + INVALID_INPUT_VALUE("S001", "선택할 수 없는 기능입니다."); + + private final String code; + private final String message; + + ErrorCode(String code, String message) { + this.code = code; + this.message = message; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/subway/exception/SelectionException.java b/src/main/java/subway/exception/SelectionException.java new file mode 100644 index 000000000..751b82072 --- /dev/null +++ b/src/main/java/subway/exception/SelectionException.java @@ -0,0 +1,15 @@ +package subway.exception; + +public class SelectionException extends IllegalArgumentException { + private final ErrorCode errorCode; + + public SelectionException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} + diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java index 2f4f171b6..520577799 100644 --- a/src/main/java/subway/view/InputView.java +++ b/src/main/java/subway/view/InputView.java @@ -8,4 +8,8 @@ public class InputView { public InputView(Scanner scanner) { this.scanner = scanner; } + + public String inputNextLine() { + return scanner.nextLine(); + } } diff --git a/src/main/java/subway/view/MainSelection.java b/src/main/java/subway/view/MainSelection.java new file mode 100644 index 000000000..73f7655b4 --- /dev/null +++ b/src/main/java/subway/view/MainSelection.java @@ -0,0 +1,26 @@ +package subway.view; + +import subway.exception.ErrorCode; +import subway.exception.SelectionException; + +public class MainSelection { + private final static String OPTION_ONE = "1"; + private final static String OPTION_QUIT = "Q"; + + private final String option; + + public MainSelection(String option) { + this.option = option; + validate(option); + } + + private void validate(String option) { + if (!option.equals(OPTION_ONE) && !option.equals(OPTION_QUIT)) { + throw new SelectionException(ErrorCode.INVALID_INPUT_VALUE); + } + } + + public String getOption() { + return option; + } +} diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java index 8ccc1d24b..f423cee88 100644 --- a/src/main/java/subway/view/OutputView.java +++ b/src/main/java/subway/view/OutputView.java @@ -9,7 +9,6 @@ public OutputView(StringBuilder sb) { this.sb = sb; } - public void printOptions(String[] strings) { sb.append(Prefix.ENTER.getPrefix()); for (String string : strings) { diff --git a/src/test/java/subway/view/MainSelectionTest.java b/src/test/java/subway/view/MainSelectionTest.java new file mode 100644 index 000000000..941eb97b3 --- /dev/null +++ b/src/test/java/subway/view/MainSelectionTest.java @@ -0,0 +1,44 @@ +package subway.view; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.exception.ErrorCode; +import subway.exception.SelectionException; + +import static org.assertj.core.api.Assertions.*; + +class MainSelectionTest { + + @Test + @DisplayName("메인 옵션 선택시 보장된 입력 값만 입력해야한다.") + void testInput() { + //given + String inputOne = "1"; + String inputQuit = "Q"; + + //when + MainSelection mainSelectionOne = new MainSelection(inputOne); + MainSelection mainSelectionQuit = new MainSelection(inputQuit); + + //then + assertThat(mainSelectionOne.getOption()).isEqualTo(inputOne); + assertThat(mainSelectionQuit.getOption()).isEqualTo(inputQuit); + } + + @Test + @DisplayName("메인 옵션 선택시 보장되지 않은 입력 값일 시 에러가 발생한다.") + void testInputError() { + //given + String inputWrong = "2"; + String inputWrong2 = "0"; + + //then + assertThatThrownBy(() -> new MainSelection(inputWrong)) + .isInstanceOf(SelectionException.class) + .hasMessage(ErrorCode.INVALID_INPUT_VALUE.getMessage()); + assertThatThrownBy(() -> new MainSelection(inputWrong2)) + .isInstanceOf(SelectionException.class) + .hasMessage(ErrorCode.INVALID_INPUT_VALUE.getMessage()); + + } +} \ No newline at end of file From b250fa336d51ce387054fd5256c37ce8d23001c7 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 14:14:22 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat:=20Q=EA=B0=80=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=90=A0=20=EC=8B=9C,=20=EC=A2=85=EB=A3=8C=20(=20=EC=86=8C?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=20q=20=EB=8F=84=20=ED=97=88=EC=9A=A9=20?= =?UTF-8?q?=ED=95=A8.=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/subway/SubwayManageApp.java | 15 +++++++++++++-- src/main/java/subway/view/MainSelection.java | 11 ++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 4a17eecc2..db00b4679 100644 --- a/docs/README.md +++ b/docs/README.md @@ -99,7 +99,7 @@ - 보장된 값(1,Q 만을 허용) - 보장된 값이 아닐 시 에러 출력 - `SelectionException` -- [ ] Q가 입력될 시, 종료 +- [x] Q가 입력될 시, 종료 ( 소문자 q 도 허용 함. ) ### **경로 조회** - [ ] 보장된 숫자 입력 diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 62a7d6cf8..41c515e45 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -16,8 +16,19 @@ public SubwayManageApp(InputView inputView, OutputView outputView) { public void startApp() { MainView mainView = new MainView(outputView); - mainView.showOptions(); - MainSelection mainSelection = new MainSelection(inputView.inputNextLine()); + while (true) { + mainView.showOptions(); + MainSelection mainSelection = new MainSelection(inputView.inputNextLine()); + chooseOption(mainSelection); + if (mainSelection.isQuit()) { + break; + } + } + } + + private void chooseOption(MainSelection mainSelection) { + if (mainSelection.isOptionOne()) { + } } } diff --git a/src/main/java/subway/view/MainSelection.java b/src/main/java/subway/view/MainSelection.java index 73f7655b4..c27518215 100644 --- a/src/main/java/subway/view/MainSelection.java +++ b/src/main/java/subway/view/MainSelection.java @@ -6,6 +6,7 @@ public class MainSelection { private final static String OPTION_ONE = "1"; private final static String OPTION_QUIT = "Q"; + private final static String OPTION_QUIT_LOWERCASE = "q"; private final String option; @@ -15,7 +16,7 @@ public MainSelection(String option) { } private void validate(String option) { - if (!option.equals(OPTION_ONE) && !option.equals(OPTION_QUIT)) { + if (!option.equals(OPTION_ONE) && !option.equals(OPTION_QUIT) && !option.equals(OPTION_QUIT_LOWERCASE)) { throw new SelectionException(ErrorCode.INVALID_INPUT_VALUE); } } @@ -23,4 +24,12 @@ private void validate(String option) { public String getOption() { return option; } + + public boolean isOptionOne() { + return option.equals(OPTION_ONE); + } + + public boolean isQuit() { + return option.equals(OPTION_QUIT) | option.equals(OPTION_QUIT_LOWERCASE); + } } From 2fbbb90473983f4c93724db5c78e55e2d49a513c Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 14:22:51 +0900 Subject: [PATCH 07/19] =?UTF-8?q?feat:=20=EC=A1=B0=ED=9A=8C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=B3=B4=EC=9E=A5=EB=90=9C=20?= =?UTF-8?q?=EA=B0=92=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 조회 화면에서 보장된 값 입력 테스트 완료 --- docs/README.md | 7 +-- src/main/java/subway/SubwayManageApp.java | 8 ++- .../java/subway/view/SearchSelection.java | 29 +++++++++++ .../java/subway/view/SearchSelectionTest.java | 51 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 src/main/java/subway/view/SearchSelection.java create mode 100644 src/test/java/subway/view/SearchSelectionTest.java diff --git a/docs/README.md b/docs/README.md index db00b4679..ce082b433 100644 --- a/docs/README.md +++ b/docs/README.md @@ -102,9 +102,10 @@ - [x] Q가 입력될 시, 종료 ( 소문자 q 도 허용 함. ) ### **경로 조회** -- [ ] 보장된 숫자 입력 - - 보장된 숫자(1,2,B 만을 허용) - - 보장된 숫자가 아닐 시 에러 출력 +- [ ] 경로 조회 화면 출력 +- [x] 보장된 값 입력 + - 보장된 값(1,2,B 만을 허용) + - 보장된 값이 아닐 시 에러 출력 - `에러 발생` - [ ] 1을 입력시 최단 거리 조회 - [ ] 출발역을 입력 diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 41c515e45..659bb3fcc 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -3,6 +3,7 @@ import subway.view.InputView; import subway.view.MainSelection; import subway.view.OutputView; +import subway.view.SearchSelection; import subway.view.screen.MainView; public class SubwayManageApp { @@ -28,7 +29,12 @@ public void startApp() { private void chooseOption(MainSelection mainSelection) { if (mainSelection.isOptionOne()) { - + manageSearch(); } } + + private void manageSearch() { + SearchSelection searchSelection = new SearchSelection(inputView.inputNextLine()); + + } } diff --git a/src/main/java/subway/view/SearchSelection.java b/src/main/java/subway/view/SearchSelection.java new file mode 100644 index 000000000..b6a6abc92 --- /dev/null +++ b/src/main/java/subway/view/SearchSelection.java @@ -0,0 +1,29 @@ +package subway.view; + +import subway.exception.ErrorCode; +import subway.exception.SelectionException; + +public class SearchSelection { + private final static String OPTION_ONE = "1"; + private final static String OPTION_TWO = "2"; + private final static String OPTION_BACK = "B"; + private final static String OPTION_BACK_LOWERCASE = "b"; + + private final String option; + + public SearchSelection(String option) { + this.option = option; + validate(option); + } + + private void validate(String option) { + if (!option.equals(OPTION_ONE) && !option.equals(OPTION_TWO) + && !option.equals(OPTION_BACK) && !option.equals(OPTION_BACK_LOWERCASE)) { + throw new SelectionException(ErrorCode.INVALID_INPUT_VALUE); + } + } + + public String getOption() { + return option; + } +} diff --git a/src/test/java/subway/view/SearchSelectionTest.java b/src/test/java/subway/view/SearchSelectionTest.java new file mode 100644 index 000000000..ac354762e --- /dev/null +++ b/src/test/java/subway/view/SearchSelectionTest.java @@ -0,0 +1,51 @@ +package subway.view; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.exception.ErrorCode; +import subway.exception.SelectionException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class SearchSelectionTest { + + @Test + @DisplayName("메인 옵션 선택시 보장된 입력 값만 입력해야한다.") + void testInput() { + //given + String inputOne = "1"; + String input2 = "2"; + String input3 = "B"; + String input4 = "b"; + + //when + SearchSelection searchSelection = new SearchSelection(inputOne); + SearchSelection searchSelection2 = new SearchSelection(input2); + SearchSelection searchSelection3 = new SearchSelection(input3); + SearchSelection searchSelection4 = new SearchSelection(input4); + + //then + assertThat(searchSelection.getOption()).isEqualTo(inputOne); + assertThat(searchSelection2.getOption()).isEqualTo(input2); + assertThat(searchSelection3.getOption()).isEqualTo(input3); + assertThat(searchSelection4.getOption()).isEqualTo(input4); + } + + @Test + @DisplayName("메인 옵션 선택시 보장되지 않은 입력 값일 시 에러가 발생한다.") + void testInputError() { + //given + String inputWrong = "3"; + String inputWrong2 = "-b"; + + //then + assertThatThrownBy(() -> new SearchSelection(inputWrong)) + .isInstanceOf(SelectionException.class) + .hasMessage(ErrorCode.INVALID_INPUT_VALUE.getMessage()); + assertThatThrownBy(() -> new SearchSelection(inputWrong2)) + .isInstanceOf(SelectionException.class) + .hasMessage(ErrorCode.INVALID_INPUT_VALUE.getMessage()); + + } +} \ No newline at end of file From a4e7eec4bc0b24fce2abd72fc3194a4038c30af6 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 14:33:21 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=ED=99=94=EB=A9=B4=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 10 +++++++-- src/main/java/subway/SubwayManageApp.java | 7 +++++-- .../java/subway/view/screen/SearchView.java | 21 +++++++++++++++++++ .../view/{ => selection}/MainSelection.java | 2 +- .../view/{ => selection}/SearchSelection.java | 2 +- .../java/subway/view/MainSelectionTest.java | 1 + .../java/subway/view/SearchSelectionTest.java | 1 + 7 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/main/java/subway/view/screen/SearchView.java rename src/main/java/subway/view/{ => selection}/MainSelection.java (96%) rename src/main/java/subway/view/{ => selection}/SearchSelection.java (96%) diff --git a/docs/README.md b/docs/README.md index ce082b433..ee17e52e5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -102,11 +102,17 @@ - [x] Q가 입력될 시, 종료 ( 소문자 q 도 허용 함. ) ### **경로 조회** -- [ ] 경로 조회 화면 출력 +- [x] 경로 조회 화면 출력 - [x] 보장된 값 입력 - 보장된 값(1,2,B 만을 허용) - 보장된 값이 아닐 시 에러 출력 - - `에러 발생` + - `SelectionException` +- [ ] 지하철 역 저장 +- [ ] 노선 저장 +- [ ] 지하철 마다 시간(분) 저장 +- [ ] 노선에 지하철 역 저장 + + - [ ] 1을 입력시 최단 거리 조회 - [ ] 출발역을 입력 - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 659bb3fcc..64d97fb60 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -1,9 +1,10 @@ package subway; import subway.view.InputView; -import subway.view.MainSelection; +import subway.view.screen.SearchView; +import subway.view.selection.MainSelection; import subway.view.OutputView; -import subway.view.SearchSelection; +import subway.view.selection.SearchSelection; import subway.view.screen.MainView; public class SubwayManageApp { @@ -34,6 +35,8 @@ private void chooseOption(MainSelection mainSelection) { } private void manageSearch() { + SearchView searchView = new SearchView(outputView); + searchView.showOptions(); SearchSelection searchSelection = new SearchSelection(inputView.inputNextLine()); } diff --git a/src/main/java/subway/view/screen/SearchView.java b/src/main/java/subway/view/screen/SearchView.java new file mode 100644 index 000000000..6320b1717 --- /dev/null +++ b/src/main/java/subway/view/screen/SearchView.java @@ -0,0 +1,21 @@ +package subway.view.screen; + +import subway.view.OutputView; +import subway.view.Prefix; + +public class SearchView { + private static final String MAIN = Prefix.SHARP.getPrefix() + "경로 기준"; + private static final String DISTANCE = Prefix.ONE.getPrefix() + "최단 거리"; + private static final String TIME = Prefix.TWO.getPrefix() + "최소 시간"; + private static final String BACK = Prefix.BACK.getPrefix() + "돌아가기"; + + private final OutputView outputView; + + public SearchView(OutputView outputView) { + this.outputView = outputView; + } + + public void showOptions() { + outputView.printOptions(new String[]{MAIN, DISTANCE, TIME, BACK}); + } +} diff --git a/src/main/java/subway/view/MainSelection.java b/src/main/java/subway/view/selection/MainSelection.java similarity index 96% rename from src/main/java/subway/view/MainSelection.java rename to src/main/java/subway/view/selection/MainSelection.java index c27518215..3162f19fc 100644 --- a/src/main/java/subway/view/MainSelection.java +++ b/src/main/java/subway/view/selection/MainSelection.java @@ -1,4 +1,4 @@ -package subway.view; +package subway.view.selection; import subway.exception.ErrorCode; import subway.exception.SelectionException; diff --git a/src/main/java/subway/view/SearchSelection.java b/src/main/java/subway/view/selection/SearchSelection.java similarity index 96% rename from src/main/java/subway/view/SearchSelection.java rename to src/main/java/subway/view/selection/SearchSelection.java index b6a6abc92..de8af9edd 100644 --- a/src/main/java/subway/view/SearchSelection.java +++ b/src/main/java/subway/view/selection/SearchSelection.java @@ -1,4 +1,4 @@ -package subway.view; +package subway.view.selection; import subway.exception.ErrorCode; import subway.exception.SelectionException; diff --git a/src/test/java/subway/view/MainSelectionTest.java b/src/test/java/subway/view/MainSelectionTest.java index 941eb97b3..38f76d232 100644 --- a/src/test/java/subway/view/MainSelectionTest.java +++ b/src/test/java/subway/view/MainSelectionTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import subway.exception.ErrorCode; import subway.exception.SelectionException; +import subway.view.selection.MainSelection; import static org.assertj.core.api.Assertions.*; diff --git a/src/test/java/subway/view/SearchSelectionTest.java b/src/test/java/subway/view/SearchSelectionTest.java index ac354762e..3ce8b6de0 100644 --- a/src/test/java/subway/view/SearchSelectionTest.java +++ b/src/test/java/subway/view/SearchSelectionTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import subway.exception.ErrorCode; import subway.exception.SelectionException; +import subway.view.selection.SearchSelection; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; From caa3daa4fd837b205465f95ebac3a4838b9e4b50 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 15:00:00 +0900 Subject: [PATCH 09/19] =?UTF-8?q?feat:=20=EC=A7=80=ED=95=98=EC=B2=A0=20?= =?UTF-8?q?=EC=97=AD=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 보장된 값의 지하철 역이 저장되어야 한다. 테스트 완료 --- docs/README.md | 5 +- .../java/subway/domain/station/Station.java | 19 +++++ .../domain/station/StationRepository.java | 11 +++ .../subway/domain/station/StationService.java | 25 ++++++ .../domain/station/dto/StationSaveReqDto.java | 13 +++ src/main/java/subway/exception/ErrorCode.java | 12 ++- .../subway/exception/StationException.java | 14 ++++ .../domain/station/StationServiceTest.java | 50 ++++++++++++ .../subway/domain/station/StationTest.java | 81 +++++++++++++++++++ 9 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 src/main/java/subway/domain/station/StationService.java create mode 100644 src/main/java/subway/domain/station/dto/StationSaveReqDto.java create mode 100644 src/main/java/subway/exception/StationException.java create mode 100644 src/test/java/subway/domain/station/StationServiceTest.java create mode 100644 src/test/java/subway/domain/station/StationTest.java diff --git a/docs/README.md b/docs/README.md index ee17e52e5..e8cfd9889 100644 --- a/docs/README.md +++ b/docs/README.md @@ -65,7 +65,7 @@ - 하는 것 -### **라인** +### **노선** - 아는 것 - 노선 이름 - 지하철 역(들) @@ -107,8 +107,9 @@ - 보장된 값(1,2,B 만을 허용) - 보장된 값이 아닐 시 에러 출력 - `SelectionException` -- [ ] 지하철 역 저장 +- [x] 지하철 역 저장 - [ ] 노선 저장 + - [ ] 2개 이상의 지하철 역들이 포함되어 있어야 한다. - [ ] 지하철 마다 시간(분) 저장 - [ ] 노선에 지하철 역 저장 diff --git a/src/main/java/subway/domain/station/Station.java b/src/main/java/subway/domain/station/Station.java index ef99213b8..5a73e2c33 100644 --- a/src/main/java/subway/domain/station/Station.java +++ b/src/main/java/subway/domain/station/Station.java @@ -1,10 +1,18 @@ package subway.domain.station; +import subway.exception.ErrorCode; +import subway.exception.StationException; + public class Station { + private static final int MIN_SIZE = 2; + private static final String MUST_CONTAIN_LAST = "역"; + private static final String PERMIT_CHARACTER = "^[가-힣|0-9]*$"; + private String name; public Station(String name) { this.name = name; + validateName(name); } public String getName() { @@ -12,4 +20,15 @@ public String getName() { } // 추가 기능 구현 + private void validateName(String name) { + if (name.length() < MIN_SIZE) { + throw new StationException(ErrorCode.STATION_NAME_LENGTH_ERROR); + } + if (!name.endsWith(MUST_CONTAIN_LAST)) { + throw new StationException(ErrorCode.STATION_INVALID_LAST_NAME); + } + if (!name.matches(PERMIT_CHARACTER)) { + throw new StationException(ErrorCode.STATION_INVALID_CHARACTER); + } + } } diff --git a/src/main/java/subway/domain/station/StationRepository.java b/src/main/java/subway/domain/station/StationRepository.java index fd8446b38..f0749cc33 100644 --- a/src/main/java/subway/domain/station/StationRepository.java +++ b/src/main/java/subway/domain/station/StationRepository.java @@ -1,5 +1,8 @@ package subway.domain.station; +import subway.exception.ErrorCode; +import subway.exception.StationException; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,4 +26,12 @@ public static boolean deleteStation(String name) { public static void deleteAll() { stations.clear(); } + + public static Station findByName(String stationName) { + Station findStation = stations.stream() + .filter(station -> station.getName().equals(stationName)) + .findAny() + .orElseThrow(() -> new StationException(ErrorCode.STATION_NOT_EXIST)); + return findStation; + } } diff --git a/src/main/java/subway/domain/station/StationService.java b/src/main/java/subway/domain/station/StationService.java new file mode 100644 index 000000000..da24eee69 --- /dev/null +++ b/src/main/java/subway/domain/station/StationService.java @@ -0,0 +1,25 @@ +package subway.domain.station; + +import subway.domain.station.dto.StationSaveReqDto; +import subway.exception.ErrorCode; +import subway.exception.StationException; + +public class StationService { + public StationService() { + } + + public Station saveStation(StationSaveReqDto saveReqDto) { + try { + StationRepository.findByName(saveReqDto.getStationName()); + } catch (StationException stationException) { + Station station = new Station(saveReqDto.getStationName()); + StationRepository.addStation(station); + return station; + } + throw new StationException(ErrorCode.STATION_ALREADY_EXIST); + } + + public void removeAll() { + StationRepository.deleteAll(); + } +} diff --git a/src/main/java/subway/domain/station/dto/StationSaveReqDto.java b/src/main/java/subway/domain/station/dto/StationSaveReqDto.java new file mode 100644 index 000000000..8d43e8af4 --- /dev/null +++ b/src/main/java/subway/domain/station/dto/StationSaveReqDto.java @@ -0,0 +1,13 @@ +package subway.domain.station.dto; + +public class StationSaveReqDto { + private final String stationName; + + public StationSaveReqDto(String stationName) { + this.stationName = stationName; + } + + public String getStationName() { + return stationName; + } +} diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index 0a3e20928..20e07c05f 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -1,8 +1,18 @@ package subway.exception; +import subway.view.Prefix; + public enum ErrorCode { //Selection - INVALID_INPUT_VALUE("S001", "선택할 수 없는 기능입니다."); + INVALID_INPUT_VALUE("S001", "선택할 수 없는 기능입니다."), + + //Station + STATION_NOT_EXIST("ST001", "존재하지 않는 역입니다."), + STATION_NAME_LENGTH_ERROR("ST002",Prefix.ERROR.getPrefix() + "역 이름은 2글자 이상이어야 합니다."), + STATION_INVALID_LAST_NAME("ST003", Prefix.ERROR.getPrefix() + "마지막 글자에 역이 들어가야합니다."), + STATION_INVALID_CHARACTER("ST004", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), + STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."); + private final String code; private final String message; diff --git a/src/main/java/subway/exception/StationException.java b/src/main/java/subway/exception/StationException.java new file mode 100644 index 000000000..d5d928fe7 --- /dev/null +++ b/src/main/java/subway/exception/StationException.java @@ -0,0 +1,14 @@ +package subway.exception; + +public class StationException extends IllegalArgumentException { + private final ErrorCode errorCode; + + public StationException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/station/StationServiceTest.java b/src/test/java/subway/domain/station/StationServiceTest.java new file mode 100644 index 000000000..70d0ab6a3 --- /dev/null +++ b/src/test/java/subway/domain/station/StationServiceTest.java @@ -0,0 +1,50 @@ +package subway.domain.station; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.domain.station.dto.StationSaveReqDto; +import subway.exception.ErrorCode; +import subway.exception.StationException; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class StationServiceTest { + + StationService stationService; + + @BeforeEach + void before() { + stationService = new StationService(); + String stationName = "행복역"; + String stationName2 = "사랑역"; + String stationName3 = "희망역"; + String stationName4 = "소망역"; + stationService.saveStation(new StationSaveReqDto(stationName)); + stationService.saveStation(new StationSaveReqDto(stationName2)); + stationService.saveStation(new StationSaveReqDto(stationName3)); + stationService.saveStation(new StationSaveReqDto(stationName4)); + } + + @AfterEach + void after() { + stationService.removeAll(); + } + + @Test + @DisplayName("이미 등록된 지하철 역일 시 에러가 발생한다. ") + void testDuplicateSave() { + //given + String name = "인천시청역"; + String name2 = "인천시청역"; + + //when + Station savedIncheonStation = stationService.saveStation(new StationSaveReqDto(name)); + + //then + assertThatThrownBy(() -> stationService.saveStation(new StationSaveReqDto(name2))) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_ALREADY_EXIST.getMessage()); + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/station/StationTest.java b/src/test/java/subway/domain/station/StationTest.java new file mode 100644 index 000000000..13aea2477 --- /dev/null +++ b/src/test/java/subway/domain/station/StationTest.java @@ -0,0 +1,81 @@ +package subway.domain.station; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.exception.ErrorCode; +import subway.exception.StationException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class StationTest { + @Test + @DisplayName("숫자, 한글이 포함된 역을 저장할 수 있다.") + void testStationSave() { + //given + String name = "하이2역"; + String name2 = "바이역"; + + //when + Station stationName = new Station(name); + Station stationName2 = new Station(name2); + + //then + assertThat(stationName.getName()).isEqualTo(name); + assertThat(stationName2.getName()).isEqualTo(name2); + } + + @Test + @DisplayName("2글자 이하일 시 에러가 발생한다") + void testStationSaveLengthError() { + //given + String name = "하"; + String name2 = "바"; + String name3 = ""; + + //when + + //then + assertThatThrownBy(() -> new Station(name)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_NAME_LENGTH_ERROR.getMessage()); + assertThatThrownBy(() -> new Station(name2)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_NAME_LENGTH_ERROR.getMessage()); + assertThatThrownBy(() -> new Station(name3)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_NAME_LENGTH_ERROR.getMessage()); + } + + @Test + @DisplayName("저장할 이름의 마지막 글자가 '역'이 아니면 에러가 발생한다") + void testStationSaveLastNameError() { + //given + String name = "하이욕"; + String name2 = "바이염"; + + //then + assertThatThrownBy(() -> new Station(name)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_INVALID_LAST_NAME.getMessage()); + assertThatThrownBy(() -> new Station(name2)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_INVALID_LAST_NAME.getMessage()); + } + + @Test + @DisplayName("저장할 이름에 한글, 숫자 외의 문자가 들어오면 에러가 발생한다") + void testStationSaveInvalidCharacter() { + //given + String name = "하 역"; + String name2 = "바e역"; + + //then + assertThatThrownBy(() -> new Station(name)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_INVALID_CHARACTER.getMessage()); + assertThatThrownBy(() -> new Station(name2)) + .isInstanceOf(StationException.class) + .hasMessage(ErrorCode.STATION_INVALID_CHARACTER.getMessage()); + } +} \ No newline at end of file From 6ecfe1c8b398c3fabbd912bedaa98199ded5ab24 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 15:14:02 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat:=20=EB=85=B8=EC=84=A0=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 보장된 값의 노선을 저장한다. --- docs/README.md | 9 +-- src/main/java/subway/domain/line/Line.java | 19 +++++ .../subway/domain/line/LineRepository.java | 11 +++ .../java/subway/domain/line/LineService.java | 21 ++++++ .../domain/line/dto/LineSaveReqDto.java | 13 ++++ .../domain/station/StationRepository.java | 2 +- .../java/subway/domain/station/Stations.java | 5 ++ src/main/java/subway/exception/ErrorCode.java | 15 +++- .../java/subway/exception/LineException.java | 14 ++++ .../subway/domain/line/LineServiceTest.java | 36 +++++++++ .../java/subway/domain/line/LineTest.java | 75 +++++++++++++++++++ 11 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 src/main/java/subway/domain/line/LineService.java create mode 100644 src/main/java/subway/domain/line/dto/LineSaveReqDto.java create mode 100644 src/main/java/subway/exception/LineException.java create mode 100644 src/test/java/subway/domain/line/LineServiceTest.java create mode 100644 src/test/java/subway/domain/line/LineTest.java diff --git a/docs/README.md b/docs/README.md index e8cfd9889..7adb0d664 100644 --- a/docs/README.md +++ b/docs/README.md @@ -108,12 +108,9 @@ - 보장된 값이 아닐 시 에러 출력 - `SelectionException` - [x] 지하철 역 저장 -- [ ] 노선 저장 - - [ ] 2개 이상의 지하철 역들이 포함되어 있어야 한다. -- [ ] 지하철 마다 시간(분) 저장 -- [ ] 노선에 지하철 역 저장 - - +- [x] 노선 저장 +- [ ] 구간 저장 +- [ ] 지하철 구간마다 시간(분) 저장 - [ ] 1을 입력시 최단 거리 조회 - [ ] 출발역을 입력 - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. diff --git a/src/main/java/subway/domain/line/Line.java b/src/main/java/subway/domain/line/Line.java index bb1a937bb..0280b0d50 100644 --- a/src/main/java/subway/domain/line/Line.java +++ b/src/main/java/subway/domain/line/Line.java @@ -1,10 +1,18 @@ package subway.domain.line; +import subway.exception.ErrorCode; +import subway.exception.LineException; + public class Line { + private static final int MIN_SIZE = 2; + private static final String MUST_CONTAIN_LAST = "선"; + private static final String PERMIT_CHARACTER = "^[가-힣|0-9]*$"; + private String name; public Line(String name) { this.name = name; + validateName(name); } public String getName() { @@ -12,4 +20,15 @@ public String getName() { } // 추가 기능 구현 + private void validateName(String name) { + if (name.length() < MIN_SIZE) { + throw new LineException(ErrorCode.LINE_NAME_LENGTH_ERROR); + } + if (!name.endsWith(MUST_CONTAIN_LAST)) { + throw new LineException(ErrorCode.LINE_INVALID_LAST_NAME); + } + if (!name.matches(PERMIT_CHARACTER)) { + throw new LineException(ErrorCode.LINE_INVALID_CHARACTER); + } + } } diff --git a/src/main/java/subway/domain/line/LineRepository.java b/src/main/java/subway/domain/line/LineRepository.java index 89982c4d8..2c98c6fe5 100644 --- a/src/main/java/subway/domain/line/LineRepository.java +++ b/src/main/java/subway/domain/line/LineRepository.java @@ -1,5 +1,8 @@ package subway.domain.line; +import subway.exception.ErrorCode; +import subway.exception.LineException; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,4 +26,12 @@ public static boolean deleteLineByName(String name) { public static void deleteAll() { lines.clear(); } + + public static Line findByName(String lineName) { + Line findLine = lines.stream() + .filter(line -> line.getName().equals(lineName)) + .findAny() + .orElseThrow(() -> new LineException(ErrorCode.LINE_NOT_FOUND)); + return findLine; + } } diff --git a/src/main/java/subway/domain/line/LineService.java b/src/main/java/subway/domain/line/LineService.java new file mode 100644 index 000000000..a025029c9 --- /dev/null +++ b/src/main/java/subway/domain/line/LineService.java @@ -0,0 +1,21 @@ +package subway.domain.line; + +import subway.domain.line.dto.LineSaveReqDto; +import subway.exception.ErrorCode; +import subway.exception.LineException; + +public class LineService { + public LineService() { + } + + public Line saveLine(LineSaveReqDto saveReqDto) { + try { + LineRepository.findByName(saveReqDto.getName()); + } catch (LineException lineException) { + Line line = new Line(saveReqDto.getName()); + LineRepository.addLine(line); + return line; + } + throw new LineException(ErrorCode.LINE_ALREADY_EXIST); + } +} diff --git a/src/main/java/subway/domain/line/dto/LineSaveReqDto.java b/src/main/java/subway/domain/line/dto/LineSaveReqDto.java new file mode 100644 index 000000000..45067758f --- /dev/null +++ b/src/main/java/subway/domain/line/dto/LineSaveReqDto.java @@ -0,0 +1,13 @@ +package subway.domain.line.dto; + +public class LineSaveReqDto { + private String name; + + public LineSaveReqDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/subway/domain/station/StationRepository.java b/src/main/java/subway/domain/station/StationRepository.java index f0749cc33..5cb972afe 100644 --- a/src/main/java/subway/domain/station/StationRepository.java +++ b/src/main/java/subway/domain/station/StationRepository.java @@ -31,7 +31,7 @@ public static Station findByName(String stationName) { Station findStation = stations.stream() .filter(station -> station.getName().equals(stationName)) .findAny() - .orElseThrow(() -> new StationException(ErrorCode.STATION_NOT_EXIST)); + .orElseThrow(() -> new StationException(ErrorCode.STATION_NOT_FOUND)); return findStation; } } diff --git a/src/main/java/subway/domain/station/Stations.java b/src/main/java/subway/domain/station/Stations.java index 84f9d0215..65ff92e5a 100644 --- a/src/main/java/subway/domain/station/Stations.java +++ b/src/main/java/subway/domain/station/Stations.java @@ -1,6 +1,7 @@ package subway.domain.station; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Stations { @@ -9,4 +10,8 @@ public class Stations { public Stations(List stations) { this.stations = new ArrayList<>(stations); } + + public List getStations() { + return Collections.unmodifiableList(stations); + } } diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index 20e07c05f..6679867a5 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -7,11 +7,20 @@ public enum ErrorCode { INVALID_INPUT_VALUE("S001", "선택할 수 없는 기능입니다."), //Station - STATION_NOT_EXIST("ST001", "존재하지 않는 역입니다."), - STATION_NAME_LENGTH_ERROR("ST002",Prefix.ERROR.getPrefix() + "역 이름은 2글자 이상이어야 합니다."), + STATION_EMTPY("ST001", "존재하지 않는 역입니다."), + STATION_NAME_LENGTH_ERROR("ST002", Prefix.ERROR.getPrefix() + "역 이름은 2글자 이상이어야 합니다."), STATION_INVALID_LAST_NAME("ST003", Prefix.ERROR.getPrefix() + "마지막 글자에 역이 들어가야합니다."), STATION_INVALID_CHARACTER("ST004", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), - STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."); + STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."), + STATION_NOT_FOUND("ST006", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 지하철 역이 없습니다."), + + + //Line + LINE_NAME_LENGTH_ERROR("L001", Prefix.ERROR.getPrefix() + "노선 이름은 2글자 이상이어야 합니다."), + LINE_INVALID_LAST_NAME("L002", Prefix.ERROR.getPrefix() + "마지막 글자에 선이 들어가야합니다."), + LINE_INVALID_CHARACTER("L003", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), + LINE_NOT_FOUND("S004", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."), + LINE_ALREADY_EXIST("S005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 노선입니다."); private final String code; diff --git a/src/main/java/subway/exception/LineException.java b/src/main/java/subway/exception/LineException.java new file mode 100644 index 000000000..2105643a0 --- /dev/null +++ b/src/main/java/subway/exception/LineException.java @@ -0,0 +1,14 @@ +package subway.exception; + +public class LineException extends IllegalArgumentException { + private final ErrorCode errorCode; + + public LineException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/line/LineServiceTest.java b/src/test/java/subway/domain/line/LineServiceTest.java new file mode 100644 index 000000000..dbe44f5df --- /dev/null +++ b/src/test/java/subway/domain/line/LineServiceTest.java @@ -0,0 +1,36 @@ +package subway.domain.line; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.domain.line.dto.LineSaveReqDto; +import subway.exception.ErrorCode; +import subway.exception.LineException; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class LineServiceTest { + LineService lineService; + + @BeforeEach + void before() { + lineService = new LineService(); + } + + @Test + @DisplayName("이미 등록된 노선일 시 에러가 발생한다. ") + void testDuplicateSave() { + //given + String line = "1호선"; + String line2 = "1호선"; + + //when + lineService.saveLine(new LineSaveReqDto(line)); + + //then + assertThatThrownBy(() -> lineService.saveLine(new LineSaveReqDto(line2))) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_ALREADY_EXIST.getMessage()); + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/line/LineTest.java b/src/test/java/subway/domain/line/LineTest.java new file mode 100644 index 000000000..530fcb16e --- /dev/null +++ b/src/test/java/subway/domain/line/LineTest.java @@ -0,0 +1,75 @@ +package subway.domain.line; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.exception.ErrorCode; +import subway.exception.LineException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LineTest { + @Test + @DisplayName("숫자, 한글이 포함된 노선을 저장할 수 있다") + void testSave() { + //given + String line = "1호선"; + String line2 = "2호선"; + + //when + Line saveLine = new Line(line); + Line saveLine2 = new Line(line2); + + //then + assertThat(saveLine.getName()).isEqualTo(line); + assertThat(saveLine2.getName()).isEqualTo(line2); + } + + @Test + @DisplayName("2글자 미만인 구간의 이름이 들어올 시 에러가 발생한다.") + void testLengthError() { + //given + String line = "선"; + String line2 = "샨"; + + //then + assertThatThrownBy(() -> new Line(line)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_NAME_LENGTH_ERROR.getMessage()); + assertThatThrownBy(() -> new Line(line2)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_NAME_LENGTH_ERROR.getMessage()); + } + + @Test + @DisplayName("한글, 숫자가 아닌 이름이 들어올 시 에러가 발생한다.") + void testSaveError() { + //given + String line = "Q선"; + String line2 = "기 선"; + + //then + assertThatThrownBy(() -> new Line(line)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_INVALID_CHARACTER.getMessage()); + assertThatThrownBy(() -> new Line(line2)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_INVALID_CHARACTER.getMessage()); + } + + @Test + @DisplayName("마지막 글자가 선이 아닐 시 에러가 발생한다.") + void testLastNameError() { + //given + String line = "1호션"; + String line2 = "2호신"; + + //then + assertThatThrownBy(() -> new Line(line)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_INVALID_LAST_NAME.getMessage()); + assertThatThrownBy(() -> new Line(line2)) + .isInstanceOf(LineException.class) + .hasMessage(ErrorCode.LINE_INVALID_LAST_NAME.getMessage()); + } +} \ No newline at end of file From f7f5525f668dd6b9c527bb22ae2f54db00b99a48 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 15:33:41 +0900 Subject: [PATCH 11/19] =?UTF-8?q?feat:=20=EA=B5=AC=EA=B0=84=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구간 저장 테스트도 완료함. --- docs/README.md | 6 +- .../java/subway/domain/section/Section.java | 40 ++++++ .../domain/section/SectionRepository.java | 37 ++++++ .../subway/domain/section/SectionService.java | 98 +++++++++++++++ .../domain/section/dto/SectionFindResDto.java | 13 ++ .../domain/section/dto/SectionSaveReqDto.java | 25 ++++ .../section/dto/SectionStationAddReqDto.java | 25 ++++ .../dto/SectionStationDeleteReqDto.java | 19 +++ .../java/subway/domain/station/Stations.java | 8 ++ src/main/java/subway/exception/ErrorCode.java | 9 +- .../subway/exception/SectionException.java | 14 +++ .../domain/section/SectionServiceTest.java | 117 ++++++++++++++++++ 12 files changed, 407 insertions(+), 4 deletions(-) create mode 100644 src/main/java/subway/domain/section/Section.java create mode 100644 src/main/java/subway/domain/section/SectionRepository.java create mode 100644 src/main/java/subway/domain/section/SectionService.java create mode 100644 src/main/java/subway/domain/section/dto/SectionFindResDto.java create mode 100644 src/main/java/subway/domain/section/dto/SectionSaveReqDto.java create mode 100644 src/main/java/subway/domain/section/dto/SectionStationAddReqDto.java create mode 100644 src/main/java/subway/domain/section/dto/SectionStationDeleteReqDto.java create mode 100644 src/main/java/subway/exception/SectionException.java create mode 100644 src/test/java/subway/domain/section/SectionServiceTest.java diff --git a/docs/README.md b/docs/README.md index 7adb0d664..cd3b3df86 100644 --- a/docs/README.md +++ b/docs/README.md @@ -109,8 +109,10 @@ - `SelectionException` - [x] 지하철 역 저장 - [x] 노선 저장 -- [ ] 구간 저장 -- [ ] 지하철 구간마다 시간(분) 저장 +- [x] 구간 저장 +- [ ] 초기 저장 (시간(분) 미포함) +- [ ] 지하철 구간마다 시간(분) 저장 +- [ ] 초기 저장(구간마다 시간 포함) - [ ] 1을 입력시 최단 거리 조회 - [ ] 출발역을 입력 - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. diff --git a/src/main/java/subway/domain/section/Section.java b/src/main/java/subway/domain/section/Section.java new file mode 100644 index 000000000..e937c22e8 --- /dev/null +++ b/src/main/java/subway/domain/section/Section.java @@ -0,0 +1,40 @@ +package subway.domain.section; + +import subway.domain.line.Line; +import subway.domain.station.Station; +import subway.domain.station.Stations; + +import java.util.List; +import java.util.stream.Collectors; + +public class Section { + private final Line line; + private final Stations stations; + + private Section(Line line, Stations stations) { + this.line = line; + this.stations = stations; + } + + public static Section of(Line line, Stations stations) { + return new Section(line, stations); + } + + public void addStation(Station station, int sequence) { + stations.addStation(station, sequence); + } + + public String getLineName() { + return line.getName(); + } + + public int getStationsLength() { + return stations.size(); + } + + public List getStationsName() { + return stations.getStations().stream() + .map(Station::getName) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/subway/domain/section/SectionRepository.java b/src/main/java/subway/domain/section/SectionRepository.java new file mode 100644 index 000000000..306611950 --- /dev/null +++ b/src/main/java/subway/domain/section/SectionRepository.java @@ -0,0 +1,37 @@ +package subway.domain.section; + +import subway.exception.ErrorCode; +import subway.exception.SectionException; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +public class SectionRepository { + private static final Map sections = new ConcurrentHashMap<>(); + + public SectionRepository() { + } + + public Section addSection(Section section) { + if (findByName(section.getLineName()) != null) { + throw new SectionException(ErrorCode.LINE_ALREADY_EXIST); + } + sections.put(section.getLineName(), section); + return section; + } + + public Section findByName(String lineName) { + Section section = sections.get(lineName); + return section; + } + + public List
sections() { + return sections.values().stream().collect(Collectors.toList()); + } + + public void removeAll() { + sections.clear(); + } +} diff --git a/src/main/java/subway/domain/section/SectionService.java b/src/main/java/subway/domain/section/SectionService.java new file mode 100644 index 000000000..e7ce31e3d --- /dev/null +++ b/src/main/java/subway/domain/section/SectionService.java @@ -0,0 +1,98 @@ +package subway.domain.section; + +import subway.domain.line.Line; +import subway.domain.line.LineRepository; +import subway.domain.section.dto.SectionSaveReqDto; +import subway.domain.section.dto.SectionStationAddReqDto; +import subway.domain.section.dto.SectionStationDeleteReqDto; +import subway.domain.station.Station; +import subway.domain.station.StationRepository; +import subway.domain.station.Stations; +import subway.exception.ErrorCode; +import subway.exception.LineException; +import subway.exception.SectionException; +import subway.exception.StationException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SectionService { + public static final int CONVERT_SEQUENCE = 1; + + private final SectionRepository sectionRepository; + + public SectionService(SectionRepository sectionRepository) { + this.sectionRepository = sectionRepository; + } + + public Section saveSection(SectionSaveReqDto saveReqDto) { + Line line = new Line(saveReqDto.getLineName()); + checkAlreadyExist(line.getName()); + + Station upwardStation = new Station(saveReqDto.getUpwardStationName()); + checkUpwardNotFound(upwardStation.getName()); + + Station downwardStation = new Station(saveReqDto.getDownwardStationName()); + checkDownwardNotFound(downwardStation.getName()); + checkSameName(upwardStation.getName(), downwardStation.getName()); + + LineRepository.addLine(line); + Section section = Section.of(line, new Stations(Arrays.asList(upwardStation, downwardStation))); + return sectionRepository.addSection(section); + } + + public void addStation(SectionStationAddReqDto sectionStationAddReqDto) { + Section section = findByName(sectionStationAddReqDto.getLineName()); + Station station = StationRepository.findByName(sectionStationAddReqDto.getStationName()); + int sequence = sectionStationAddReqDto.getSequence(); + if (sequence > section.getStationsLength()) { + sequence = section.getStationsLength() + CONVERT_SEQUENCE; + } + section.addStation(station, sequence - CONVERT_SEQUENCE); + } + + public Section findByName(String lineName) { + Section findSection = sectionRepository.findByName(lineName); + if (findSection == null) { + throw new SectionException(ErrorCode.SECTION_NOT_FOUND); + } + return findSection; + } + + private void checkSameName(String upwardStationName, String downwardStationName) { + if (upwardStationName.equals(downwardStationName)) { + throw new SectionException(ErrorCode.SECTION_SAME_STATION_NAME); + } + } + + public void checkUpwardNotFound(String stationName) { + try { + StationRepository.findByName(stationName); + } catch (StationException stationException) { + throw new SectionException(ErrorCode.SECTION_NOT_FOUND); + } + } + + public void checkDownwardNotFound(String stationName) { + try { + StationRepository.findByName(stationName); + } catch (StationException stationException) { + throw new SectionException(ErrorCode.SECTION_NOT_FOUND); + } + } + + private void checkAlreadyExist(String name) { + try { + LineRepository.findByName(name); + } catch (LineException lineException) { + return; + } + throw new SectionException(ErrorCode.LINE_ALREADY_EXIST); + } + + public void removeAll() { + sectionRepository.removeAll(); + LineRepository.deleteAll(); + } +} diff --git a/src/main/java/subway/domain/section/dto/SectionFindResDto.java b/src/main/java/subway/domain/section/dto/SectionFindResDto.java new file mode 100644 index 000000000..3e4ccd7a4 --- /dev/null +++ b/src/main/java/subway/domain/section/dto/SectionFindResDto.java @@ -0,0 +1,13 @@ +package subway.domain.section.dto; + +public class SectionFindResDto { + private String lineName; + + public SectionFindResDto(String lineName) { + this.lineName = lineName; + } + + public String getLineName() { + return lineName; + } +} diff --git a/src/main/java/subway/domain/section/dto/SectionSaveReqDto.java b/src/main/java/subway/domain/section/dto/SectionSaveReqDto.java new file mode 100644 index 000000000..1757c6200 --- /dev/null +++ b/src/main/java/subway/domain/section/dto/SectionSaveReqDto.java @@ -0,0 +1,25 @@ +package subway.domain.section.dto; + +public class SectionSaveReqDto { + private String lineName; + private String upwardStationName; + private String downwardStationName; + + public SectionSaveReqDto(String lineName, String upwardStationName, String downwardStationName) { + this.lineName = lineName; + this.upwardStationName = upwardStationName; + this.downwardStationName = downwardStationName; + } + + public String getLineName() { + return lineName; + } + + public String getUpwardStationName() { + return upwardStationName; + } + + public String getDownwardStationName() { + return downwardStationName; + } +} diff --git a/src/main/java/subway/domain/section/dto/SectionStationAddReqDto.java b/src/main/java/subway/domain/section/dto/SectionStationAddReqDto.java new file mode 100644 index 000000000..40f57f95a --- /dev/null +++ b/src/main/java/subway/domain/section/dto/SectionStationAddReqDto.java @@ -0,0 +1,25 @@ +package subway.domain.section.dto; + +public class SectionStationAddReqDto { + private String lineName; + private String stationName; + private int sequence; + + public SectionStationAddReqDto(String lineName, String stationName, int sequence) { + this.lineName = lineName; + this.stationName = stationName; + this.sequence = sequence; + } + + public String getLineName() { + return lineName; + } + + public String getStationName() { + return stationName; + } + + public int getSequence() { + return sequence; + } +} diff --git a/src/main/java/subway/domain/section/dto/SectionStationDeleteReqDto.java b/src/main/java/subway/domain/section/dto/SectionStationDeleteReqDto.java new file mode 100644 index 000000000..0196777b0 --- /dev/null +++ b/src/main/java/subway/domain/section/dto/SectionStationDeleteReqDto.java @@ -0,0 +1,19 @@ +package subway.domain.section.dto; + +public class SectionStationDeleteReqDto { + private String lineName; + private String stationName; + + public SectionStationDeleteReqDto(String lineName, String stationName) { + this.lineName = lineName; + this.stationName = stationName; + } + + public String getLineName() { + return lineName; + } + + public String getStationName() { + return stationName; + } +} diff --git a/src/main/java/subway/domain/station/Stations.java b/src/main/java/subway/domain/station/Stations.java index 65ff92e5a..50332f5b6 100644 --- a/src/main/java/subway/domain/station/Stations.java +++ b/src/main/java/subway/domain/station/Stations.java @@ -14,4 +14,12 @@ public Stations(List stations) { public List getStations() { return Collections.unmodifiableList(stations); } + + public void addStation(Station station, int sequence) { + stations.add(sequence, station); + } + + public int size() { + return stations.size(); + } } diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index 6679867a5..b57668236 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -14,13 +14,18 @@ public enum ErrorCode { STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."), STATION_NOT_FOUND("ST006", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 지하철 역이 없습니다."), - //Line LINE_NAME_LENGTH_ERROR("L001", Prefix.ERROR.getPrefix() + "노선 이름은 2글자 이상이어야 합니다."), LINE_INVALID_LAST_NAME("L002", Prefix.ERROR.getPrefix() + "마지막 글자에 선이 들어가야합니다."), LINE_INVALID_CHARACTER("L003", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), LINE_NOT_FOUND("S004", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."), - LINE_ALREADY_EXIST("S005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 노선입니다."); + LINE_ALREADY_EXIST("S005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 노선입니다."), + + //Section + SECTION_SAME_STATION_NAME("SE001", Prefix.ERROR.getPrefix() + "상행 좀점역과 하행 종점역의 이름이 같을 수 없습니다."), + SECTION_NOT_FOUND("SE002", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."); + + private final String code; diff --git a/src/main/java/subway/exception/SectionException.java b/src/main/java/subway/exception/SectionException.java new file mode 100644 index 000000000..4d169c805 --- /dev/null +++ b/src/main/java/subway/exception/SectionException.java @@ -0,0 +1,14 @@ +package subway.exception; + +public class SectionException extends IllegalArgumentException { + private final ErrorCode errorCode; + + public SectionException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} diff --git a/src/test/java/subway/domain/section/SectionServiceTest.java b/src/test/java/subway/domain/section/SectionServiceTest.java new file mode 100644 index 000000000..f64e72f91 --- /dev/null +++ b/src/test/java/subway/domain/section/SectionServiceTest.java @@ -0,0 +1,117 @@ +package subway.domain.section; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.domain.section.dto.SectionSaveReqDto; +import subway.domain.section.dto.SectionStationAddReqDto; +import subway.domain.station.StationService; +import subway.domain.station.dto.StationSaveReqDto; +import subway.exception.ErrorCode; +import subway.exception.SectionException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class SectionServiceTest { + SectionService sectionService; + StationService stationService; + + @BeforeEach + void before() { + sectionService = new SectionService(new SectionRepository()); + stationService = new StationService(); + String stationName = "행복역"; + String stationName2 = "사랑역"; + String stationName3 = "희망역"; + String stationName4 = "소망역"; + stationService.saveStation(new StationSaveReqDto(stationName)); + stationService.saveStation(new StationSaveReqDto(stationName2)); + stationService.saveStation(new StationSaveReqDto(stationName3)); + stationService.saveStation(new StationSaveReqDto(stationName4)); + + String lineName = "1호선"; + String upwardName = "행복역"; + String downwardName = "사랑역"; + sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName)); + sectionService.addStation(new SectionStationAddReqDto(lineName, stationName3, 2)); + } + + @AfterEach + void after() { + stationService.removeAll(); + sectionService.removeAll(); + } + + @Test + @DisplayName("노선을 저장한다") + void testSaved() { + //given + String lineName = "2호선"; + String upwardName = "희망역"; + String downwardName = "소망역"; + + //when + Section savedSection = sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName)); + + //then + assertThat(savedSection.getLineName()).isEqualTo(lineName); + } + + @Test + @DisplayName("이미 저장된 노선일 시 에러가 발생한다.") + void testAlreadySavedError() { + //given + String lineName = "1호선"; + String upwardName = "희망역"; + String downwardName = "소망역"; + + //then + assertThatThrownBy(() -> sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName))) + .isInstanceOf(SectionException.class) + .hasMessage(ErrorCode.LINE_ALREADY_EXIST.getMessage()); + } + + @Test + @DisplayName("등룍하려는 상행 종점역이 존재하지 않으면 에러가 발생한다") + void testUpwardNotFound() { + //given + String lineName = "2호선"; + String upwardName = "역곡역"; + String downwardName = "소망역"; + + //then + assertThatThrownBy(() -> sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName))) + .isInstanceOf(SectionException.class); + } + + @Test + @DisplayName("등룍하려는 하행 종점역이 존재하지 않으면 에러가 발생한다") + void testDownwardNotFound() { + //given + String lineName = "2호선"; + String upwardName = "소망역"; + String downwardName = "역곡역"; + + //then + assertThatThrownBy(() -> sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName))) + .isInstanceOf(SectionException.class); + } + + @Test + @DisplayName("등룍하려는 하행 종점역이 앞서 등록한 상행 종점역일 시 에러가 발생한다") + void testDownwardSaveError() { + //given + String lineName = "2호선"; + String upwardName = "소망역"; + String downwardName = "소망역"; + + //then + assertThatThrownBy(() -> sectionService.saveSection(new SectionSaveReqDto(lineName, upwardName, downwardName))) + .isInstanceOf(SectionException.class) + .hasMessage(ErrorCode.SECTION_SAME_STATION_NAME.getMessage()); + } +} + From b368c2f27611530f793f6c8539a07d3d0c537927 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 15:41:00 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat:=20-=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20(=EC=8B=9C=EA=B0=84(=EB=B6=84)=20=EB=AF=B8?= =?UTF-8?q?=ED=8F=AC=ED=95=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 시간을 어떻게 저장해야할지 감이 안잡혀서 현재는 구간많 있는 것으로 저장함. --- docs/README.md | 2 +- src/main/java/subway/Application.java | 6 +++ src/main/java/subway/DataInitService.java | 54 +++++++++++++++++++ .../domain/{ => distanceTime}/Distance.java | 2 +- .../{ => distanceTime}/DistanceTime.java | 2 +- .../distanceTime/DistanceTimeService.java | 4 ++ .../domain/{ => distanceTime}/Time.java | 2 +- 7 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/main/java/subway/DataInitService.java rename src/main/java/subway/domain/{ => distanceTime}/Distance.java (87%) rename src/main/java/subway/domain/{ => distanceTime}/DistanceTime.java (85%) create mode 100644 src/main/java/subway/domain/distanceTime/DistanceTimeService.java rename src/main/java/subway/domain/{ => distanceTime}/Time.java (87%) diff --git a/docs/README.md b/docs/README.md index cd3b3df86..3413c32b1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -110,7 +110,7 @@ - [x] 지하철 역 저장 - [x] 노선 저장 - [x] 구간 저장 -- [ ] 초기 저장 (시간(분) 미포함) +- [x] 초기 저장 (시간(분) 미포함) - [ ] 지하철 구간마다 시간(분) 저장 - [ ] 초기 저장(구간마다 시간 포함) - [ ] 1을 입력시 최단 거리 조회 diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 8c14dfd7d..489a0d3ae 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,5 +1,8 @@ package subway; +import subway.domain.section.SectionRepository; +import subway.domain.section.SectionService; +import subway.domain.station.StationService; import subway.view.InputView; import subway.view.OutputView; @@ -9,6 +12,9 @@ public class Application { public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); // TODO: 프로그램 구현 + DataInitService dataInitService = new DataInitService(new StationService(), new SectionService(new SectionRepository())); + dataInitService.init(); + SubwayManageApp subwayManageApp = new SubwayManageApp(new InputView(scanner), new OutputView(new StringBuilder())); subwayManageApp.startApp(); } diff --git a/src/main/java/subway/DataInitService.java b/src/main/java/subway/DataInitService.java new file mode 100644 index 000000000..9d7ee92c2 --- /dev/null +++ b/src/main/java/subway/DataInitService.java @@ -0,0 +1,54 @@ +package subway; + +import subway.domain.section.SectionService; +import subway.domain.section.dto.SectionSaveReqDto; +import subway.domain.section.dto.SectionStationAddReqDto; +import subway.domain.station.StationService; +import subway.domain.station.dto.StationSaveReqDto; + +public class DataInitService { + private static final String STATION_GYODAE = "교대역"; + private static final String STATION_GANGNAM = "강남역"; + private static final String STATION_YEOKSAM = "역삼역"; + private static final String STATION_SOUTH_TERMINAL = "남부터미널역"; + private static final String STATION_YANGJAE = "양재역"; + private static final String STATION_CITIZEN_FOREST = "양재시민의숲역"; + private static final String STATION_MAEBONG = "매봉역"; + private static final String LINE_TWO = "2호선"; + private static final String LINE_THREE = "3호선"; + private static final String LINE_SINBUNDANG = "신분당선"; + private static final int SECOND = 2; + private static final int THIRD = 3; + + private final StationService stationService; + private final SectionService sectionService; + + public DataInitService(StationService stationService, SectionService sectionService) { + this.stationService = stationService; + this.sectionService = sectionService; + } + + public void init() { + saveStation(); + saveSection(); + } + + private void saveSection() { + sectionService.saveSection(new SectionSaveReqDto(LINE_TWO, STATION_GYODAE, STATION_YEOKSAM)); + sectionService.addStation(new SectionStationAddReqDto(LINE_TWO, STATION_GANGNAM, SECOND)); + + sectionService.saveSection(new SectionSaveReqDto(LINE_THREE, STATION_GYODAE, STATION_MAEBONG)); + sectionService.addStation(new SectionStationAddReqDto(LINE_THREE, STATION_SOUTH_TERMINAL, SECOND)); + sectionService.addStation(new SectionStationAddReqDto(LINE_THREE, STATION_YANGJAE, THIRD)); + + sectionService.saveSection(new SectionSaveReqDto(LINE_SINBUNDANG, STATION_GANGNAM, STATION_CITIZEN_FOREST)); + sectionService.addStation(new SectionStationAddReqDto(LINE_SINBUNDANG, STATION_YANGJAE, SECOND)); + } + + private void saveStation() { + String[] stationNames = {STATION_GYODAE, STATION_GANGNAM, STATION_YEOKSAM, STATION_SOUTH_TERMINAL, STATION_YANGJAE, STATION_CITIZEN_FOREST, STATION_MAEBONG}; + for (String stationName : stationNames) { + stationService.saveStation(new StationSaveReqDto(stationName)); + } + } +} diff --git a/src/main/java/subway/domain/Distance.java b/src/main/java/subway/domain/distanceTime/Distance.java similarity index 87% rename from src/main/java/subway/domain/Distance.java rename to src/main/java/subway/domain/distanceTime/Distance.java index 824153e08..a5c54a9fb 100644 --- a/src/main/java/subway/domain/Distance.java +++ b/src/main/java/subway/domain/distanceTime/Distance.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.distanceTime; import java.math.BigDecimal; diff --git a/src/main/java/subway/domain/DistanceTime.java b/src/main/java/subway/domain/distanceTime/DistanceTime.java similarity index 85% rename from src/main/java/subway/domain/DistanceTime.java rename to src/main/java/subway/domain/distanceTime/DistanceTime.java index e4fec8f7d..518657754 100644 --- a/src/main/java/subway/domain/DistanceTime.java +++ b/src/main/java/subway/domain/distanceTime/DistanceTime.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.distanceTime; public class DistanceTime { private final Distance distance; diff --git a/src/main/java/subway/domain/distanceTime/DistanceTimeService.java b/src/main/java/subway/domain/distanceTime/DistanceTimeService.java new file mode 100644 index 000000000..f6ac944c5 --- /dev/null +++ b/src/main/java/subway/domain/distanceTime/DistanceTimeService.java @@ -0,0 +1,4 @@ +package subway.domain.distanceTime; + +public class DistanceTimeService { +} diff --git a/src/main/java/subway/domain/Time.java b/src/main/java/subway/domain/distanceTime/Time.java similarity index 87% rename from src/main/java/subway/domain/Time.java rename to src/main/java/subway/domain/distanceTime/Time.java index 755da947f..426303cc9 100644 --- a/src/main/java/subway/domain/Time.java +++ b/src/main/java/subway/domain/distanceTime/Time.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.distanceTime; import java.math.BigDecimal; From 8e21c44d86141170fd26569f311371ea47df414b Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 16:36:07 +0900 Subject: [PATCH 13/19] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5(=EA=B5=AC=EA=B0=84=EB=A7=88=EB=8B=A4=20=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC,=20=EC=8B=9C=EA=B0=84=20=ED=8F=AC=ED=95=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 초기 저장을 완료함 --- docs/README.md | 3 +- src/main/java/subway/DataInitService.java | 66 +++++++++++++++++++ src/main/java/subway/SearchService.java | 17 +++++ src/main/java/subway/SubwayManageApp.java | 12 ++++ .../subway/domain/distanceTime/Distance.java | 18 +++-- .../domain/distanceTime/DistanceTime.java | 11 ---- .../distanceTime/DistanceTimeService.java | 4 -- .../java/subway/domain/distanceTime/Time.java | 18 +++-- .../exception/DistanceTimeException.java | 14 ++++ src/main/java/subway/exception/ErrorCode.java | 6 +- .../view/selection/SearchSelection.java | 12 ++++ src/test/java/subway/JGraphtTest.java | 4 +- 12 files changed, 154 insertions(+), 31 deletions(-) create mode 100644 src/main/java/subway/SearchService.java delete mode 100644 src/main/java/subway/domain/distanceTime/DistanceTime.java delete mode 100644 src/main/java/subway/domain/distanceTime/DistanceTimeService.java create mode 100644 src/main/java/subway/exception/DistanceTimeException.java diff --git a/docs/README.md b/docs/README.md index 3413c32b1..1212d1aec 100644 --- a/docs/README.md +++ b/docs/README.md @@ -111,8 +111,7 @@ - [x] 노선 저장 - [x] 구간 저장 - [x] 초기 저장 (시간(분) 미포함) -- [ ] 지하철 구간마다 시간(분) 저장 -- [ ] 초기 저장(구간마다 시간 포함) +- [x] 초기 저장(구간마다 거리, 시간 포함) - [ ] 1을 입력시 최단 거리 조회 - [ ] 출발역을 입력 - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. diff --git a/src/main/java/subway/DataInitService.java b/src/main/java/subway/DataInitService.java index 9d7ee92c2..fbc44d6ff 100644 --- a/src/main/java/subway/DataInitService.java +++ b/src/main/java/subway/DataInitService.java @@ -1,5 +1,10 @@ package subway; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import org.jgrapht.graph.DefaultWeightedEdge; +import org.jgrapht.graph.WeightedMultigraph; +import subway.domain.distanceTime.Distance; +import subway.domain.distanceTime.Time; import subway.domain.section.SectionService; import subway.domain.section.dto.SectionSaveReqDto; import subway.domain.section.dto.SectionStationAddReqDto; @@ -17,9 +22,22 @@ public class DataInitService { private static final String LINE_TWO = "2호선"; private static final String LINE_THREE = "3호선"; private static final String LINE_SINBUNDANG = "신분당선"; + private static final int SECOND = 2; private static final int THIRD = 3; + private static final int KM_ONE = 1; + private static final int KM_TWO = 2; + private static final int KM_THREE = 3; + private static final int KM_SIX = 6; + private static final int KM_TEN = 10; + + private static final int MINUTE_ONE = 1; + private static final int MINUTE_TWO = 2; + private static final int MINUTE_THREE = 3; + private static final int MINUTE_FIVE = 5; + private static final int MINUTE_EIGHT = 8; + private final StationService stationService; private final SectionService sectionService; @@ -31,6 +49,54 @@ public DataInitService(StationService stationService, SectionService sectionServ public void init() { saveStation(); saveSection(); + saveDistance(); + saveTime(); + } + + private void saveDistance() { + WeightedMultigraph graph = getStringDefaultWeightedEdgeWeightedMultigraph(); + + graph.setEdgeWeight(graph.addEdge(STATION_GYODAE, STATION_GANGNAM), new Distance(KM_TWO).getKm()); + graph.setEdgeWeight(graph.addEdge(STATION_GANGNAM, STATION_YEOKSAM), new Distance(KM_TWO).getKm()); + + graph.setEdgeWeight(graph.addEdge(STATION_GYODAE, STATION_SOUTH_TERMINAL), new Distance(KM_THREE).getKm()); + graph.setEdgeWeight(graph.addEdge(STATION_SOUTH_TERMINAL, STATION_YANGJAE), new Distance(KM_SIX).getKm()); + graph.setEdgeWeight(graph.addEdge(STATION_YANGJAE, STATION_MAEBONG), new Distance(KM_ONE).getKm()); + + graph.setEdgeWeight(graph.addEdge(STATION_GANGNAM, STATION_YANGJAE), new Distance(KM_TWO).getKm()); + graph.setEdgeWeight(graph.addEdge(STATION_YANGJAE, STATION_CITIZEN_FOREST), new Distance(KM_TEN).getKm()); + + DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); + SearchService.addDijkstraShortestPath(dijkstraShortestPath); + } + + private void saveTime() { + WeightedMultigraph graph = getStringDefaultWeightedEdgeWeightedMultigraph(); + + graph.setEdgeWeight(graph.addEdge(STATION_GYODAE, STATION_GANGNAM), new Time(MINUTE_THREE).getMinute()); + graph.setEdgeWeight(graph.addEdge(STATION_GANGNAM, STATION_YEOKSAM), new Time(MINUTE_THREE).getMinute()); + + graph.setEdgeWeight(graph.addEdge(STATION_GYODAE, STATION_SOUTH_TERMINAL), new Time(MINUTE_TWO).getMinute()); + graph.setEdgeWeight(graph.addEdge(STATION_SOUTH_TERMINAL, STATION_YANGJAE), new Time(MINUTE_FIVE).getMinute()); + graph.setEdgeWeight(graph.addEdge(STATION_YANGJAE, STATION_MAEBONG), new Time(MINUTE_ONE).getMinute()); + + graph.setEdgeWeight(graph.addEdge(STATION_GANGNAM, STATION_YANGJAE), new Time(MINUTE_EIGHT).getMinute()); + graph.setEdgeWeight(graph.addEdge(STATION_YANGJAE, STATION_CITIZEN_FOREST), new Time(MINUTE_THREE).getMinute()); + + DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); + SearchService.addDijkstraShortestPath(dijkstraShortestPath); + } + + private WeightedMultigraph getStringDefaultWeightedEdgeWeightedMultigraph() { + WeightedMultigraph graph = new WeightedMultigraph(DefaultWeightedEdge.class); + graph.addVertex(STATION_GYODAE); + graph.addVertex(STATION_GANGNAM); + graph.addVertex(STATION_YEOKSAM); + graph.addVertex(STATION_SOUTH_TERMINAL); + graph.addVertex(STATION_YANGJAE); + graph.addVertex(STATION_MAEBONG); + graph.addVertex(STATION_CITIZEN_FOREST); + return graph; } private void saveSection() { diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java new file mode 100644 index 000000000..9e292d04c --- /dev/null +++ b/src/main/java/subway/SearchService.java @@ -0,0 +1,17 @@ +package subway; + +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; + +import java.util.ArrayList; +import java.util.List; + +public class SearchService { + private static final List dijkstraShortestPaths = new ArrayList<>(); + + public SearchService() { + } + + public static void addDijkstraShortestPath(DijkstraShortestPath dijkstraShortestPath) { + dijkstraShortestPaths.add(dijkstraShortestPath); + } +} diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 64d97fb60..8bf26fa14 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -38,6 +38,18 @@ private void manageSearch() { SearchView searchView = new SearchView(outputView); searchView.showOptions(); SearchSelection searchSelection = new SearchSelection(inputView.inputNextLine()); + chooseSearchOption(searchSelection); + } + + private void chooseSearchOption(SearchSelection searchSelection) { + if (searchSelection.isOptionOne()) { + + } + if (searchSelection.isOptionTwo()) { + } + if (searchSelection.isBack()) { + return; + } } } diff --git a/src/main/java/subway/domain/distanceTime/Distance.java b/src/main/java/subway/domain/distanceTime/Distance.java index a5c54a9fb..a92033ab6 100644 --- a/src/main/java/subway/domain/distanceTime/Distance.java +++ b/src/main/java/subway/domain/distanceTime/Distance.java @@ -1,15 +1,23 @@ package subway.domain.distanceTime; -import java.math.BigDecimal; +import subway.exception.DistanceTimeException; +import subway.exception.ErrorCode; public class Distance { - private BigDecimal km; + private int km; - public Distance(BigDecimal km) { + public Distance(int km) { this.km = km; + validate(km); } - public static Distance km(double km) { - return new Distance(BigDecimal.valueOf(km)); + private void validate(int km) { + if (km < 1) { + throw new DistanceTimeException(ErrorCode.INPUT_VALUE_MUST_NATURAL); + } + } + + public int getKm() { + return km; } } diff --git a/src/main/java/subway/domain/distanceTime/DistanceTime.java b/src/main/java/subway/domain/distanceTime/DistanceTime.java deleted file mode 100644 index 518657754..000000000 --- a/src/main/java/subway/domain/distanceTime/DistanceTime.java +++ /dev/null @@ -1,11 +0,0 @@ -package subway.domain.distanceTime; - -public class DistanceTime { - private final Distance distance; - private final Time time; - - public DistanceTime(Distance distance, Time time) { - this.distance = distance; - this.time = time; - } -} diff --git a/src/main/java/subway/domain/distanceTime/DistanceTimeService.java b/src/main/java/subway/domain/distanceTime/DistanceTimeService.java deleted file mode 100644 index f6ac944c5..000000000 --- a/src/main/java/subway/domain/distanceTime/DistanceTimeService.java +++ /dev/null @@ -1,4 +0,0 @@ -package subway.domain.distanceTime; - -public class DistanceTimeService { -} diff --git a/src/main/java/subway/domain/distanceTime/Time.java b/src/main/java/subway/domain/distanceTime/Time.java index 426303cc9..d45a381be 100644 --- a/src/main/java/subway/domain/distanceTime/Time.java +++ b/src/main/java/subway/domain/distanceTime/Time.java @@ -1,15 +1,23 @@ package subway.domain.distanceTime; -import java.math.BigDecimal; +import subway.exception.DistanceTimeException; +import subway.exception.ErrorCode; public class Time { - private BigDecimal minute; + private int minute; - public Time(BigDecimal minute) { + public Time(int minute) { this.minute = minute; + validate(minute); } - public static Time minute(long minute) { - return new Time(BigDecimal.valueOf(minute)); + private void validate(int minute) { + if (minute < 1) { + throw new DistanceTimeException(ErrorCode.INPUT_VALUE_MUST_NATURAL); + } + } + + public int getMinute() { + return minute; } } diff --git a/src/main/java/subway/exception/DistanceTimeException.java b/src/main/java/subway/exception/DistanceTimeException.java new file mode 100644 index 000000000..3d375750b --- /dev/null +++ b/src/main/java/subway/exception/DistanceTimeException.java @@ -0,0 +1,14 @@ +package subway.exception; + +public class DistanceTimeException extends IllegalArgumentException { + private final ErrorCode errorCode; + + public DistanceTimeException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } +} diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index b57668236..91c736cac 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -23,10 +23,10 @@ public enum ErrorCode { //Section SECTION_SAME_STATION_NAME("SE001", Prefix.ERROR.getPrefix() + "상행 좀점역과 하행 종점역의 이름이 같을 수 없습니다."), - SECTION_NOT_FOUND("SE002", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."); - - + SECTION_NOT_FOUND("SE002", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."), + //DistanceTime + INPUT_VALUE_MUST_NATURAL("D001", Prefix.ERROR.getPrefix() + "1이상의 자연수만 입력 가능합니다."); private final String code; private final String message; diff --git a/src/main/java/subway/view/selection/SearchSelection.java b/src/main/java/subway/view/selection/SearchSelection.java index de8af9edd..22e6844da 100644 --- a/src/main/java/subway/view/selection/SearchSelection.java +++ b/src/main/java/subway/view/selection/SearchSelection.java @@ -26,4 +26,16 @@ private void validate(String option) { public String getOption() { return option; } + + public boolean isOptionOne() { + return option.equals(OPTION_ONE); + } + + public boolean isOptionTwo() { + return option.equals(OPTION_TWO); + } + + public boolean isBack() { + return option.equals(OPTION_BACK) | option.equals(OPTION_BACK_LOWERCASE); + } } diff --git a/src/test/java/subway/JGraphtTest.java b/src/test/java/subway/JGraphtTest.java index 4f5f76536..5cfd1ebff 100644 --- a/src/test/java/subway/JGraphtTest.java +++ b/src/test/java/subway/JGraphtTest.java @@ -17,12 +17,14 @@ public void getDijkstraShortestPath() { graph.addVertex("v2"); graph.addVertex("v3"); graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2); - graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2); + graph.setEdgeWeight(graph.addEdge("v2", "v3"), 3); graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100); DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList(); + double pathWeight = dijkstraShortestPath.getPathWeight("v3", "v1"); assertThat(shortestPath.size()).isEqualTo(3); + assertThat(pathWeight).isEqualTo(5); } } From ca772e455e3614338ff975fd2afb7df033ab269c Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 16:48:28 +0900 Subject: [PATCH 14/19] =?UTF-8?q?feat:=20=EC=B6=9C=EB=B0=9C=EC=97=AD?= =?UTF-8?q?=EC=9D=84=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 6 ++-- src/main/java/subway/SearchService.java | 30 ++++++++++++++++++- src/main/java/subway/SubwayManageApp.java | 3 +- src/main/java/subway/exception/ErrorCode.java | 2 ++ src/main/java/subway/view/OutputView.java | 3 +- .../java/subway/view/screen/SearchView.java | 7 +++++ 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1212d1aec..fab262cd6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -113,9 +113,9 @@ - [x] 초기 저장 (시간(분) 미포함) - [x] 초기 저장(구간마다 거리, 시간 포함) - [ ] 1을 입력시 최단 거리 조회 - - [ ] 출발역을 입력 - - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - - `에러 발생` + - [x] 출발역을 입력 + - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `StationException` - [ ] 도착역 역을 입력 - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `에러 발생` diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java index 9e292d04c..cf40dfd01 100644 --- a/src/main/java/subway/SearchService.java +++ b/src/main/java/subway/SearchService.java @@ -1,17 +1,45 @@ package subway; import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import subway.domain.station.Station; +import subway.domain.station.StationRepository; +import subway.domain.station.StationService; +import subway.exception.ErrorCode; +import subway.exception.SectionException; +import subway.exception.StationException; +import subway.view.InputView; +import subway.view.screen.SearchView; import java.util.ArrayList; import java.util.List; public class SearchService { private static final List dijkstraShortestPaths = new ArrayList<>(); + private static final int DISTANCE_INDEX = 0; + private static final int TIME_INDEX = 1; - public SearchService() { + private final InputView inputView; + private final SearchView searchView; + + public SearchService(InputView inputView, SearchView searchView) { + this.inputView = inputView; + this.searchView = searchView; } public static void addDijkstraShortestPath(DijkstraShortestPath dijkstraShortestPath) { dijkstraShortestPaths.add(dijkstraShortestPath); } + + public void findShortestDistance() { + searchView.printAdd(); + String firstStationName = inputView.inputNextLine(); + Station firstStation = StationRepository.findByName(firstStationName); + + + } + private void checkSameName(String firstStationName, String downwardStationName) { + if (firstStationName.equals(downwardStationName)) { + throw new StationException(ErrorCode.SECTION_SAME_STATION_NAME); + } + } } diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 8bf26fa14..062553dcf 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -42,8 +42,9 @@ private void manageSearch() { } private void chooseSearchOption(SearchSelection searchSelection) { + SearchService searchService = new SearchService(inputView, new SearchView(outputView)); if (searchSelection.isOptionOne()) { - + searchService.findShortestDistance(); } if (searchSelection.isOptionTwo()) { diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index 91c736cac..2afacb348 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -13,6 +13,8 @@ public enum ErrorCode { STATION_INVALID_CHARACTER("ST004", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."), STATION_NOT_FOUND("ST006", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 지하철 역이 없습니다."), + STATION_SAME_NAME("ST007", Prefix.ERROR.getPrefix() + "출발역과 도착역의 이름이 같을 수 없습니다."), + //Line LINE_NAME_LENGTH_ERROR("L001", Prefix.ERROR.getPrefix() + "노선 이름은 2글자 이상이어야 합니다."), diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java index f423cee88..930dd6764 100644 --- a/src/main/java/subway/view/OutputView.java +++ b/src/main/java/subway/view/OutputView.java @@ -22,7 +22,8 @@ public void printOptions(String[] strings) { public void printSharp(String text) { sb.append(Prefix.ENTER.getPrefix()); - sb.append(text).append(Prefix.ENTER.getPrefix()); + sb.append(Prefix.SHARP.getPrefix()); + sb.append(text); System.out.println(sb.toString()); clearSb(); diff --git a/src/main/java/subway/view/screen/SearchView.java b/src/main/java/subway/view/screen/SearchView.java index 6320b1717..6597a903d 100644 --- a/src/main/java/subway/view/screen/SearchView.java +++ b/src/main/java/subway/view/screen/SearchView.java @@ -8,6 +8,9 @@ public class SearchView { private static final String DISTANCE = Prefix.ONE.getPrefix() + "최단 거리"; private static final String TIME = Prefix.TWO.getPrefix() + "최소 시간"; private static final String BACK = Prefix.BACK.getPrefix() + "돌아가기"; + private static final String PRINT_ADD = "출발역을 입력하세요."; + private static final String PRINT_ADD_SECOND = "도착역을 입력하세요."; + private static final String PRINT_AFTER_ADD = "조회결과."; private final OutputView outputView; @@ -18,4 +21,8 @@ public SearchView(OutputView outputView) { public void showOptions() { outputView.printOptions(new String[]{MAIN, DISTANCE, TIME, BACK}); } + + public void printAdd() { + outputView.printSharp(PRINT_ADD); + } } From 1caacc358a3f81a5e304ae1a15c8898e477433f6 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 17:06:46 +0900 Subject: [PATCH 15/19] =?UTF-8?q?feat:=20=EB=8F=84=EC=B0=A9=EC=97=AD=20?= =?UTF-8?q?=EC=97=AD=EC=9D=84=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. --- docs/README.md | 10 ++++---- src/main/java/subway/SearchService.java | 24 +++++++++++++++---- src/main/java/subway/view/OutputView.java | 7 ++++++ .../java/subway/view/screen/SearchView.java | 21 +++++++++++++++- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index fab262cd6..f15a68d5d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -116,13 +116,13 @@ - [x] 출발역을 입력 - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `StationException` - - [ ] 도착역 역을 입력 - - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - - `에러 발생` + - [x] 도착역 역을 입력 + - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - `StationException` - [ ] 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다 - `에러 발생` - - [ ] 출발역과 도착역이 같으면 에러를 출력한다 - - `에러 발생` + - [x] 출발역과 도착역이 같으면 에러를 출력한다 + - `StationException` - [ ] 최단 거리를 조회한다. 테스트 - [ ] 최단 거리를 조회한다. diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java index cf40dfd01..afa9bc7ec 100644 --- a/src/main/java/subway/SearchService.java +++ b/src/main/java/subway/SearchService.java @@ -1,11 +1,10 @@ package subway; +import org.jgrapht.GraphPath; import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import subway.domain.station.Station; import subway.domain.station.StationRepository; -import subway.domain.station.StationService; import subway.exception.ErrorCode; -import subway.exception.SectionException; import subway.exception.StationException; import subway.view.InputView; import subway.view.screen.SearchView; @@ -35,11 +34,26 @@ public void findShortestDistance() { String firstStationName = inputView.inputNextLine(); Station firstStation = StationRepository.findByName(firstStationName); + searchView.printSecondAdd(); + String secondStationName = inputView.inputNextLine(); + Station secondStation = StationRepository.findByName(secondStationName); + checkSameName(firstStationName, secondStationName); + searchView.printAfterAdd(); + printDistance(firstStation, secondStation); } - private void checkSameName(String firstStationName, String downwardStationName) { - if (firstStationName.equals(downwardStationName)) { - throw new StationException(ErrorCode.SECTION_SAME_STATION_NAME); + + private void printDistance(Station firstStation, Station secondStation) { + DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(DISTANCE_INDEX); + double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); + GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); + + searchView.printList(path, pathWeight); + } + + private void checkSameName(String firstStationName, String secondStationName) { + if (firstStationName.equals(secondStationName)) { + throw new StationException(ErrorCode.STATION_SAME_NAME); } } } diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java index 930dd6764..0f4cab5fc 100644 --- a/src/main/java/subway/view/OutputView.java +++ b/src/main/java/subway/view/OutputView.java @@ -29,6 +29,13 @@ public void printSharp(String text) { clearSb(); } + public void printInfos(String string) { + sb.append(Prefix.INFO.getPrefix()); + sb.append(string); + System.out.println(sb.toString()); + clearSb(); + } + private void clearSb() { sb.delete(START_INDEX, sb.length()); } diff --git a/src/main/java/subway/view/screen/SearchView.java b/src/main/java/subway/view/screen/SearchView.java index 6597a903d..53fb54757 100644 --- a/src/main/java/subway/view/screen/SearchView.java +++ b/src/main/java/subway/view/screen/SearchView.java @@ -1,8 +1,11 @@ package subway.view.screen; +import org.jgrapht.GraphPath; import subway.view.OutputView; import subway.view.Prefix; +import java.util.List; + public class SearchView { private static final String MAIN = Prefix.SHARP.getPrefix() + "경로 기준"; private static final String DISTANCE = Prefix.ONE.getPrefix() + "최단 거리"; @@ -10,7 +13,7 @@ public class SearchView { private static final String BACK = Prefix.BACK.getPrefix() + "돌아가기"; private static final String PRINT_ADD = "출발역을 입력하세요."; private static final String PRINT_ADD_SECOND = "도착역을 입력하세요."; - private static final String PRINT_AFTER_ADD = "조회결과."; + private static final String PRINT_AFTER_ADD = "조회결과"; private final OutputView outputView; @@ -25,4 +28,20 @@ public void showOptions() { public void printAdd() { outputView.printSharp(PRINT_ADD); } + + public void printAfterAdd() { + outputView.printSharp(PRINT_AFTER_ADD); + } + + public void printSecondAdd() { + outputView.printSharp(PRINT_ADD_SECOND); + } + + public void printList(GraphPath path, double pathWeight) { + outputView.printInfos(Prefix.CONTOUR.getPrefix()); + outputView.printInfos("총 거리: " + pathWeight + "km"); + outputView.printInfos(Prefix.CONTOUR.getPrefix()); + + + } } From 5d1d19b6a0b30d03245fbb34eb4887f17fca2fa4 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 17:12:07 +0900 Subject: [PATCH 16/19] =?UTF-8?q?feat:=20=EC=B5=9C=EB=8B=A8=20=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=A1=B0=ED=9A=8C=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 +++---- src/main/java/subway/SearchService.java | 1 - src/main/java/subway/view/screen/SearchView.java | 6 ++++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index f15a68d5d..1330f50e1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -119,12 +119,11 @@ - [x] 도착역 역을 입력 - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `StationException` - - [ ] 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다 - - `에러 발생` - [x] 출발역과 도착역이 같으면 에러를 출력한다 - `StationException` - - [ ] 최단 거리를 조회한다. 테스트 - - [ ] 최단 거리를 조회한다. + - [x] 최단 거리를 조회한다. 테스트 + - [x] 최단 거리를 조회한다. + - [ ] 제대로 출력하기 - [ ] 2를 입력시 최소 시간 조회 - [ ] 출발역을 입력 diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java index afa9bc7ec..9fa41c10d 100644 --- a/src/main/java/subway/SearchService.java +++ b/src/main/java/subway/SearchService.java @@ -47,7 +47,6 @@ private void printDistance(Station firstStation, Station secondStation) { DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(DISTANCE_INDEX); double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); - searchView.printList(path, pathWeight); } diff --git a/src/main/java/subway/view/screen/SearchView.java b/src/main/java/subway/view/screen/SearchView.java index 53fb54757..3986814d1 100644 --- a/src/main/java/subway/view/screen/SearchView.java +++ b/src/main/java/subway/view/screen/SearchView.java @@ -4,6 +4,7 @@ import subway.view.OutputView; import subway.view.Prefix; +import java.util.Arrays; import java.util.List; public class SearchView { @@ -42,6 +43,11 @@ public void printList(GraphPath path, double pathWeight) { outputView.printInfos("총 거리: " + pathWeight + "km"); outputView.printInfos(Prefix.CONTOUR.getPrefix()); + String paths = path.getEdgeList().toString(); + String[] split = paths.split(" : "); + for (String singlePath : split) { + outputView.printInfos(singlePath); + } } } From 321a177dcf4eb300c4bdcb04b5fc43d69eac63ca Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 17:16:39 +0900 Subject: [PATCH 17/19] =?UTF-8?q?feat:=202=EB=A5=BC=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=8B=9C=20=EC=B5=9C=EC=86=8C=20=EC=8B=9C=EA=B0=84=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 21 ++++++++--------- src/main/java/subway/SearchService.java | 28 ++++++++++++++++++++--- src/main/java/subway/SubwayManageApp.java | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1330f50e1..348344641 100644 --- a/docs/README.md +++ b/docs/README.md @@ -112,7 +112,7 @@ - [x] 구간 저장 - [x] 초기 저장 (시간(분) 미포함) - [x] 초기 저장(구간마다 거리, 시간 포함) -- [ ] 1을 입력시 최단 거리 조회 +- [x] 1을 입력시 최단 거리 조회 - [x] 출발역을 입력 - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `StationException` @@ -121,23 +121,20 @@ - `StationException` - [x] 출발역과 도착역이 같으면 에러를 출력한다 - `StationException` - - [x] 최단 거리를 조회한다. 테스트 - [x] 최단 거리를 조회한다. - [ ] 제대로 출력하기 -- [ ] 2를 입력시 최소 시간 조회 - - [ ] 출발역을 입력 - - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. +- [x] 2를 입력시 최소 시간 조회 + - [x] 출발역을 입력 + - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `에러 발생` - - [ ] 도착역 역을 입력 - - [ ] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. + - [x] 도착역 역을 입력 + - [x] 저장소에 저장되어 있는 지하철 역이 아닐 시 에러가 발생한다. - `에러 발생` - - [ ] 출발역과 도착역이 연결되어 있지 않으면 에러를 출력한다 - - `에러 발생` - - [ ] 출발역과 도착역이 같으면 에러를 출력한다 + - [x] 출발역과 도착역이 같으면 에러를 출력한다 - `에러 발생` - - [ ] 최소 시간을 조회한다. 테스트 - - [ ] 최소 시간를 조회한다. + - [x] 최소 시간를 조회한다. + - [ ] 제대로 출력하기 ### **에러 발생해도 서비스가 죽지 않아야 한다** - [ ] 에러 핸들링 diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java index 9fa41c10d..3a2312523 100644 --- a/src/main/java/subway/SearchService.java +++ b/src/main/java/subway/SearchService.java @@ -14,8 +14,8 @@ public class SearchService { private static final List dijkstraShortestPaths = new ArrayList<>(); - private static final int DISTANCE_INDEX = 0; - private static final int TIME_INDEX = 1; + private static final int DISTANCE_INDEX = 1; + private static final int TIME_INDEX = 0; private final InputView inputView; private final SearchView searchView; @@ -43,16 +43,38 @@ public void findShortestDistance() { printDistance(firstStation, secondStation); } - private void printDistance(Station firstStation, Station secondStation) { + public void findShortestTime() { + searchView.printAdd(); + String firstStationName = inputView.inputNextLine(); + Station firstStation = StationRepository.findByName(firstStationName); + + searchView.printSecondAdd(); + String secondStationName = inputView.inputNextLine(); + Station secondStation = StationRepository.findByName(secondStationName); + checkSameName(firstStationName, secondStationName); + + searchView.printAfterAdd(); + printTime(firstStation, secondStation); + } + + private void printTime(Station firstStation, Station secondStation) { DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(DISTANCE_INDEX); double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); searchView.printList(path, pathWeight); } + private void printDistance(Station firstStation, Station secondStation) { + DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(TIME_INDEX); + double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); + GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); + searchView.printList(path, pathWeight); + } + private void checkSameName(String firstStationName, String secondStationName) { if (firstStationName.equals(secondStationName)) { throw new StationException(ErrorCode.STATION_SAME_NAME); } } + } diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 062553dcf..59970623a 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -47,7 +47,7 @@ private void chooseSearchOption(SearchSelection searchSelection) { searchService.findShortestDistance(); } if (searchSelection.isOptionTwo()) { - + searchService.findShortestTime(); } if (searchSelection.isBack()) { return; From 54da7a1152b252fc8110aa7c1f2648784905a821 Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 17:22:50 +0900 Subject: [PATCH 18/19] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=EA=B0=80=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=B4=EB=8F=84=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=EA=B0=80=20=EC=A3=BD=EC=A7=80=20=EC=95=8A=EC=95=84?= =?UTF-8?q?=EC=95=BC=20=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 +-- src/main/java/subway/SubwayManageApp.java | 25 +++++++++++++---- src/main/java/subway/exception/ErrorCode.java | 28 +++++++++---------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/docs/README.md b/docs/README.md index 348344641..98c3619ad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -136,5 +136,5 @@ - [x] 최소 시간를 조회한다. - [ ] 제대로 출력하기 -### **에러 발생해도 서비스가 죽지 않아야 한다** -- [ ] 에러 핸들링 +### **에러가 발생해도 서비스가 죽지 않아야 한다** +- [x] 에러 핸들링 diff --git a/src/main/java/subway/SubwayManageApp.java b/src/main/java/subway/SubwayManageApp.java index 59970623a..7f951dcf7 100644 --- a/src/main/java/subway/SubwayManageApp.java +++ b/src/main/java/subway/SubwayManageApp.java @@ -1,6 +1,7 @@ package subway; import subway.view.InputView; +import subway.view.Prefix; import subway.view.screen.SearchView; import subway.view.selection.MainSelection; import subway.view.OutputView; @@ -20,8 +21,14 @@ public void startApp() { MainView mainView = new MainView(outputView); while (true) { mainView.showOptions(); - MainSelection mainSelection = new MainSelection(inputView.inputNextLine()); - chooseOption(mainSelection); + MainSelection mainSelection; + try { + mainSelection = new MainSelection(inputView.inputNextLine()); + chooseOption(mainSelection); + } catch (Exception exception) { + System.out.println(Prefix.ENTER.getPrefix() + Prefix.ERROR.getPrefix() + exception.getMessage()); + continue; + } if (mainSelection.isQuit()) { break; } @@ -36,9 +43,17 @@ private void chooseOption(MainSelection mainSelection) { private void manageSearch() { SearchView searchView = new SearchView(outputView); - searchView.showOptions(); - SearchSelection searchSelection = new SearchSelection(inputView.inputNextLine()); - chooseSearchOption(searchSelection); + while (true) { + try { + searchView.showOptions(); + SearchSelection searchSelection = new SearchSelection(inputView.inputNextLine()); + chooseSearchOption(searchSelection); + break; + } catch (Exception exception) { + System.out.println(Prefix.ENTER.getPrefix() + Prefix.ERROR.getPrefix() + exception.getMessage()); + continue; + } + } } private void chooseSearchOption(SearchSelection searchSelection) { diff --git a/src/main/java/subway/exception/ErrorCode.java b/src/main/java/subway/exception/ErrorCode.java index 2afacb348..03c7ab2e5 100644 --- a/src/main/java/subway/exception/ErrorCode.java +++ b/src/main/java/subway/exception/ErrorCode.java @@ -8,27 +8,27 @@ public enum ErrorCode { //Station STATION_EMTPY("ST001", "존재하지 않는 역입니다."), - STATION_NAME_LENGTH_ERROR("ST002", Prefix.ERROR.getPrefix() + "역 이름은 2글자 이상이어야 합니다."), - STATION_INVALID_LAST_NAME("ST003", Prefix.ERROR.getPrefix() + "마지막 글자에 역이 들어가야합니다."), - STATION_INVALID_CHARACTER("ST004", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), - STATION_ALREADY_EXIST("ST005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 역입니다."), - STATION_NOT_FOUND("ST006", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 지하철 역이 없습니다."), - STATION_SAME_NAME("ST007", Prefix.ERROR.getPrefix() + "출발역과 도착역의 이름이 같을 수 없습니다."), + STATION_NAME_LENGTH_ERROR("ST002", "역 이름은 2글자 이상이어야 합니다."), + STATION_INVALID_LAST_NAME("ST003", "마지막 글자에 역이 들어가야합니다."), + STATION_INVALID_CHARACTER("ST004", "한글, 숫자만 입력 가능합니다."), + STATION_ALREADY_EXIST("ST005", "이미 등록된 지하철 역입니다."), + STATION_NOT_FOUND("ST006", "입력된 이름으로 등록된 지하철 역이 없습니다."), + STATION_SAME_NAME("ST007", "출발역과 도착역의 이름이 같을 수 없습니다."), //Line - LINE_NAME_LENGTH_ERROR("L001", Prefix.ERROR.getPrefix() + "노선 이름은 2글자 이상이어야 합니다."), - LINE_INVALID_LAST_NAME("L002", Prefix.ERROR.getPrefix() + "마지막 글자에 선이 들어가야합니다."), - LINE_INVALID_CHARACTER("L003", Prefix.ERROR.getPrefix() + "한글, 숫자만 입력 가능합니다."), - LINE_NOT_FOUND("S004", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."), - LINE_ALREADY_EXIST("S005", Prefix.ERROR.getPrefix() + "이미 등록된 지하철 노선입니다."), + LINE_NAME_LENGTH_ERROR("L001", "노선 이름은 2글자 이상이어야 합니다."), + LINE_INVALID_LAST_NAME("L002", "마지막 글자에 선이 들어가야합니다."), + LINE_INVALID_CHARACTER("L003", "한글, 숫자만 입력 가능합니다."), + LINE_NOT_FOUND("S004", "입력된 이름으로 등록된 노선이 없습니다."), + LINE_ALREADY_EXIST("S005", "이미 등록된 지하철 노선입니다."), //Section - SECTION_SAME_STATION_NAME("SE001", Prefix.ERROR.getPrefix() + "상행 좀점역과 하행 종점역의 이름이 같을 수 없습니다."), - SECTION_NOT_FOUND("SE002", Prefix.ERROR.getPrefix() + "입력된 이름으로 등록된 노선이 없습니다."), + SECTION_SAME_STATION_NAME("SE001", "상행 좀점역과 하행 종점역의 이름이 같을 수 없습니다."), + SECTION_NOT_FOUND("SE002", "입력된 이름으로 등록된 노선이 없습니다."), //DistanceTime - INPUT_VALUE_MUST_NATURAL("D001", Prefix.ERROR.getPrefix() + "1이상의 자연수만 입력 가능합니다."); + INPUT_VALUE_MUST_NATURAL("D001", "1이상의 자연수만 입력 가능합니다."); private final String code; private final String message; From 596d3807caa7aa770ba58c34016e4cfe786fb36e Mon Sep 17 00:00:00 2001 From: Livenow14 Date: Sat, 19 Dec 2020 17:45:10 +0900 Subject: [PATCH 19/19] =?UTF-8?q?feat:=20=EA=B0=81=EA=B0=81=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84,=20=EA=B1=B0=EB=A6=AC=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 +- src/main/java/subway/SearchService.java | 13 +++--- .../subway/domain/section/SectionService.java | 3 -- .../java/subway/view/screen/SearchView.java | 40 ++++++++++++++----- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/docs/README.md b/docs/README.md index 98c3619ad..2e3a3bb51 100644 --- a/docs/README.md +++ b/docs/README.md @@ -122,7 +122,6 @@ - [x] 출발역과 도착역이 같으면 에러를 출력한다 - `StationException` - [x] 최단 거리를 조회한다. - - [ ] 제대로 출력하기 - [x] 2를 입력시 최소 시간 조회 - [x] 출발역을 입력 @@ -134,7 +133,8 @@ - [x] 출발역과 도착역이 같으면 에러를 출력한다 - `에러 발생` - [x] 최소 시간를 조회한다. - - [ ] 제대로 출력하기 + +- [ ] 최단 거리 최소시간 같이 출력 ### **에러가 발생해도 서비스가 죽지 않아야 한다** - [x] 에러 핸들링 diff --git a/src/main/java/subway/SearchService.java b/src/main/java/subway/SearchService.java index 3a2312523..a7891d206 100644 --- a/src/main/java/subway/SearchService.java +++ b/src/main/java/subway/SearchService.java @@ -14,8 +14,8 @@ public class SearchService { private static final List dijkstraShortestPaths = new ArrayList<>(); - private static final int DISTANCE_INDEX = 1; - private static final int TIME_INDEX = 0; + private static final int DISTANCE_INDEX = 0; + private static final int TIME_INDEX = 1; private final InputView inputView; private final SearchView searchView; @@ -58,17 +58,17 @@ public void findShortestTime() { } private void printTime(Station firstStation, Station secondStation) { - DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(DISTANCE_INDEX); + DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(TIME_INDEX); double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); - searchView.printList(path, pathWeight); + searchView.printTimeList(path, pathWeight); } private void printDistance(Station firstStation, Station secondStation) { - DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(TIME_INDEX); + DijkstraShortestPath dijkstraShortestPathDistance = dijkstraShortestPaths.get(DISTANCE_INDEX); double pathWeight = dijkstraShortestPathDistance.getPathWeight(firstStation.getName(), secondStation.getName()); GraphPath path = dijkstraShortestPathDistance.getPath(firstStation.getName(), secondStation.getName()); - searchView.printList(path, pathWeight); + searchView.printDistanceList(path, pathWeight); } private void checkSameName(String firstStationName, String secondStationName) { @@ -76,5 +76,4 @@ private void checkSameName(String firstStationName, String secondStationName) { throw new StationException(ErrorCode.STATION_SAME_NAME); } } - } diff --git a/src/main/java/subway/domain/section/SectionService.java b/src/main/java/subway/domain/section/SectionService.java index e7ce31e3d..09ce59425 100644 --- a/src/main/java/subway/domain/section/SectionService.java +++ b/src/main/java/subway/domain/section/SectionService.java @@ -4,7 +4,6 @@ import subway.domain.line.LineRepository; import subway.domain.section.dto.SectionSaveReqDto; import subway.domain.section.dto.SectionStationAddReqDto; -import subway.domain.section.dto.SectionStationDeleteReqDto; import subway.domain.station.Station; import subway.domain.station.StationRepository; import subway.domain.station.Stations; @@ -14,8 +13,6 @@ import subway.exception.StationException; import java.util.Arrays; -import java.util.Collections; -import java.util.List; public class SectionService { public static final int CONVERT_SEQUENCE = 1; diff --git a/src/main/java/subway/view/screen/SearchView.java b/src/main/java/subway/view/screen/SearchView.java index 3986814d1..966fec1a3 100644 --- a/src/main/java/subway/view/screen/SearchView.java +++ b/src/main/java/subway/view/screen/SearchView.java @@ -4,9 +4,6 @@ import subway.view.OutputView; import subway.view.Prefix; -import java.util.Arrays; -import java.util.List; - public class SearchView { private static final String MAIN = Prefix.SHARP.getPrefix() + "경로 기준"; private static final String DISTANCE = Prefix.ONE.getPrefix() + "최단 거리"; @@ -38,16 +35,37 @@ public void printSecondAdd() { outputView.printSharp(PRINT_ADD_SECOND); } - public void printList(GraphPath path, double pathWeight) { + public void printDistanceList(GraphPath path, double pathWeight) { outputView.printInfos(Prefix.CONTOUR.getPrefix()); - outputView.printInfos("총 거리: " + pathWeight + "km"); + outputView.printInfos("총 거리: " + (int)pathWeight + "km"); outputView.printInfos(Prefix.CONTOUR.getPrefix()); + path.getEdgeList().stream() + .forEach(edge -> { + String tmp = edge.toString(); + int index = tmp.indexOf(":"); + String substring = tmp.substring(1, index); + outputView.printInfos(substring); + }); + String lastText = path.getEdgeList().get(path.getEdgeList().size() - 1).toString(); + int index = lastText.indexOf(":"); + String substring = lastText.substring(index + 2, lastText.length() -1); + outputView.printInfos(substring); + } - String paths = path.getEdgeList().toString(); - String[] split = paths.split(" : "); - - for (String singlePath : split) { - outputView.printInfos(singlePath); - } + public void printTimeList(GraphPath path, double pathWeight) { + outputView.printInfos(Prefix.CONTOUR.getPrefix()); + outputView.printInfos("총 시간: " + (int)pathWeight + "분"); + outputView.printInfos(Prefix.CONTOUR.getPrefix()); + path.getEdgeList().stream() + .forEach(edge -> { + String tmp = edge.toString(); + int index = tmp.indexOf(":"); + String substring = tmp.substring(1, index); + outputView.printInfos(substring); + }); + String lastText = path.getEdgeList().get(path.getEdgeList().size() - 1).toString(); + int index = lastText.indexOf(":"); + String substring = lastText.substring(index + 2, lastText.length() -1); + outputView.printInfos(substring); } }