diff --git a/README.md b/README.md index 450e7753a..0954810ab 100644 --- a/README.md +++ b/README.md @@ -1,469 +1,13 @@ -# 지하철 노선도 미션 -- 지하철 역과 노선을 관리하는 지하철 노선도 기능을 구현한다. - -
- -## 🚀 기능 요구사항 - -### 초기 설정 -- 프로그램 시작 시 역, 노선 등 필요한 정보를 미리 셋팅할 수 있다. - -> 아래의 사전 등록 정보로 반드시 초기 설정을 하기 -> -``` - 1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다. - 2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다. - 3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점) - - 2호선: 교대역 - 강남역 - 역삼역 - - 3호선: 교대역 - 남부터미널역 - 양재역 - 매봉역 - - 신분당선: 강남역 - 양재역 - 양재시민의숲역 - ``` - - - -### 지하철 역 관련 기능 -- 지하철 역을 등록하고 삭제할 수 있다. (단, 노선에 등록된 역은 삭제할 수 없다) -- 중복된 지하철 역 이름이 등록될 수 없다. -- 지하철 역 이름은 2글자 이상이어야 한다. -- 지하철 역의 목록을 조회할 수 있다. - -### 지하철 노선 관련 기능 -- 지하철 노선을 등록하고 삭제할 수 있다. -- 중복된 지하철 노선 이름이 등록될 수 없다. -- 지하철 노선 이름은 2글자 이상이어야 한다. -- 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다. -- 지하철 노선의 목록을 조회할 수 있다. - -### 지하철 구간 추가 기능 -- 지하철 노선에 구간을 추가하는 기능은 노선에 역을 추가하는 기능이라고도 할 수 있다. - - 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다. -- 하나의 역은 여러개의 노선에 추가될 수 있다. -- 역과 역 사이에 새로운 역이 추가 될 수 있다. -- 노선에서 갈래길은 생길 수 없다. - - - -### 지하철 구간 삭제 기능 -- 노선에 등록된 역을 제거할 수 있다. -- 종점을 제거할 경우 다음 역이 종점이 된다. +### 기능 목록 +- 사전 등록 정보 초기 설정하기 +- 맨 처음 사용자 입력값 1, 2, 3, 4, Q 검증 필요 +- 이 외에도 단계별로 입력값 1, 2, 3, B 검증 필요 +- 역 등록 시에 중복 검사 필요 +- 역 등록 시에 역 이름 길이 검증 필요 +- 역 삭제 시에 역 이름 존재 유무 검증 필요 +- 노선 등록 시에 중복 검사 필요 +- 노선 등록 시에 이름 길이 검증 필요 +- 노선 삭제 시에 역 이름 존재 유무 검증 필요 +- 구간 등록/삭제 시 노선 유무 검증 필요 +- 구간 등록/삭제 시 역 유무 검증 필요 - 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다. - - - -### 지하철 노선에 등록된 역 조회 기능 -- 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회할 수 있다. - -
- -## ✍🏻 입출력 요구사항 -- `프로그래밍 실행 결과 예시`를 참고하여 입출력을 구현한다. -- 기대하는 출력 결과는 `[INFO]`를 붙여서 출력한다. 출력값의 형식은 예시와 동일하게 한다. -- 에러 발생 시 `[ERROR]`를 붙여서 출력한다. (에러의 문구는 자유롭게 작성한다.) - -### 💻 프로그래밍 실행 결과 -#### 역 관리 -``` -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -1 - -## 역 관리 화면 -1. 역 등록 -2. 역 삭제 -3. 역 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -1 - -## 등록할 역 이름을 입력하세요. -잠실역 - -[INFO] 지하철 역이 등록되었습니다. - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -1 - -## 역 관리 화면 -1. 역 등록 -2. 역 삭제 -3. 역 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -3 - -## 역 목록 -[INFO] 교대역 -[INFO] 강남역 -[INFO] 역삼역 -[INFO] 남부터미널역 -[INFO] 양재역 -[INFO] 양재시민의숲역 -[INFO] 매봉역 -[INFO] 잠실역 - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -1 - -## 역 관리 화면 -1. 역 등록 -2. 역 삭제 -3. 역 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -2 - -## 삭제할 역 이름을 입력하세요. -잠실역 - -[INFO] 지하철 역이 삭제되었습니다. - -... -``` - -### 노선 관리 - -``` - -... - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -2 - -## 노선 관리 화면 -1. 노선 등록 -2. 노선 삭제 -3. 노선 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -1 - -## 등록할 노선 이름을 입력하세요. -1호선 - -## 등록할 노선의 상행 종점역 이름을 입력하세요. -강남역 - -## 등록할 노선의 하행 종점역 이름을 입력하세요. -잠실역 - -[INFO] 지하철 노선이 등록되었습니다. - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -2 - -## 노선 관리 화면 -1. 노선 등록 -2. 노선 삭제 -3. 노선 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -3 - -## 노선 목록 -[INFO] 2호선 -[INFO] 3호선 -[INFO] 신분당선 -[INFO] 1호선 - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -2 - -## 노선 관리 화면 -1. 노선 등록 -2. 노선 삭제 -3. 노선 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -2 - -## 삭제할 노선 이름을 입력하세요. -1호선 - -[INFO] 지하철 노선이 삭제되었습니다. - -... - -``` - -### 구간 관리 -- 순서는 1부터 시작한다. - -``` -... - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -3 - -## 구간 관리 화면 -1. 구간 등록 -2. 구간 삭제 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -1 - -## 노선을 입력하세요. -2호선 - -## 역이름을 입력하세요. -잠실역 - -## 순서를 입력하세요. -2 - -[INFO] 구간이 등록되었습니다. - -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -3 - -## 구간 관리 화면 -1. 구간 등록 -2. 구간 삭제 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -2 - -## 삭제할 구간의 노선을 입력하세요. -2호선 - -## 삭제할 구간의 역을 입력하세요. -잠실역 - -[INFO] 구간이 삭제되었습니다. - -... - -``` - -### 지하철 노선도 출력 - -``` -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -4 - -## 지하철 노선도 -[INFO] 2호선 -[INFO] --- -[INFO] 교대역 -[INFO] 강남역 -[INFO] 역삼역 - -[INFO] 3호선 -[INFO] --- -[INFO] 교대역 -[INFO] 남부터미널역 -[INFO] 양재역 -[INFO] 매봉역 - -[INFO] 신분당선 -[INFO] --- -[INFO] 강남역 -[INFO] 양재역 -[INFO] 양재시민의숲역 - -``` - -#### 에러 출력 예시 - -``` -## 메인 화면 -1. 역 관리 -2. 노선 관리 -3. 구간 관리 -4. 지하철 노선도 출력 -Q. 종료 - -## 원하는 기능을 선택하세요. -5 - -[ERROR] 선택할 수 없는 기능입니다. - -## 원하는 기능을 선택하세요. -1 - -## 역 관리 화면 -1. 역 등록 -2. 역 삭제 -3. 역 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. -1 - -## 등록할 역 이름을 입력하세요. -강남역 - -[ERROR] 이미 등록된 역 이름입니다. - -## 역 관리 화면 -1. 역 등록 -2. 역 삭제 -3. 역 조회 -B. 돌아가기 - -## 원하는 기능을 선택하세요. - -... - -``` - -
- -## 🎱 프로그래밍 요구사항 -- 자바 코드 컨벤션을 지키면서 프로그래밍한다. - - 기본적으로 [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)을 원칙으로 한다. - - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. -- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다. - - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. - - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다. -- 3항 연산자를 쓰지 않는다. -- 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다. - - 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다. -- else 예약어를 쓰지 않는다. - - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. - - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. -- 프로그래밍 요구사항에서 별도로 변경 불가 안내가 없는 경우 파일 수정과 패키지 이동을 자유롭게 할 수 있다. -- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 `[ERROR]` 로 시작해야 한다. - -### 프로그래밍 요구사항 - Application -- Application 클래스를 활용해 구현해야 한다. -- Application의 패키지 구조는 변경하지 않는다. -```java -public class Application { - public static void main(String[] args) { - ... - } -} -``` - -### 프로그래밍 요구사항 - Station, Line -- Station, Line 클래스를 활용하여 지하철역과 노선을 구현해야 한다. -- 제공하는 각 클래스의 기본 생성자를 추가할 수 없다. -- 필드(인스턴스 변수)인 name의 접근 제어자 private을 변경할 수 없다. -- 가능하면 setter 메소드(ex. setXXX)를 추가하지 않고 구현한다. - -```java -public class Station { - private String name; - - public Station(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // 추가 기능 구현 -} - -``` - -### 프로그래밍 요구사항 - StationRepository, LineRepository -- Station과 Line의 상태를 저장할 수 있는 StationRepository, LineRepository를 제공한다. -- 필요 시 StationRepository, LineRepository 이 외 추가로 Repository를 만들 수 있다. -- 추가로 생성되는 객체에 대해서 XXXRepository 네이밍으로 저장 클래스를 추가할 수 있다. -- 객체들의 상태를 관리하기 위해서 XXXRepository 클래스를 활용해 저장 로직을 구현해야 한다. -- 필요에 따라 자유롭게 수정이 가능하다. - -```java -public class StationRepository { - private static final List stations = new ArrayList<>(); - - public static List stations() { - return Collections.unmodifiableList(stations); - } - - public static void addStation(Station station) { - stations.add(station); - } - - public static boolean deleteStation(String name) { - return stations.removeIf(station -> Objects.equals(station.getName(), name)); - } -} -``` - -
- -## 📈 진행 요구사항 -- 미션은 [java-subway-map-precourse 저장소](https://github.com/woowacourse/java-subway-map-precourse) 를 fork/clone해 시작한다. -- 기능을 구현하기 전에 java-subway-map-precourse/docs/README.md 파일에 구현할 기능 목록을 정리해 추가한다. -- git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가한다. - - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 참고해 commit log를 남긴다. -- [프리코스 과제 제출 문서](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 절차를 따라 미션을 제출한다. - - [프리코스 과제 FAQ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse/faq) 문서를 참고하여 진행할 수 있다. -
- -## 📝 License - -This project is [MIT](https://github.com/woowacourse/java-subway-map-precourse/blob/master/LICENSE.md) licensed. diff --git a/src/main/java/log/ErrorCase.java b/src/main/java/log/ErrorCase.java new file mode 100644 index 000000000..63cbd1fec --- /dev/null +++ b/src/main/java/log/ErrorCase.java @@ -0,0 +1,12 @@ +package log; + +public class ErrorCase { + + public static final String FUNCTION_INPUT_ERROR = "선택할 수 없는 기능입니다. "; + public static final String ALREADY_EXIST_ERROR = "이미 등록된 역/노선 이름입니다. "; + public static final String NAME_LENGTH_ERROR = "역/노선의 이름은 최소 2자 이상이어야 합니다. "; + public static final String NO_SUCH_NAME_ERROR = "등록되지 않은 역/노선 이름입니다. "; + public static final String INVALID_POSITION_ERROR = "잘못된 위치값입니다. "; + public static final String HAS_IN_LINE_ERROR = "노선에 등록된 역은 삭제할 수 없습니다. "; + public static final String TERMINAL_LENGTH_ERROR = "노선의 역 수는 2개 이상이어야 합니다. "; +} diff --git a/src/main/java/log/Logger.java b/src/main/java/log/Logger.java new file mode 100644 index 000000000..cba5572c2 --- /dev/null +++ b/src/main/java/log/Logger.java @@ -0,0 +1,69 @@ +package log; + +import static log.ErrorCase.FUNCTION_INPUT_ERROR; + +import java.util.List; +import java.util.Scanner; + +public class Logger { + public static final String LEVEL_GUIDE = "\n## "; + public static final String LEVEL_ERROR = "\n[ERROR] "; + public static final String LEVEL_INFO = "\n[INFO] "; + + public static void guidePrint(String errorBody) { + System.out.print(LEVEL_GUIDE + errorBody); + } + + public static void errorPrint(String errorBody) { + System.out.println(LEVEL_ERROR + errorBody); + } + + public static void infoPrint(String infoBody) { + System.out.print(LEVEL_INFO + infoBody); + } + + public static void displayMainScreen() { + System.out.println("\n## 메인 화면\n" + + "1. 역 관리\n" + + "2. 노선 관리\n" + + "3. 구간 관리\n" + + "4. 지하철 노선도 출력\n" + + "Q. 종료"); + } + + public static String displayInputScreen(Scanner scanner, List whiteList) { + String input; + while (true) { + guidePrint("원하는 기능을 선택하세요.\n"); + input = scanner.next(); + if (whiteList.contains(input)) { + break; + } + errorPrint(FUNCTION_INPUT_ERROR); + } + return input; + } + + public static void displayStationManageScreen() { + System.out.println("\n## 역 관리 화면\n" + + "1. 역 등록\n" + + "2. 역 삭제\n" + + "3. 역 조회\n" + + "B. 돌아가기"); + } + + public static void displayLineManageScreen() { + System.out.println("\n## 노선 관리 화면\n" + + "1. 노선 등록\n" + + "2. 노선 삭제\n" + + "3. 노선 조회\n" + + "B. 돌아가기"); + } + + public static void displaySectionManageScreen() { + System.out.println("\n## 구간 관리 화면\n" + + "1. 구간 등록\n" + + "2. 구간 삭제\n" + + "B. 돌아가기"); + } +} diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..1d47822b9 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,75 @@ package subway; +import static log.Logger.displayInputScreen; +import static log.Logger.displayMainScreen; +import static subway.LineManage.linaManage; +import static subway.SectionManage.sectionManage; +import static subway.StationManage.stationManage; +import static subway.domain.LineRepository.addLine; +import static subway.domain.StationRepository.addStation; +import static subway.domain.StationRepository.getStationByName; +import static subway.routeMap.routeMapPrint; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; import java.util.Scanner; +import subway.domain.Line; +import subway.domain.Station; public class Application { + + static final String STATION_MANAGE = "1"; + static final String LINE_MANAGE = "2"; + static final String SECTION_MANAGE = "3"; + static final String ALL_INFO = "4"; + static final String EXIT = "Q"; + public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); - // TODO: 프로그램 구현 + initSetting(); + boolean exitFlag = false; + while (!exitFlag) { + displayMainScreen(); + exitFlag = isExit(scanner); + } + } + + private static void initSetting() { + final ArrayList initStations = new ArrayList<>( + Arrays.asList("교대역", "강남역", "역삼역", "남부터미널역", "양재역", "양재시민의숲역", "매봉역")); + + for (String stationName : initStations) { + addStation(new Station(stationName)); + } + addLine(new Line("2호선", new LinkedList(Arrays.asList( + getStationByName("교대역"), getStationByName("강남역"), getStationByName("역삼역"))))); + addLine(new Line("3호선", new LinkedList(Arrays.asList( + getStationByName("교대역"), getStationByName("남부터미널역"), getStationByName("양재역"), + getStationByName("매봉역"))))); + addLine(new Line("신분당선", new LinkedList(Arrays.asList( + getStationByName("강남역"), getStationByName("양재역"), getStationByName("양재시민의숲역"))))); + } + + private static boolean isExit(Scanner scanner) { + String input = displayInputScreen(scanner, new ArrayList<>(Arrays.asList( + STATION_MANAGE, LINE_MANAGE, SECTION_MANAGE, ALL_INFO, EXIT))); + + if (input.equals(EXIT)) { + return true; + } + if (input.equals(STATION_MANAGE)) { + stationManage(scanner); + } + if (input.equals(LINE_MANAGE)) { + linaManage(scanner); + } + if (input.equals(SECTION_MANAGE)) { + sectionManage(scanner); + } + if (input.equals(ALL_INFO)) { + routeMapPrint(); + } + return false; } } diff --git a/src/main/java/subway/LineManage.java b/src/main/java/subway/LineManage.java new file mode 100644 index 000000000..3133fc78e --- /dev/null +++ b/src/main/java/subway/LineManage.java @@ -0,0 +1,126 @@ +package subway; + +import static log.ErrorCase.ALREADY_EXIST_ERROR; +import static log.ErrorCase.NAME_LENGTH_ERROR; +import static log.ErrorCase.NO_SUCH_NAME_ERROR; +import static log.Logger.displayInputScreen; +import static log.Logger.displayLineManageScreen; +import static log.Logger.errorPrint; +import static log.Logger.guidePrint; +import static log.Logger.infoPrint; +import static subway.domain.LineRepository.addLine; +import static subway.domain.LineRepository.deleteLineByName; +import static subway.domain.LineRepository.hasLine; +import static subway.domain.LineRepository.lines; +import static subway.domain.StationRepository.hasStation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import subway.domain.Line; +import subway.domain.Station; + +public class LineManage { + + static final String ADD_LINE = "1"; + static final String DELETE_LINE = "2"; + static final String ALL_LINES = "3"; + static final String BACK_SCREEN = "B"; + static final int MIN_LINE_NAME_LENGTH = 2; + + static public void linaManage(Scanner scanner) { + boolean exitFlag = false; + while (!exitFlag) { + displayLineManageScreen(); + exitFlag = isExit(scanner); + } + } + + private static boolean isExit(Scanner scanner) { + String input = displayInputScreen(scanner, new ArrayList<>(Arrays.asList( + ADD_LINE, DELETE_LINE, ALL_LINES, BACK_SCREEN))); + if (input.equals(ADD_LINE)) { + return addLineControl(scanner); + } + if (input.equals(DELETE_LINE)) { + return deleteLineControl(scanner); + } + if (input.equals(ALL_LINES)) { + return allLinesControl(); + } + return input.equals(BACK_SCREEN); + } + + private static boolean addLineControl(Scanner scanner) { + guidePrint("등록할 노선 이름을 입력하세요. \n"); + String lineName = scanner.next(); + if (!validateLineName(lineName)) { + return false; + } + guidePrint("등록할 노선의 상행 종점역 이름을 입력하세요. \n"); + String upwardTerminal = scanner.next(); + if (!validateTerminalName(upwardTerminal)) { + return false; + } + guidePrint("등록할 노선의 하행 종점역 이름을 입력하세요. \n"); + String downWardTerminal = scanner.next(); + if (!validateTerminalName(downWardTerminal)) { + return false; + } + addLine(new Line(lineName, new Station(upwardTerminal), new Station(downWardTerminal))); + infoPrint("지하철 노선이 등록되었습니다. \n"); + return true; + } + + private static boolean deleteLineControl(Scanner scanner) { + guidePrint("삭제할 노선 이름을 입력하세요. \n"); + String lineName = scanner.next(); + if (!lineExists(lineName)) { + errorPrint(NO_SUCH_NAME_ERROR); + return false; + } + deleteLineByName(lineName); + infoPrint("지하철 노선이 삭제되었습니다. \n"); + return true; + } + + private static boolean allLinesControl() { + guidePrint("노선 목록"); + List allLines = lines(); + for (Line line : allLines) { + line.printName(); + } + System.out.println(); + return true; + } + + private static boolean validateLineName(String lineName) { + if (!lineNameLengthValidate(lineName)) { + errorPrint(NAME_LENGTH_ERROR); + return false; + } + if (lineExists(lineName)) { + errorPrint(ALREADY_EXIST_ERROR); + return false; + } + return true; + } + + private static boolean validateTerminalName(String terminalName) { + if (!hasStation(terminalName)) { + errorPrint(NO_SUCH_NAME_ERROR); + return false; + } + return true; + } + + private static boolean lineNameLengthValidate(String lineName) { + return lineName.length() >= MIN_LINE_NAME_LENGTH; + } + + private static boolean lineExists(String lineName) { + return hasLine(lineName); + } + +} diff --git a/src/main/java/subway/SectionManage.java b/src/main/java/subway/SectionManage.java new file mode 100644 index 000000000..4d059e360 --- /dev/null +++ b/src/main/java/subway/SectionManage.java @@ -0,0 +1,155 @@ +package subway; + +import static log.ErrorCase.ALREADY_EXIST_ERROR; +import static log.ErrorCase.INVALID_POSITION_ERROR; +import static log.ErrorCase.NO_SUCH_NAME_ERROR; +import static log.ErrorCase.TERMINAL_LENGTH_ERROR; +import static log.Logger.displayInputScreen; +import static log.Logger.displaySectionManageScreen; +import static log.Logger.errorPrint; +import static log.Logger.guidePrint; +import static log.Logger.infoPrint; +import static subway.domain.LineRepository.getLineByName; +import static subway.domain.StationRepository.getStationByName; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Scanner; +import subway.domain.Line; +import subway.domain.Station; + +public class SectionManage { + + static final String ADD_SECTION = "1"; + static final String DELETE_SECTION = "2"; + static final String BACK_SCREEN = "B"; + static final int MIN_LINE_LENGTH = 2; + static boolean errorFlag = false; + + static public void sectionManage(Scanner scanner) { + boolean exitFlag = false; + while (!exitFlag) { + displaySectionManageScreen(); + exitFlag = isExit(scanner); + } + } + + private static boolean isExit(Scanner scanner) { + String input = displayInputScreen(scanner, new ArrayList<>(Arrays.asList( + ADD_SECTION, DELETE_SECTION, BACK_SCREEN))); + if (input.equals(ADD_SECTION)) { + return addSectionControl(scanner); + } + if (input.equals(DELETE_SECTION)) { + return deleteSectionControl(scanner); + } + return input.equals(BACK_SCREEN); + } + + private static boolean addSectionControl(Scanner scanner) { + errorFlag = false; + Line line = inputAddLine(scanner); + if (errorFlag) { + return false; + } + Station terminal = inputAddTerminal(scanner, line); + if (errorFlag) { + return false; + } + int position = inputPosition(scanner, line.getLength()); + if (errorFlag) { + return false; + } + line.addTerminal(position - 1, terminal); + infoPrint("구간이 등록되었습니다. \n"); + return true; + } + + private static boolean deleteSectionControl(Scanner scanner) { + errorFlag = false; + Line line = inputDeleteLine(scanner); + if (errorFlag) { + return false; + } + String terminalName = inputDeleteTerminal(scanner, line); + if (errorFlag) { + return false; + } + line.deleteTerminal(terminalName); + infoPrint("구간이 삭제되었습니다. \n"); + return true; + } + + private static Line inputAddLine(Scanner scanner) { + guidePrint("노선 이름을 입력하세요. \n"); + String lineName = scanner.next(); + Line line = getLineByName(lineName); + if (line == null) { + errorPrint(NO_SUCH_NAME_ERROR); + errorFlag = true; + } + return line; + } + + private static Station inputAddTerminal(Scanner scanner, Line line) { + guidePrint("역 이름을 입력하세요. \n"); + String terminalName = scanner.next(); + Station terminal = getStationByName(terminalName); + if (terminal == null) { + errorPrint(NO_SUCH_NAME_ERROR); + errorFlag = true; + return null; + } + if (line.hasTerminal(terminalName)) { + errorPrint(ALREADY_EXIST_ERROR); + errorFlag = true; + } + return terminal; + } + + private static Line inputDeleteLine(Scanner scanner) { + guidePrint("삭제할 구간의 노선을 입력하세요. \n"); + String lineName = scanner.next(); + Line line = getLineByName(lineName); + if (line == null) { + errorPrint(NO_SUCH_NAME_ERROR); + errorFlag = true; + return null; + } + if (line.getLength() <= 2) { + errorPrint(TERMINAL_LENGTH_ERROR); + errorFlag = true; + return null; + } + return line; + } + + private static String inputDeleteTerminal(Scanner scanner, Line line) { + guidePrint("삭제할 구간의 역을 입력하세요. \n"); + String terminalName = scanner.next(); + Station terminal = getStationByName(terminalName); + if (terminal == null) { + errorPrint(NO_SUCH_NAME_ERROR); + errorFlag = true; + return null; + } + if (!line.hasTerminal(terminalName)) { + errorPrint(NO_SUCH_NAME_ERROR); + errorFlag = true; + return null; + } + return terminalName; + } + + private static int inputPosition(Scanner scanner, int max) { + guidePrint("순서를 입력하세요. \n"); + final int MIN_POSITION = 1; + final int MAX_POSITION = max + 1; + int position = scanner.nextInt(); + if (position < MIN_POSITION || position > MAX_POSITION) { + errorPrint(INVALID_POSITION_ERROR); + errorFlag = true; + } + return position; + } +} diff --git a/src/main/java/subway/StationManage.java b/src/main/java/subway/StationManage.java new file mode 100644 index 000000000..c0c8a646c --- /dev/null +++ b/src/main/java/subway/StationManage.java @@ -0,0 +1,100 @@ +package subway; + +import static log.ErrorCase.ALREADY_EXIST_ERROR; +import static log.ErrorCase.NAME_LENGTH_ERROR; +import static log.ErrorCase.NO_SUCH_NAME_ERROR; +import static log.Logger.displayInputScreen; +import static log.Logger.displayStationManageScreen; +import static log.Logger.errorPrint; +import static log.Logger.guidePrint; +import static log.Logger.infoPrint; +import static subway.domain.StationRepository.addStation; +import static subway.domain.StationRepository.deleteStation; +import static subway.domain.StationRepository.hasStation; +import static subway.domain.StationRepository.stations; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import subway.domain.Station; + +public class StationManage { + + static final String ADD_STATION = "1"; + static final String DELETE_STATION = "2"; + static final String ALL_STATIONS = "3"; + static final String BACK_SCREEN = "B"; + static final int MIN_STATION_NAME_LENGTH = 2; + + static public void stationManage(Scanner scanner) { + boolean exitFlag = false; + while (!exitFlag) { + displayStationManageScreen(); + exitFlag = isExit(scanner); + } + } + + private static boolean isExit(Scanner scanner) { + String input = displayInputScreen(scanner, new ArrayList<>(Arrays.asList( + ADD_STATION, DELETE_STATION, ALL_STATIONS, BACK_SCREEN))); + if (input.equals(BACK_SCREEN)) { + return true; + } + if (input.equals(ADD_STATION)) { + return addStationControl(scanner); + } + if (input.equals(DELETE_STATION)) { + return deleteStationControl(scanner); + } + if (input.equals(ALL_STATIONS)) { + return allStationsContol(); + } + return false; + } + + private static boolean addStationControl(Scanner scanner) { + guidePrint("등록할 역 이름을 입력하세요. \n"); + String stationName = scanner.next(); + if (!stationNameLengthValidate(stationName)) { + errorPrint(NAME_LENGTH_ERROR); + return false; + } + if (stationExists(stationName)) { + errorPrint(ALREADY_EXIST_ERROR); + return false; + } + addStation(new Station(stationName)); + infoPrint("지하철 역이 등록되었습니다. \n"); + return true; + } + + private static boolean deleteStationControl(Scanner scanner) { + guidePrint("삭제할 역 이름을 입력하세요. \n"); + String stationName = scanner.next(); + if (!stationExists(stationName)) { + errorPrint(NO_SUCH_NAME_ERROR); + return false; + } + deleteStation(stationName); + infoPrint("지하철 역이 삭제되었습니다. \n"); + return true; + } + + private static boolean allStationsContol() { + guidePrint("역 목록\n"); + List allStations = stations(); + for (Station station : allStations) { + station.print(); + } + return true; + } + + private static boolean stationNameLengthValidate(String stationName) { + return stationName.length() >= MIN_STATION_NAME_LENGTH; + } + + private static boolean stationExists(String stationName) { + return hasStation(stationName); + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index f4d738d5a..96c69f73e 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,15 +1,59 @@ package subway.domain; +import static log.Logger.infoPrint; + +import java.util.Arrays; +import java.util.LinkedList; + public class Line { - private String name; - public Line(String name) { + private final String name; + private final LinkedList terminals; + + public Line(String name, Station upwardTerminal, Station downwardTerminal) { this.name = name; + terminals = new LinkedList(Arrays.asList(upwardTerminal, downwardTerminal)); + } + + public Line(String name, LinkedList terminals) { + this.name = name; + this.terminals = terminals; } public String getName() { return name; } - // 추가 기능 구현 + public int getLength() { + return terminals.size(); + } + + public boolean hasTerminal(String terminalName) { + for (Station terminal : terminals) { + if (terminal.getName().equals(terminalName)) { + return true; + } + } + return false; + } + + public void addTerminal(int position, Station newTerminal) { + terminals.add(position, newTerminal); + } + + public void deleteTerminal(String terminalName) { + terminals.removeIf(terminal -> terminal.getName().equals(terminalName)); + } + + public void printName() { + infoPrint(this.name); + } + + public void printAllInfo() { + printName(); + infoPrint("---\n"); + for (Station terminal : terminals) { + terminal.print(); + } + } } diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 49132ddb6..045f9122b 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -19,4 +19,22 @@ public static void addLine(Line line) { public static boolean deleteLineByName(String name) { return lines.removeIf(line -> Objects.equals(line.getName(), name)); } + + public static boolean hasLine(String name) { + for (Line line : lines) { + if (line.getName().equals(name)) { + return true; + } + } + return false; + } + + public static Line getLineByName(String name) { + for (Line line : lines) { + if (line.getName().equals(name)) { + return line; + } + } + return null; + } } diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index bdb142590..c7c47ee05 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -11,5 +11,7 @@ public String getName() { return name; } - // 추가 기능 구현 + public void print() { + System.out.println("[INFO] " + this.name); + } } diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java index b7245c0f3..6400ccaf8 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/StationRepository.java @@ -6,6 +6,7 @@ import java.util.Objects; public class StationRepository { + private static final List stations = new ArrayList<>(); public static List stations() { @@ -19,4 +20,22 @@ public static void addStation(Station station) { public static boolean deleteStation(String name) { return stations.removeIf(station -> Objects.equals(station.getName(), name)); } + + public static boolean hasStation(String name) { + for (Station station : stations) { + if (station.getName().equals(name)) { + return true; + } + } + return false; + } + + public static Station getStationByName(String name) { + for (Station station : stations) { + if (station.getName().equals(name)) { + return station; + } + } + return null; + } } diff --git a/src/main/java/subway/routeMap.java b/src/main/java/subway/routeMap.java new file mode 100644 index 000000000..a4c200d2a --- /dev/null +++ b/src/main/java/subway/routeMap.java @@ -0,0 +1,18 @@ +package subway; + +import static log.Logger.guidePrint; +import static subway.domain.LineRepository.lines; + +import java.util.List; +import subway.domain.Line; + +public class routeMap { + public static void routeMapPrint() { + guidePrint("지하철 노선도"); + + List allLines = lines(); + for (Line line : allLines) { + line.printAllInfo(); + } + } +}