diff --git a/README.md b/README.md
deleted file mode 100644
index 597ae6f36..000000000
--- a/README.md
+++ /dev/null
@@ -1,469 +0,0 @@
-# 지하철 노선도 미션
-- 지하철 역과 노선을 관리하는 지하철 노선도 기능을 구현한다.
-
-
-
-## 🚀 기능 요구사항
-
-### 초기 설정
-- 프로그램 시작 시 역, 노선 등 필요한 정보를 미리 셋팅할 수 있다.
-
-> 아래의 사전 등록 정보로 반드시 초기 설정을 하기
->
-```
- 1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다.
- 2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
- 3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
- - 2호선: 교대역 - 강남역 - 역삼역
- - 3호선: 교대역 - 남부터미널역 - 양재역 - 매봉역
- - 신분당선: 강남역 - 양재역 - 양재시민의숲역
- ```
-
-
-
-### 지하철 역 관련 기능
-- 지하철 역을 등록하고 삭제할 수 있다. (단, 노선에 등록된 역은 삭제할 수 없다)
-- 중복된 지하철 역 이름이 등록될 수 없다.
-- 지하철 역 이름은 2글자 이상이어야 한다.
-- 지하철 역의 목록을 조회할 수 있다.
-
-### 지하철 노선 관련 기능
-- 지하철 노선을 등록하고 삭제할 수 있다.
-- 중복된 지하철 노선 이름이 등록될 수 없다.
-- 지하철 노선 이름은 2글자 이상이어야 한다.
-- 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다.
-- 지하철 노선의 목록을 조회할 수 있다.
-
-### 지하철 구간 추가 기능
-- 지하철 노선에 구간을 추가하는 기능은 노선에 역을 추가하는 기능이라고도 할 수 있다.
- - 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다.
-- 하나의 역은 여러개의 노선에 추가될 수 있다.
-- 역과 역 사이에 새로운 역이 추가 될 수 있다.
-- 노선에서 갈래길은 생길 수 없다.
-
-
-
-### 지하철 구간 삭제 기능
-- 노선에 등록된 역을 제거할 수 있다.
-- 종점을 제거할 경우 다음 역이 종점이 된다.
-- 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다.
-
-
-
-### 지하철 노선에 등록된 역 조회 기능
-- 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회할 수 있다.
-
-
-
-## ✍🏻 입출력 요구사항
-- `프로그래밍 실행 결과 예시`를 참고하여 입출력을 구현한다.
-- 기대하는 출력 결과는 `[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. 역 관리
-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/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..3245f893c
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,118 @@
+## **📃 프로젝트 소개**
+
+- 지하철 노선도 관리 프로그램 입니다.
+- 콘솔창에 보여지는 메뉴 UI를 통해서 지하철 노선도를 관리할 수 있습니다.
+- "역 관리" 메뉴에서는 지하철 역을 등록하고, 삭제하고, 조회할 수 있습니다.
+- "노선 관리" 메뉴에서는 지하철 노선을 등록하고, 삭제하고, 조회할 수 있습니다.
+- "구간 관리" 메뉴에서는 지하철 노선을 등록하고, 삭제할 수 있습니다.
+- "지하철 노선도 출력" 기능을 통해 모든 지하철 노선들을 조회할 수 있습니다.
+
+
+
+## **🛠️ 프로그램 기능 목록**
+
+#### 초기 설정
+
+```
+ 1. 지하철역으로 교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역이 등록되어 있다.
+ 2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
+ 3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
+ - 2호선: 교대역 - 강남역 - 역삼역
+ - 3호선: 교대역 - 남부터미널역 - 양재역 - 매봉역
+ - 신분당선: 강남역 - 양재역 - 양재시민의숲역
+```
+
+
+
+#### 메뉴 관련 기능
+
+- **메뉴 UI가 출력되고 동작한다.**
+
+ - ```
+ ## 메인 화면 ## 역 관리 화면
+ 1. 역 관리 1. 역 등록
+ 2. 노선 관리 2. 역 삭제
+ 3. 구간 관리 3. 역 조회
+ 4. 지하철 노선도 출력 B. 돌아가기
+ Q. 종료
+ ```
+
+ - 위와 같은 UI의 메뉴를 화면에 출력한다. (왼쪽 메인 화면, 오른쪽 역 관리 화면)
+
+ - 메뉴에서 선택할 수 있는 목록 종류로는 하위 메뉴(sub menu)와 항목(item)이 있다. 각 목록 맨 앞에는 id가 출력된다.
+
+ - 사용자로부터 화면에 보이는 id 중 하나를 입력받으면 그에 따라서 동작해야한다.
+
+ - 하위 메뉴 id를 입력 받았을 경우 하위 메뉴 화면을 출력한다.
+ - 항목 id를 입력 받았을 경우 해당 항목의 기능을 실행한다.
+ - 기능 실행이 끝나면 실행 결과를 화면에 출력하고, 메인 화면으로 돌아간다.
+ - ex0) `## 메인화면`에서 `2`를 입력 받으면 `노선 관리` 메뉴 화면을 출력한다.
+ - ex1) `## 메인화면`에서 `4`를 입력 받으면 `지하철 노선도 출력 기능`을 실행한다.
+ - ex2) `## 메인화면`에서 `Q`를 입력 받으면 `프로그램 종료 기능`이 실행된다.
+ - ex3) `## 역 관리 화면`에서 `3`을 입력 받으면 `역 조회 기능`이 실행된다.
+ - ex4) `## 역 관리 화면`에서 `B`를 입력 받으면 `이전 화면으로 돌아가는 기능`이 실행된다.
+
+ - **[예외]** 현재 화면에 없는 id를 입력했을 경우
+
+
+
+#### 지하철 역 관련 기능
+
+- **지하철 역을 등록한다.**
+ - **[예외]** 중복된 지하철 역 이름이 등록될 수 없다.
+ - **[예외]** 지하철 역 이름은 2글자 이상이어야 한다.
+ - **[예외]** 지하철 역 이름에 특수 문자가 포함되는 경우
+- **지하철 역을 삭제한다.**
+ - **[예외]** 노선에 등록된 역은 삭제할 수 없다.
+ - **[예외]** 아예 등록되지 않은 역이 입력으로 들어오는 경우
+- **지하철 역 목록을 조회한다.**
+
+
+
+#### 지하철 노선 관련 기능
+
+- **지하철 노선을 등록한다.**
+ - 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다.
+ - **[예외]** 중복된 지하철 노선 이름이 등록될 수 없다.
+ - **[예외]** 지하철 노선 이름은 2글자 이상이어야 한다.
+ - **[예외]** 지하철 노선 이름에 특수 문자가 포함되는 경우
+ - **[예외]** 입력받은 상행/하행 종점역이 등록되지 않은 역일 경우
+- **지하철 노선을 삭제 한다.**
+ - **[예외]** 등록되지 않은 노선 이름이 입력으로 들어올 경우
+- **지하철 노선 목록을 조회한다.**
+
+
+
+#### 지하철 구간 관련 기능
+
+- **지하철 노선에 구간을 추가한다.**
+ - 하나의 역은 여러개의 노선에 추가될 수 있다.
+ - 노선, 추가할 역, 구간 위치를 입력 받는다.
+ - **[예외]** 등록되지 않은 노선이 입력으로 들어올 경우
+ - **[예외]** 등록되지 않은 역이 입력으로 들어올 경우
+ - **[예외]** 구간 위치가 잘못된 값일 경우(음수거나 노선의 범위보다 큰 값일 경우)
+ - **[예외]** 노선에서 갈래길은 생길 수 없다. (하나의 노선에 같은 역이 중복되는 경우)
+ - **[예외]** 지하철 노선 이름에 특수 문자가 포함되는 경우
+
+- **지하철 노선의 구간을 제거한다.**
+ - 종점을 제거할 경우 다음 역이 종점이 된다.
+ - **[예외]** 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다.
+ - **[예외]** 등록되지 않은 노선이 입력으로 들어올 경우
+ - **[예외]** 등록되지 않은 역이 입력으로 들어올 경우
+
+
+
+#### 지하철 노선도 관련 기능
+
+- **모든 지하철 노선을 조회한다.**
+
+ - 각 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회한다.
+
+
+
+------
+
+### 📝메모
+
+- 기대하는 출력 결과는 `[INFO]`를 붙여서 출력한다. 출력값의 형식은 예시와 동일하게 한다.
+- 에러 발생 시 `[ERROR]`를 붙여서 출력한다. (에러의 문구는 자유롭게 작성한다.)
\ No newline at end of file
diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java
index 0bcf786cc..19a92f29a 100644
--- a/src/main/java/subway/Application.java
+++ b/src/main/java/subway/Application.java
@@ -1,10 +1,16 @@
package subway;
-import java.util.Scanner;
+import subway.controller.SubwayManageController;
+import subway.domain.util.DataFactory;
public class Application {
+
public static void main(String[] args) {
- final Scanner scanner = new Scanner(System.in);
- // TODO: 프로그램 구현
+ DataFactory dataFactory = new DataFactory();
+ dataFactory.makeSubwayData();
+
+ SubwayManageController subwayManageController = new SubwayManageController();
+ subwayManageController.run();
}
+
}
diff --git a/src/main/java/subway/controller/SubwayManageController.java b/src/main/java/subway/controller/SubwayManageController.java
new file mode 100644
index 000000000..da4bf06d9
--- /dev/null
+++ b/src/main/java/subway/controller/SubwayManageController.java
@@ -0,0 +1,82 @@
+package subway.controller;
+
+import java.util.LinkedHashMap;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.selector.menu.Menu;
+import subway.domain.selector.menu.MenuRepository;
+import subway.domain.selector.utilitem.BackWardItem;
+import subway.domain.selector.utilitem.ExitItem;
+import subway.view.InputView;
+import subway.view.OutputView;
+
+public class SubwayManageController {
+
+ private static final InputView inputView = new InputView();
+ private static final OutputView outputView = new OutputView();
+ private static final String MAIN_MENU_ID = "0";
+ private String previousMenuId = MAIN_MENU_ID;
+ private String currentMenuId = MAIN_MENU_ID;
+ private boolean isRun;
+
+ public void run() {
+ isRun = true;
+ LinkedHashMap menus = MenuRepository.menus();
+
+ while (isRun) {
+ Menu menu = menus.get(currentMenuId);
+ outputView.printScreen(menu);
+
+ Selector selector = inputView.getSelector(menu);
+ if (isExitItem(selector)
+ || isBackWardItem(selector)
+ || isSubMenu(selector)) {
+ continue;
+ }
+ executeItem(selector, menu);
+ setMenuIdInformation(MAIN_MENU_ID, MAIN_MENU_ID);
+ }
+ }
+
+ private boolean isExitItem(Selector selector) {
+ if (selector instanceof ExitItem) {
+ isRun = false;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isBackWardItem(Selector selector) {
+ if (selector instanceof BackWardItem) {
+ this.currentMenuId = this.previousMenuId;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isSubMenu(Selector selector) {
+ if (selector instanceof Manipulable) {
+ setMenuIdInformation(MAIN_MENU_ID, MAIN_MENU_ID);
+ return false;
+ }
+ setMenuIdInformation(currentMenuId, selector.getId());
+ return true;
+ }
+
+ private void setMenuIdInformation(String previousMenuId, String currentMenuId) {
+ this.previousMenuId = previousMenuId;
+ this.currentMenuId = currentMenuId;
+ }
+
+ private void executeItem(Selector selector, Menu menu) {
+ try {
+ Manipulable item = (Manipulable) selector;
+ item.execute();
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ outputView.printScreen(menu);
+ executeItem(selector, menu);
+ }
+ }
+
+}
diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java
deleted file mode 100644
index f4d738d5a..000000000
--- a/src/main/java/subway/domain/Line.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package subway.domain;
-
-public class Line {
- private String name;
-
- public Line(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- // 추가 기능 구현
-}
diff --git a/src/main/java/subway/domain/line/Line.java b/src/main/java/subway/domain/line/Line.java
new file mode 100644
index 000000000..c934d85d4
--- /dev/null
+++ b/src/main/java/subway/domain/line/Line.java
@@ -0,0 +1,45 @@
+package subway.domain.line;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import subway.domain.station.Station;
+
+public class Line {
+
+ private final List stations = new ArrayList<>();
+ private String name;
+
+ public Line(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addAllStation(List stationsList) {
+ stations.addAll(stationsList);
+ }
+
+ public void addStationByIndex(Station station, int index) {
+ stations.add(index, station);
+ }
+
+ public void deleteStationByName(String name) {
+ stations.removeIf(station -> station.getName().equals(name));
+ }
+
+ public boolean isContainsStation(Station station) {
+ for (Station each : stations) {
+ if (each.getName().equals(station.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List stations() {
+ return Collections.unmodifiableList(stations);
+ }
+}
diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/line/LineRepository.java
similarity index 68%
rename from src/main/java/subway/domain/LineRepository.java
rename to src/main/java/subway/domain/line/LineRepository.java
index 49132ddb6..a4919d003 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;
@@ -6,6 +6,7 @@
import java.util.Objects;
public class LineRepository {
+
private static final List lines = new ArrayList<>();
public static List lines() {
@@ -16,6 +17,15 @@ public static void addLine(Line line) {
lines.add(line);
}
+ public static Line getLineByName(String name) {
+ for (Line line : lines) {
+ if (line.getName().equals(name)) {
+ return line;
+ }
+ }
+ return null;
+ }
+
public static boolean deleteLineByName(String name) {
return lines.removeIf(line -> Objects.equals(line.getName(), name));
}
diff --git a/src/main/java/subway/domain/selector/Manipulable.java b/src/main/java/subway/domain/selector/Manipulable.java
new file mode 100644
index 000000000..24841cf3d
--- /dev/null
+++ b/src/main/java/subway/domain/selector/Manipulable.java
@@ -0,0 +1,7 @@
+package subway.domain.selector;
+
+public interface Manipulable {
+
+ default void execute(){};
+
+}
diff --git a/src/main/java/subway/domain/selector/Selector.java b/src/main/java/subway/domain/selector/Selector.java
new file mode 100644
index 000000000..d17cb61fd
--- /dev/null
+++ b/src/main/java/subway/domain/selector/Selector.java
@@ -0,0 +1,28 @@
+package subway.domain.selector;
+
+import subway.view.InputView;
+import subway.view.MessageView;
+import subway.view.OutputView;
+
+public abstract class Selector {
+
+ protected String id;
+ protected String name;
+ protected InputView inputView = new InputView();
+ protected OutputView outputView = new OutputView();
+ protected MessageView messageView = new MessageView();
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/lineitem/LineAdder.java b/src/main/java/subway/domain/selector/lineitem/LineAdder.java
new file mode 100644
index 000000000..38774f509
--- /dev/null
+++ b/src/main/java/subway/domain/selector/lineitem/LineAdder.java
@@ -0,0 +1,51 @@
+package subway.domain.selector.lineitem;
+
+import java.util.LinkedList;
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.selector.stationitem.StationValidator;
+import subway.domain.station.Station;
+
+public class LineAdder extends Selector implements Manipulable {
+
+ LineValidator lineValidator = new LineValidator();
+ StationValidator stationValidator = new StationValidator();
+
+ public LineAdder(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public List makeStations() {
+ messageView.printUpwardTerminalStationInputMessage();
+ String UpwardTerminalStationName = inputView.getName();
+ messageView.printDownTerminalStationInputMessage();
+ String DownTerminalStationName = inputView.getName();
+
+ stationValidator.validateContainsStations(UpwardTerminalStationName);
+ stationValidator.validateContainsStations(DownTerminalStationName);
+
+ List stations = new LinkedList<>();
+ stations.add(new Station(UpwardTerminalStationName));
+ stations.add(new Station(DownTerminalStationName));
+ return stations;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printAddLineMessage();
+
+ String lineName = inputView.getName();
+ lineValidator.validateAddLine(lineName);
+
+ Line line = new Line(lineName);
+ line.addAllStation(makeStations());
+ LineRepository.addLine(line);
+
+ messageView.printAddLineSuccessMessage();
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/lineitem/LineGetter.java b/src/main/java/subway/domain/selector/lineitem/LineGetter.java
new file mode 100644
index 000000000..6e26a36a6
--- /dev/null
+++ b/src/main/java/subway/domain/selector/lineitem/LineGetter.java
@@ -0,0 +1,19 @@
+package subway.domain.selector.lineitem;
+
+import subway.domain.line.LineRepository;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+
+public class LineGetter extends Selector implements Manipulable {
+
+ public LineGetter(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printGetLinesMessage();
+ outputView.printLines(LineRepository.lines());
+ }
+}
diff --git a/src/main/java/subway/domain/selector/lineitem/LineRemover.java b/src/main/java/subway/domain/selector/lineitem/LineRemover.java
new file mode 100644
index 000000000..d10967cfc
--- /dev/null
+++ b/src/main/java/subway/domain/selector/lineitem/LineRemover.java
@@ -0,0 +1,26 @@
+package subway.domain.selector.lineitem;
+
+import subway.domain.line.LineRepository;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+
+public class LineRemover extends Selector implements Manipulable {
+
+ LineValidator lineValidator = new LineValidator();
+
+ public LineRemover(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printRemoveLineInputMessage();
+
+ String lineName = inputView.getName();
+ lineValidator.validateContainsLines(lineName);
+ LineRepository.deleteLineByName(lineName);
+
+ messageView.printRemoveLineSuccessMessage();
+ }
+}
diff --git a/src/main/java/subway/domain/selector/lineitem/LineValidator.java b/src/main/java/subway/domain/selector/lineitem/LineValidator.java
new file mode 100644
index 000000000..d389bd0eb
--- /dev/null
+++ b/src/main/java/subway/domain/selector/lineitem/LineValidator.java
@@ -0,0 +1,45 @@
+package subway.domain.selector.lineitem;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+
+public class LineValidator {
+
+ public static final int MIN_NAME_LENGTH = 2;
+ public static final String DUPLICATE_STATION_NAME_ERROR = "[ERROR] 이미 등록되어있는 노선 입니다.";
+ public static final String UNDER_NAME_LENGTH_ERROR = "[ERROR] 노선 이름은 2글자 이상이어야 합니다.";
+ public static final String NOT_CONTAINS_ERROR = "[ERROR] 입력하신 노선은 등록되지 않았습니다.";
+
+ public void validateAddLine(String name) {
+ validateNameDuplication(name);
+ validateNameLength(name);
+ }
+
+ private void validateNameDuplication(String name) {
+ List lines = LineRepository.lines();
+ for (Line line : lines) {
+ if (line.getName().equals(name)) {
+ throw new IllegalArgumentException(DUPLICATE_STATION_NAME_ERROR);
+ }
+ }
+ }
+
+ private void validateNameLength(String name) {
+ if (name.length() < MIN_NAME_LENGTH) {
+ throw new IllegalArgumentException(UNDER_NAME_LENGTH_ERROR);
+ }
+ }
+
+ public void validateContainsLines(String name) {
+ List lines = LineRepository.lines();
+
+ for (Line line : lines) {
+ if (name.equals(line.getName())) {
+ return;
+ }
+ }
+ throw new IllegalArgumentException(NOT_CONTAINS_ERROR);
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/menu/Menu.java b/src/main/java/subway/domain/selector/menu/Menu.java
new file mode 100644
index 000000000..8b8f640e9
--- /dev/null
+++ b/src/main/java/subway/domain/selector/menu/Menu.java
@@ -0,0 +1,31 @@
+package subway.domain.selector.menu;
+
+import java.util.LinkedHashMap;
+import subway.domain.selector.Selector;
+
+public class Menu extends Selector {
+
+ private final LinkedHashMap subMenus = new LinkedHashMap<>();
+ private final LinkedHashMap items = new LinkedHashMap<>();
+
+ public Menu(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public void addMenus(String key, Menu menu) {
+ subMenus.put(key, menu);
+ }
+
+ public void addMenuItems(String key, Selector item) {
+ items.put(key, item);
+ }
+
+ public LinkedHashMap getMenus() {
+ return subMenus;
+ }
+
+ public LinkedHashMap getItems() {
+ return items;
+ }
+}
diff --git a/src/main/java/subway/domain/selector/menu/MenuRepository.java b/src/main/java/subway/domain/selector/menu/MenuRepository.java
new file mode 100644
index 000000000..371b1231f
--- /dev/null
+++ b/src/main/java/subway/domain/selector/menu/MenuRepository.java
@@ -0,0 +1,53 @@
+package subway.domain.selector.menu;
+
+import java.util.LinkedHashMap;
+import subway.domain.selector.lineitem.LineAdder;
+import subway.domain.selector.lineitem.LineGetter;
+import subway.domain.selector.lineitem.LineRemover;
+import subway.domain.selector.sectionitem.SectionAdder;
+import subway.domain.selector.sectionitem.SectionRemover;
+import subway.domain.selector.stationitem.StationAdder;
+import subway.domain.selector.stationitem.StationGetter;
+import subway.domain.selector.stationitem.StationRemover;
+import subway.domain.selector.utilitem.BackWardItem;
+import subway.domain.selector.utilitem.ExitItem;
+import subway.domain.selector.utilitem.PrintSubwayLineItem;
+
+public class MenuRepository {
+
+ private static final LinkedHashMap menus = new LinkedHashMap<>();
+
+ static {
+ Menu stationMenu = new Menu("1", "역 관리");
+ stationMenu.addMenuItems("1", new StationAdder("1", "역 등록"));
+ stationMenu.addMenuItems("2", new StationRemover("2", "역 삭제"));
+ stationMenu.addMenuItems("3", new StationGetter("3", "역 조회"));
+ stationMenu.addMenuItems("B", new BackWardItem("B", "돌아가기"));
+ menus.put("1", stationMenu);
+
+ Menu lineMenu = new Menu("2", "노선 관리");
+ lineMenu.addMenuItems("1", new LineAdder("1", "노선 등록"));
+ lineMenu.addMenuItems("2", new LineRemover("2", "노선 삭제"));
+ lineMenu.addMenuItems("3", new LineGetter("3", "노선 조회"));
+ lineMenu.addMenuItems("B", new BackWardItem("B", "돌아가기"));
+ menus.put("2", lineMenu);
+
+ Menu sectionMenu = new Menu("3", "구간 관리");
+ sectionMenu.addMenuItems("1", new SectionAdder("1", "구간 등록"));
+ sectionMenu.addMenuItems("2", new SectionRemover("2", "구간 삭제"));
+ sectionMenu.addMenuItems("B", new BackWardItem("B", "돌아가기"));
+ menus.put("3", sectionMenu);
+
+ Menu mainMenu = new Menu("0", "메인");
+ mainMenu.addMenus("1", stationMenu);
+ mainMenu.addMenus("2", lineMenu);
+ mainMenu.addMenus("3", sectionMenu);
+ mainMenu.addMenuItems("4", new PrintSubwayLineItem("4", "지하철 노선도 출력"));
+ mainMenu.addMenuItems("Q", new ExitItem("Q", "종료"));
+ menus.put("0", mainMenu);
+ }
+
+ public static LinkedHashMap menus() {
+ return menus;
+ }
+}
diff --git a/src/main/java/subway/domain/selector/sectionitem/SectionAdder.java b/src/main/java/subway/domain/selector/sectionitem/SectionAdder.java
new file mode 100644
index 000000000..8de4961de
--- /dev/null
+++ b/src/main/java/subway/domain/selector/sectionitem/SectionAdder.java
@@ -0,0 +1,51 @@
+package subway.domain.selector.sectionitem;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.selector.lineitem.LineValidator;
+import subway.domain.selector.stationitem.StationValidator;
+import subway.domain.station.Station;
+
+public class SectionAdder extends Selector implements Manipulable {
+
+ LineValidator lineValidator = new LineValidator();
+ StationValidator stationValidator = new StationValidator();
+ SectionValidator sectionValidator = new SectionValidator();
+
+ public SectionAdder(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printSectionLineInputMessage();
+ String lineName = inputView.getName();
+ lineValidator.validateContainsLines(lineName);
+
+ messageView.printSectionStationNameInputMessage();
+ String stationName = inputView.getName();
+ stationValidator.validateContainsStations(stationName);
+
+ messageView.printSectionOrderInputMessage();
+ int order = inputView.getNumber();
+ addStation(lineName, stationName, order);
+
+ messageView.printSectionRegisterSuccessMessage();
+ }
+
+ private void addStation(String lineName, String stationName, int order) {
+ Line line = LineRepository.getLineByName(lineName);
+ List stations = line.stations();
+ sectionValidator.validateSectionOrder(order, stations.size());
+ Station station = new Station(stationName);
+ sectionValidator.validateStationsDuplication(line, station);
+ line.addStationByIndex(station, order - 1);
+ }
+
+}
+
+
diff --git a/src/main/java/subway/domain/selector/sectionitem/SectionRemover.java b/src/main/java/subway/domain/selector/sectionitem/SectionRemover.java
new file mode 100644
index 000000000..cba346acf
--- /dev/null
+++ b/src/main/java/subway/domain/selector/sectionitem/SectionRemover.java
@@ -0,0 +1,39 @@
+package subway.domain.selector.sectionitem;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.selector.lineitem.LineValidator;
+import subway.domain.selector.stationitem.StationValidator;
+
+public class SectionRemover extends Selector implements Manipulable {
+
+ SectionValidator sectionValidator = new SectionValidator();
+ LineValidator lineValidator = new LineValidator();
+ StationValidator stationValidator = new StationValidator();
+
+ public SectionRemover(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printSectionRemoveLineInputMessage();
+
+ String lineName = inputView.getName();
+ Line line = LineRepository.getLineByName(lineName);
+ lineValidator.validateContainsLines(lineName);
+
+ messageView.printSectionRemoveStationInputMessage();
+ String stationName = inputView.getName();
+ stationValidator.validateContainsStations(stationName);
+ sectionValidator.validateStationCount(line);
+ line.deleteStationByName(stationName);
+
+ messageView.printSectionRemoveSuccessMessage();
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/sectionitem/SectionValidator.java b/src/main/java/subway/domain/selector/sectionitem/SectionValidator.java
new file mode 100644
index 000000000..adbcff2da
--- /dev/null
+++ b/src/main/java/subway/domain/selector/sectionitem/SectionValidator.java
@@ -0,0 +1,32 @@
+package subway.domain.selector.sectionitem;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.station.Station;
+
+public class SectionValidator {
+
+ private static final String SECTION_ORDER_ERROR = "[ERROR] 입력한 구간 순서가 올바르지 않습니다.";
+ private static final String SECTION_FORK_LOAD_ERROR = "[ERROR] 노선에 갈래길은 허용되지 않습니다.";
+ private static final String SECTION_STATION_COUNT_ERROR = "[ERROR] 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없습니다.";
+
+ public void validateSectionOrder(int order, int size) {
+ if (order <= 0 || order > size + 1) {
+ throw new IllegalArgumentException(SECTION_ORDER_ERROR);
+ }
+ }
+
+ public void validateStationsDuplication(Line line, Station station) {
+ if (line.isContainsStation(station)) {
+ throw new IllegalArgumentException(SECTION_FORK_LOAD_ERROR);
+ }
+ }
+
+ public void validateStationCount(Line line) {
+ List stations = line.stations();
+ if (stations.size() <= 2) {
+ throw new IllegalArgumentException(SECTION_STATION_COUNT_ERROR);
+ }
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/stationitem/StationAdder.java b/src/main/java/subway/domain/selector/stationitem/StationAdder.java
new file mode 100644
index 000000000..f79f12396
--- /dev/null
+++ b/src/main/java/subway/domain/selector/stationitem/StationAdder.java
@@ -0,0 +1,28 @@
+package subway.domain.selector.stationitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.station.Station;
+import subway.domain.station.StationRepository;
+
+public class StationAdder extends Selector implements Manipulable {
+
+ StationValidator stationValidator = new StationValidator();
+
+ public StationAdder(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printAddStationMessage();
+
+ String stationName = inputView.getName();
+ stationValidator.validateAddStation(stationName);
+ StationRepository.addStation(new Station(stationName));
+
+ messageView.printAddStationSuccessMessage();
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/stationitem/StationGetter.java b/src/main/java/subway/domain/selector/stationitem/StationGetter.java
new file mode 100644
index 000000000..93370b280
--- /dev/null
+++ b/src/main/java/subway/domain/selector/stationitem/StationGetter.java
@@ -0,0 +1,19 @@
+package subway.domain.selector.stationitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.station.StationRepository;
+
+public class StationGetter extends Selector implements Manipulable {
+
+ public StationGetter(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printGetStationsMessage();
+ outputView.printStations(StationRepository.stations());
+ }
+}
diff --git a/src/main/java/subway/domain/selector/stationitem/StationRemover.java b/src/main/java/subway/domain/selector/stationitem/StationRemover.java
new file mode 100644
index 000000000..38a6c71bd
--- /dev/null
+++ b/src/main/java/subway/domain/selector/stationitem/StationRemover.java
@@ -0,0 +1,27 @@
+package subway.domain.selector.stationitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+import subway.domain.station.StationRepository;
+
+public class StationRemover extends Selector implements Manipulable {
+
+ StationValidator stationValidator = new StationValidator();
+
+ public StationRemover(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ messageView.printRemoveStationMessage();
+
+ String stationName = inputView.getName();
+ stationValidator.validateRemoveStation(stationName);
+ StationRepository.deleteStationByName(stationName);
+
+ messageView.printRemoveStationSuccessMessage();
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/stationitem/StationValidator.java b/src/main/java/subway/domain/selector/stationitem/StationValidator.java
new file mode 100644
index 000000000..ca134c216
--- /dev/null
+++ b/src/main/java/subway/domain/selector/stationitem/StationValidator.java
@@ -0,0 +1,70 @@
+package subway.domain.selector.stationitem;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.station.Station;
+import subway.domain.station.StationRepository;
+
+public class StationValidator {
+
+ public static final int MIN_NAME_LENGTH = 2;
+ public static final String DUPLICATE_STATION_NAME_ERROR = "\n[ERROR] 이미 등록되어있는 역 입니다.";
+ public static final String UNDER_NAME_LENGTH_ERROR = "[ERROR] 역 이름은 2글자 이상이어야 합니다.";
+ public static final String CONTAINS_LINE_ERROR = "[ERROR] 노선에 등록된 역은 삭제할 수 없습니다.";
+ public static final String NOT_CONTAINS_ERROR = "[ERROR] 입력하신 역은 등록되지 않았습니다.";
+
+ public void validateAddStation(String name) {
+ validateNameDuplication(name);
+ validateNameLength(name);
+ }
+
+ public void validateRemoveStation(String name) {
+ validateContainsStations(name);
+ validateContainsLines(name);
+ }
+
+ private void validateNameDuplication(String name) {
+ List stations = StationRepository.stations();
+ for (Station station : stations) {
+ if (station.getName().equals(name)) {
+ throw new IllegalArgumentException(DUPLICATE_STATION_NAME_ERROR);
+ }
+ }
+ }
+
+ private void validateNameLength(String name) {
+ if (name.length() < MIN_NAME_LENGTH) {
+ throw new IllegalArgumentException(UNDER_NAME_LENGTH_ERROR);
+ }
+ }
+
+ private void validateContainsLines(String name) {
+ List lines = LineRepository.lines();
+ for (Line line : lines) {
+ validateContainsLine(line, name);
+ }
+ }
+
+ private void validateContainsLine(Line line, String name) {
+ List stations = line.stations();
+
+ for (Station station : stations) {
+ if (station.getName().equals(name)) {
+ throw new IllegalArgumentException(CONTAINS_LINE_ERROR);
+ }
+ }
+ }
+
+ public void validateContainsStations(String name) {
+ List stations = StationRepository.stations();
+
+ for (Station station : stations) {
+ if (name.equals(station.getName())) {
+ return;
+ }
+ }
+ throw new IllegalArgumentException(NOT_CONTAINS_ERROR);
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/utilitem/BackWardItem.java b/src/main/java/subway/domain/selector/utilitem/BackWardItem.java
new file mode 100644
index 000000000..725aa0ee7
--- /dev/null
+++ b/src/main/java/subway/domain/selector/utilitem/BackWardItem.java
@@ -0,0 +1,13 @@
+package subway.domain.selector.utilitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+
+public class BackWardItem extends Selector implements Manipulable {
+
+ public BackWardItem(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/utilitem/ExitItem.java b/src/main/java/subway/domain/selector/utilitem/ExitItem.java
new file mode 100644
index 000000000..0758b710b
--- /dev/null
+++ b/src/main/java/subway/domain/selector/utilitem/ExitItem.java
@@ -0,0 +1,13 @@
+package subway.domain.selector.utilitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+
+public class ExitItem extends Selector implements Manipulable {
+
+ public ExitItem(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+}
diff --git a/src/main/java/subway/domain/selector/utilitem/PrintSubwayLineItem.java b/src/main/java/subway/domain/selector/utilitem/PrintSubwayLineItem.java
new file mode 100644
index 000000000..29a597f81
--- /dev/null
+++ b/src/main/java/subway/domain/selector/utilitem/PrintSubwayLineItem.java
@@ -0,0 +1,18 @@
+package subway.domain.selector.utilitem;
+
+import subway.domain.selector.Manipulable;
+import subway.domain.selector.Selector;
+
+public class PrintSubwayLineItem extends Selector implements Manipulable {
+
+ public PrintSubwayLineItem(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public void execute() {
+ outputView.printSubwayLineMap();
+ }
+
+}
diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/station/Station.java
similarity index 77%
rename from src/main/java/subway/domain/Station.java
rename to src/main/java/subway/domain/station/Station.java
index bdb142590..6aaecb076 100644
--- a/src/main/java/subway/domain/Station.java
+++ b/src/main/java/subway/domain/station/Station.java
@@ -1,6 +1,7 @@
-package subway.domain;
+package subway.domain.station;
public class Station {
+
private String name;
public Station(String name) {
@@ -11,5 +12,4 @@ public String getName() {
return name;
}
- // 추가 기능 구현
}
diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/station/StationRepository.java
similarity index 70%
rename from src/main/java/subway/domain/StationRepository.java
rename to src/main/java/subway/domain/station/StationRepository.java
index b7245c0f3..65cbe56cb 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;
@@ -6,6 +6,7 @@
import java.util.Objects;
public class StationRepository {
+
private static final List stations = new ArrayList<>();
public static List stations() {
@@ -16,7 +17,11 @@ public static void addStation(Station station) {
stations.add(station);
}
- public static boolean deleteStation(String name) {
+ public static void addAllStation(List stationsList) {
+ stations.addAll(stationsList);
+ }
+
+ public static boolean deleteStationByName(String name) {
return stations.removeIf(station -> Objects.equals(station.getName(), name));
}
}
diff --git a/src/main/java/subway/domain/util/DataFactory.java b/src/main/java/subway/domain/util/DataFactory.java
new file mode 100644
index 000000000..4165f8041
--- /dev/null
+++ b/src/main/java/subway/domain/util/DataFactory.java
@@ -0,0 +1,45 @@
+package subway.domain.util;
+
+import java.util.Arrays;
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.station.Station;
+import subway.domain.station.StationRepository;
+
+public class DataFactory {
+
+ public void makeSubwayData() {
+ Station station1 = new Station("교대역");
+ Station station2 = new Station("강남역");
+ Station station3 = new Station("역삼역");
+ Station station4 = new Station("남부터미널역");
+ Station station5 = new Station("양재역");
+ Station station6 = new Station("양재시민의숲역");
+ Station station7 = new Station("매봉역");
+
+ List stations = Arrays
+ .asList(station1, station2, station3, station4, station5, station6, station7);
+ makeStationData(stations);
+ makeLineData(stations);
+ }
+
+ private void makeStationData(List stations) {
+ StationRepository.addAllStation(stations);
+ }
+
+ private void makeLineData(List stations) {
+ Line line1 = new Line("2호선");
+ line1.addAllStation(Arrays.asList(stations.get(0), stations.get(1), stations.get(2)));
+ LineRepository.addLine(line1);
+
+ Line line2 = new Line("3호선");
+ line2.addAllStation(
+ Arrays.asList(stations.get(0), stations.get(3), stations.get(4), stations.get(6)));
+ LineRepository.addLine(line2);
+
+ Line line3 = new Line("신분당선");
+ line3.addAllStation(Arrays.asList(stations.get(1), stations.get(4), stations.get(5)));
+ LineRepository.addLine(line3);
+ }
+}
diff --git a/src/main/java/subway/view/InputValidator.java b/src/main/java/subway/view/InputValidator.java
new file mode 100644
index 000000000..34701d326
--- /dev/null
+++ b/src/main/java/subway/view/InputValidator.java
@@ -0,0 +1,24 @@
+package subway.view;
+
+import java.util.regex.Pattern;
+import subway.domain.selector.menu.Menu;
+
+public class InputValidator {
+
+ private static final String INVALID_SELECTOR_ID_ERROR = "[ERROR] 선택할 수 없는 기능입니다.";
+ private static final String SPECIAL_CHARACTER_PATTERN = "[0-9|a-z |A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝 ]*";
+ private static final String SPECIAL_CHARACTER_ERROR_MESSAGE = "[ERROR] 이름에 특수문자가 포함 되어있습니다.";
+
+ public static void validateContainSpecialCharacters(String name) {
+ if (!Pattern.matches(SPECIAL_CHARACTER_PATTERN, name)) {
+ throw new IllegalArgumentException(SPECIAL_CHARACTER_ERROR_MESSAGE);
+ }
+ }
+
+ public void validateSelectorId(Menu menu, String Id) {
+ if (menu.getMenus().get(Id) == null && menu.getItems().get(Id) == null) {
+ throw new IllegalArgumentException(INVALID_SELECTOR_ID_ERROR);
+ }
+ }
+
+}
diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java
new file mode 100644
index 000000000..1dfbbc14d
--- /dev/null
+++ b/src/main/java/subway/view/InputView.java
@@ -0,0 +1,45 @@
+package subway.view;
+
+import java.util.Scanner;
+import subway.domain.selector.Selector;
+import subway.domain.selector.menu.Menu;
+
+public class InputView {
+
+ private static final Scanner scanner = new Scanner(System.in);
+ private static final InputValidator inputValidator = new InputValidator();
+ private static final MessageView messageView = new MessageView();
+ private static final OutputView outputView = new OutputView();
+
+ public Selector getSelector(Menu menu) {
+ try {
+ messageView.printSelectSelectorMessage();
+ String input = scanner.nextLine();
+ inputValidator.validateSelectorId(menu, input);
+ if (menu.getMenus().get(input) != null) {
+ return menu.getMenus().get(input);
+ }
+ return menu.getItems().get(input);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ outputView.printScreen(menu);
+ return getSelector(menu);
+ }
+ }
+
+ public String getName() {
+ try {
+ String name = scanner.nextLine();
+ inputValidator.validateContainSpecialCharacters(name);
+ return name;
+ } catch (Exception e){
+ System.out.println(e.getMessage());
+ return getName();
+ }
+ }
+
+ public int getNumber() {
+ return Integer.parseInt(scanner.nextLine());
+ }
+
+}
diff --git a/src/main/java/subway/view/MessageView.java b/src/main/java/subway/view/MessageView.java
new file mode 100644
index 000000000..d622bf873
--- /dev/null
+++ b/src/main/java/subway/view/MessageView.java
@@ -0,0 +1,111 @@
+package subway.view;
+
+public class MessageView {
+
+ public static final String STATION_ADD = "## 등록할 역 이름을 입력하세요.";
+ public static final String STATION_ADD_SUCCESS = "\n[INFO] 지하철 역이 등록되었습니다.";
+ public static final String STATION_GET_SUCCESS = "\n## 역 목록";
+ public static final String STATION_REMOVE_INPUT = "## 삭제할 역 이름을 입력하세요.";
+ public static final String STATION_REMOVE_SUCCESS = "[INFO] 지하철 역이 삭제되었습니다.";
+ public static final String LINE_ADD = "## 등록할 노선 이름을 입력하세요.";
+ public static final String LINE_ADD_SUCCESS = "[INFO] 지하철 노선이 등록되었습니다.";
+ public static final String LINE_GET_SUCCESS = "\n## 노선 목록";
+ public static final String LINE_REMOVE_INPUT = "## 삭제할 노선 이름을 입력하세요.";
+ public static final String LINE_REMOVE_SUCCESS = "[INFO] 지하철 노선이 삭제되었습니다.";
+ public static final String UPWARD_TERMINAL_STATION_NAME_INPUT = "## 등록할 노선의 상행 종점역 이름을 입력하세요.";
+ public static final String DOWN_TERMINAL_STATION_NAME_INPUT = "## 등록할 노선의 하행 종점역 이름을 입력하세요.";
+ public static final String SECTION_LINE_INPUT = "## 노선을 입력하세요.";
+ public static final String SECTION_STATION_NAME_INPUT = "## 역 이름을 입력하세요.";
+ public static final String SECTION_ORDER_INPUT = "## 순서를 입력하세요.";
+ public static final String SECTION_REGISTER_SUCCESS = "## 구간이 등록되었습니다.";
+ public static final String SECTION_REMOVE_LINE_INPUT = "## 삭제할 구간의 노선을 입력하세요.";
+ public static final String SECTION_REMOVE_STATION_INPUT = "## 삭제할 구간의 역을 입력하세요.";
+ public static final String SECTION_REMOVE_SUCCESS = "[INFO] 구간이 삭제되었습니다.";
+ public static final String SELECT_SELECTOR = "## 원하는 기능을 선택하세요.";
+ public static final String SUBWAY_LINE_MAP = "## 지하철 노선도";
+
+ public void printAddStationMessage() {
+ System.out.println(STATION_ADD);
+ }
+
+ public void printAddStationSuccessMessage() {
+ System.out.println(STATION_ADD_SUCCESS);
+ }
+
+ public void printGetStationsMessage() {
+ System.out.println(STATION_GET_SUCCESS);
+ }
+
+ public void printRemoveStationMessage() {
+ System.out.println(STATION_REMOVE_INPUT);
+ }
+
+ public void printRemoveStationSuccessMessage() {
+ System.out.println(STATION_REMOVE_SUCCESS);
+ }
+
+ public void printAddLineMessage() {
+ System.out.println(LINE_ADD);
+ }
+
+ public void printAddLineSuccessMessage() {
+ System.out.println(LINE_ADD_SUCCESS);
+ }
+
+ public void printRemoveLineInputMessage() {
+ System.out.println(LINE_REMOVE_INPUT);
+ }
+
+ public void printGetLinesMessage() {
+ System.out.println(LINE_GET_SUCCESS);
+ }
+
+ public void printUpwardTerminalStationInputMessage() {
+ System.out.println(UPWARD_TERMINAL_STATION_NAME_INPUT);
+ }
+
+ public void printDownTerminalStationInputMessage() {
+ System.out.println(DOWN_TERMINAL_STATION_NAME_INPUT);
+ }
+
+ public void printRemoveLineSuccessMessage() {
+ System.out.println(LINE_REMOVE_SUCCESS);
+ }
+
+ public void printSectionLineInputMessage() {
+ System.out.println(SECTION_LINE_INPUT);
+ }
+
+ public void printSectionStationNameInputMessage() {
+ System.out.println(SECTION_STATION_NAME_INPUT);
+ }
+
+ public void printSectionOrderInputMessage() {
+ System.out.println(SECTION_ORDER_INPUT);
+ }
+
+ public void printSectionRegisterSuccessMessage() {
+ System.out.println(SECTION_REGISTER_SUCCESS);
+ }
+
+ public void printSectionRemoveLineInputMessage() {
+ System.out.println(SECTION_REMOVE_LINE_INPUT);
+ }
+
+ public void printSectionRemoveStationInputMessage() {
+ System.out.println(SECTION_REMOVE_STATION_INPUT);
+ }
+
+ public void printSectionRemoveSuccessMessage() {
+ System.out.println(SECTION_REMOVE_SUCCESS);
+ }
+
+ public void printSelectSelectorMessage() {
+ System.out.println(SELECT_SELECTOR);
+ }
+
+ public void printSubwayLineMapMessage() {
+ System.out.println(SUBWAY_LINE_MAP);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java
new file mode 100644
index 000000000..46970bccc
--- /dev/null
+++ b/src/main/java/subway/view/OutputView.java
@@ -0,0 +1,61 @@
+package subway.view;
+
+import java.util.List;
+import subway.domain.line.Line;
+import subway.domain.line.LineRepository;
+import subway.domain.selector.menu.Menu;
+import subway.domain.station.Station;
+
+public class OutputView {
+
+ private static final String INFORMATION_TAG = "[INFO]";
+ private static final String LINE_STATION_SEPARATOR = "---";
+ private static final String SCREEN_MESSAGE_START = "\n## ";
+ private static final String SCREEN_MESSAGE_END = " 화면";
+ private static final String ID_SEPARATOR = ". ";
+ MessageView messageView = new MessageView();
+
+ public void printScreen(Menu menu) {
+ System.out.println(SCREEN_MESSAGE_START + menu + SCREEN_MESSAGE_END);
+ printMenus(menu);
+ printItems(menu);
+ System.out.println();
+ }
+
+ private void printMenus(Menu menu) {
+ for (String key : menu.getMenus().keySet()) {
+ System.out.println(key + ID_SEPARATOR + menu.getMenus().get(key));
+ }
+ }
+
+ private void printItems(Menu menu) {
+ for (String key : menu.getItems().keySet()) {
+ System.out.println(key + ID_SEPARATOR + menu.getItems().get(key));
+ }
+ }
+
+ public void printStations(List stations) {
+ for (Station station : stations) {
+ System.out.println(INFORMATION_TAG + " " + station.getName());
+ }
+ }
+
+ public void printLines(List lines) {
+ for (Line line : lines) {
+ System.out.println(INFORMATION_TAG + " " + line.getName());
+ }
+ }
+
+ public void printSubwayLineMap() {
+ List lines = LineRepository.lines();
+ messageView.printSubwayLineMapMessage();
+
+ for (Line line : lines) {
+ System.out.println(INFORMATION_TAG + " " + line.getName());
+ System.out.println(INFORMATION_TAG + " " + LINE_STATION_SEPARATOR);
+ printStations(line.stations());
+ System.out.println();
+ }
+ }
+
+}