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

Filter by extension

Filter by extension

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

## 입력
- 메뉴나 기능 선택시 입력값이 범위 안의 입력인지 검증한다.
### 입력 예외 상황
- 메인과 관리 화면에서 보여주는 기능이 아닌경우
- 등록할 지하철 역 관련
- 이름의 길이가 2자 미만인 경우
- 이름이 '역'으로 끝나지 않는 경우
- 이름에 공백이 들어가는 경우
- 이름이 숫자와 한글이 아닌 경우
- 중복된 이름인 경우
- 등록할 노선 관련
- 이름의 길이가 2자 미만인 경우
- 이름이 '선'으로 끝나지 않는 경우
- 이름이 숫자와 한글이 아닌 경우
- 상행 종점역과 하행 종점역의 이름이 같은 경우
- 등록할 구간 관련
- 선택한 노선이 등록되지 않은 노선인 경우
- 역이름이 등록되지 않은 경우

<br>

## 출력
- 어플리케이션 화면 레이아웃 구성
1. 주 메뉴 화면
2. 기능 선택 화면
- 세부 기능 포함
3. 입력 안내 화면
4. 입력 결과 출력
- 입력 유도 메시지 출력
- 입력 반응 메시지 출력
- 기대 출력 결과시 '[INFO] ...'
- 에러시 '[ERROR] ...'

<br>

## 주요 로직
### 메인화면
- 선택한 메뉴로 이동 또는 기능을 실행한다.
- 역 관리, 노선 관리, 구간 관리 -> 세부 기능 선택 안내
- 지하철 노선도 출력 -> 기능 실행
- 종료 -> 어플리케이션 종료

### 역 관리 관련
- 역 등록
- 입력받은 역을 검증
- 검증 결과에 따라 저장소에 역 저장 후 [INFO]또는 [ERROR] 메시지 출력
- 역 삭제
- 입력받은 역을 검증
- 검증 결과에 따라 저장소에서 삭제 후 [INFO]또는 [ERROR] 메시지 출력
- 역 조회
- 저장소 모든 역을 호출하여 출력
- 돌아가기
- 메인 화면 호출

### 노선 관리 관련
- 노선 등록
1. 등록할 노선 이름 입력 검증
2. 노선의 상행 종점역 이름 입력 검증
3. 노선의 하행 종점역 이름 입력 검증
4. 검증 후 결과에 따라 저장소에 저장 후 [INFO]또는 [ERROR] 메시지 출력
- 노선 삭제
- 입력받은 노선 검증
- 검증 결과에 따라 저장소에서 삭제 후 [INFO]또는 [ERROR] 메시지 출력
- 노선 조회
- 저장소 모든 노선 호출하여 출력
- 돌아가기
- 메인 화면 호출

### 구간 관리 관련
- 구간 등록(노선에 역을 추가)
- 구간 등록할 노선 검증
- 역 이름 검증
- 순서 검증
- 검증 후 결과에 따라 저장소에 저장 및 역 재배열 후 [INFO]또는 [ERROR] 메시지 출력
- 구간 삭제
- 삭제할 구간 노선 검증
- 역 이름 검증
- 검증 후 결과에 따라 저장소에서 삭제 및 역 재배열 후 [INFO]또는 [ERROR] 메시지 출력
- 돌아가기
- 메인 화면 호출

### 지하철 노선도 출력 관련
- 노선도는 이름 순으로 출력한다
- 각 노선도는 노선의 이름과 등록된 역을 포함한다
- 등록된 역은 순서대로 출력한다

<br>

## 초기 설정
- 역 등록
- 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역
- 노선 등록(왼쪽 끝이 상행 종점)
- 2호선: 교대역 - 강남역 - 역삼역
- 3호선: 교대역 - 남부터미널역 - 양재역 - 매봉역
- 신분당선: 강남역 - 양재역 - 양재시민의숲역
5 changes: 5 additions & 0 deletions src/main/java/subway/Application.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package subway;

import subway.controller.SubwayMap;

import java.util.Scanner;

public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
DummyDataSetting.run();
SubwayMap subwayMap = new SubwayMap();
subwayMap.Run(scanner);
}
}
46 changes: 46 additions & 0 deletions src/main/java/subway/DummyDataSetting.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package subway;

import subway.domain.Line;
import subway.domain.LineRepository;
import subway.domain.Station;
import subway.domain.StationRepository;

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

public class DummyDataSetting {

public static void run() {
/*
* 역: 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역
* 노선: 2호선, 3호선, 신분당선
* 노선에 역
* - 2호선: 교대역 - 강남역 - 역삼역
* - 3호선: 교대역 - 남부터미널역 - 양재역 - 매봉역
* - 신분당선: 강남역 - 양재역 - 양재시민의숲역
*/
List<String> stationNames = Arrays.asList("교대역", "강남역", "역삼역", "남부터미널역", "양재역",
"양재시민의숲역", "매봉역");
for (String name : stationNames) {
StationRepository.addStation(new Station(name));
}

List<String> lineNames = Arrays.asList("2호선", "3호선", "신분당선");
for (String name : lineNames) {
LineRepository.addLine(new Line(name));
}

LineRepository.getLine("2호선").addSectionByStation(StationRepository.getStation("교대역"));
LineRepository.getLine("2호선").addSectionByStation(StationRepository.getStation("강남역"));
LineRepository.getLine("2호선").addSectionByStation(StationRepository.getStation("역삼역"));

LineRepository.getLine("3호선").addSectionByStation(StationRepository.getStation("교대역"));
LineRepository.getLine("3호선").addSectionByStation(StationRepository.getStation("남부터미널역"));
LineRepository.getLine("3호선").addSectionByStation(StationRepository.getStation("양재역"));
LineRepository.getLine("3호선").addSectionByStation(StationRepository.getStation("매봉역"));

LineRepository.getLine("신분당선").addSectionByStation(StationRepository.getStation("강남역"));
LineRepository.getLine("신분당선").addSectionByStation(StationRepository.getStation("양재역"));
LineRepository.getLine("신분당선").addSectionByStation(StationRepository.getStation("양재시민의숲역"));
}
}
27 changes: 27 additions & 0 deletions src/main/java/subway/LineManagementSign.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package subway;

import java.util.Arrays;

public enum LineManagementSign {
ADD_LINE("1"),
DELETE_LINE("2"),
SHOW_LINES("3"),
BACK_TO_MAIN("B");

private String sign;

LineManagementSign(String sign) {
this.sign = sign;
}

public String getSign() {
return sign;
}

public static LineManagementSign validateSign(String inputData) {
return Arrays.stream(LineManagementSign.values())
.filter(sign -> inputData.toUpperCase().equals(sign.getSign()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("없는 기능"));
}
}
28 changes: 28 additions & 0 deletions src/main/java/subway/MainSign.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package subway;

import java.util.Arrays;

public enum MainSign {
STATION_MANAGEMENT("1"),
LINE_MANAGEMENT("2"),
SECTION_MANAGEMENT("3"),
PRINT_SUBWAY_ROUTE("4"),
CLOSE_MAIN("Q");

private String sign;

MainSign(String sign) {
this.sign = sign;
}

public String getSign() {
return sign;
}

public static MainSign validateSign(String inputData) {
return Arrays.stream(MainSign.values())
.filter(sign -> inputData.toUpperCase().equals(sign.getSign()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("없는 기능"));
}
}
26 changes: 26 additions & 0 deletions src/main/java/subway/SectionManagementSign.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package subway;

import java.util.Arrays;

public enum SectionManagementSign {
ADD_SECTION("1"),
DELETE_SECTION("2"),
BACK_TO_MAIN("B");

private String sign;

SectionManagementSign(String sign) {
this.sign = sign;
}

public String getSign() {
return sign;
}

public static SectionManagementSign validateSign(String inputData) {
return Arrays.stream(SectionManagementSign.values())
.filter(sign -> inputData.toUpperCase().equals(sign.getSign()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("없는 기능"));
}
}
27 changes: 27 additions & 0 deletions src/main/java/subway/StationManagementSign.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package subway;

import java.util.Arrays;

public enum StationManagementSign {
ADD_STATION("1"),
DELETE_STATION("2"),
SHOW_STATIONS("3"),
BACK_TO_MAIN("B");

private String sign;

StationManagementSign(String sign) {
this.sign = sign;
}

public String getSign() {
return sign;
}

public static StationManagementSign validateSign(String inputData) {
return Arrays.stream(StationManagementSign.values())
.filter(sign -> inputData.toUpperCase().equals(sign.getSign()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("없는 기능"));
}
}
78 changes: 78 additions & 0 deletions src/main/java/subway/controller/ErrorHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package subway.controller;

import subway.domain.Line;
import subway.domain.LineRepository;
import subway.domain.Station;
import subway.domain.StationRepository;

import java.util.Objects;
import java.util.regex.Pattern;

public class ErrorHandler {
private static final String STATION_NAME_END = "역";
private static final String LINE_NAME_END = "선";
private static final int NAME_MIN_LENGTH = 2;
private static final int LENGTH_TO_INDEX = 1;

public static void validateStationNameFormat(String inputData) {
if (inputData.length() < NAME_MIN_LENGTH
|| !Pattern.matches("^[0-9가-힣]*$", inputData)
|| !inputData.substring(inputData.length() - LENGTH_TO_INDEX).equals(STATION_NAME_END)) {
throw new IllegalArgumentException("format error");
}
}

public static void validateStationDuplicate(String inputData) {
if (StationRepository.isDuplicate(inputData)) {
throw new IllegalArgumentException("duplicate error");
}
}

public static void validateStationRegistered(String inputData) {
if (!StationRepository.isDuplicate(inputData)) {
throw new IllegalArgumentException("not registered error");
}
}

public static void validateLineNameFormat(String inputData) {
if (inputData.length() < NAME_MIN_LENGTH
|| !Pattern.matches("^[0-9가-힣]*$", inputData)
|| !inputData.substring(inputData.length() - LENGTH_TO_INDEX).equals(LINE_NAME_END)) {
throw new IllegalArgumentException("format error");
}
}

public static void validateLineDuplicate(String inputData) {
if (LineRepository.isDuplicate(inputData)) {
throw new IllegalArgumentException("duplicate error");
}
}

public static void validateLineRegistered(String inputData) {
if (!LineRepository.isDuplicate(inputData)) {
throw new IllegalArgumentException("not registered error");
}
}

public static void validateStationDuplicateInLine(Station targetStation, Line line) {
if (line.getSections().stream()
.anyMatch(station -> Objects.equals(station, targetStation))) {
throw new IllegalArgumentException("duplicate error");
}
}

public static void validateStationRegisteredInLine(Station targetStation, Line line) {
if (line.getSections().stream()
.noneMatch(station -> Objects.equals(station, targetStation))) {
throw new IllegalArgumentException("not registered error");
}
}

public static void validateOrder(String targetOrder, Line line) {
int order = Integer.parseInt(targetOrder);
if (order < 1 || order > line.getSections().size()) {
throw new IllegalArgumentException("inbound error");
}
}

}
Loading