Skip to content

[패어 매칭 애플리케이션] 이호석 제출 합니다(5시간 딱.. 5시간..) #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
9fd3893
feat: 페어 매칭 시작시 기능입력 기능 및 예외 구현
HiiWee Dec 15, 2022
21e5439
feat: 과정, 레벨, 미션을 정의한 enum 추가
HiiWee Dec 15, 2022
5ef8f4f
feat: 크루 정보를 담는 도메인 정의
HiiWee Dec 15, 2022
bbcdf57
feat: 사용자에게 과정, 레벨, 미션을 입력받는 기능 추가
HiiWee Dec 15, 2022
ed1eace
feat: 크루 목록 파일에서 불러와 초기 저장 하는 기능 추가
HiiWee Dec 15, 2022
d29a3b8
feat: 이미 매칭했던 적이 있던 코스, 레벨, 미션에 대한 분기 처리 기능 추가
HiiWee Dec 15, 2022
62093c9
feat: 없는 코스, 레벨, 미션에 대한 예외 처리 기능 추가
HiiWee Dec 15, 2022
570a900
feat: 페어 매칭 기능 추가
HiiWee Dec 15, 2022
324bf65
feat: 동일 코스, 레벨, 미션에 대해 페어매칭이 존재하면 재매칭 여부 및 재매칭 기능 추가
HiiWee Dec 15, 2022
fd4e4cf
feat: 페어매칭, 재페어매칭시 페어매칭 결과 출력 기능 추가
HiiWee Dec 15, 2022
8101455
docs: 완료된 기능목록 업데이트
HiiWee Dec 15, 2022
d62fe83
feat: 페어 매칭 결과 조회 기능 및 예외 처리 추가
HiiWee Dec 15, 2022
8e5b938
feat: 페어 매칭 초기화 기능 추가
HiiWee Dec 15, 2022
232c382
style: 인덴트 및 임포트문 정리
HiiWee Dec 15, 2022
9bdc2c7
refactor: 크루 셔플시 List<String>으로 셔플하도록 변경
HiiWee Dec 15, 2022
143d040
feat: 페어 매칭 중복 3번시 재시도 및 예외 처리 기능 추가
HiiWee Dec 15, 2022
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
46 changes: 46 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## 페어매칭 관리 애플리케이션

## 기능 목록 정의서

## 페어 매칭 프로그램 시작시
- **기능 목록**
- [x] 기능을 선택할 수 있는 화면을 보여준다.
- [x] 사용자는 선택할 기능을 입력한다.
- [X] 초기 사용자의 목록을 md 파일에서 가져와 저장한다.

- **예외 목록**
- [x] 1, 2, 3, Q가 아닌 입력은 예외 처리한다.

## 1. 페어 매칭 선택시
- **페어 매칭 기능 목록**
- [X] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다.
- [x] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.`
- [x] 해당 과정에 맞는 크루들을 셔플하여 페어 매칭 결과를 만든다.
- [X] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다.
- [x] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다.
- [x] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다.
- **페어 재매칭 기능 목록**
- [x] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.`
- [x] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다.
- [x] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다.
- [x] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다.

- **예외 목록**
- [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다.
- [X] 각 과정, 레벨, 미션이 존재하지 않으면 예외 처리한다.
- [X] 만약 미션이 없는 레벨이라면 예외 처리한다.
- [X] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다.

## 2. 페어 조회 선택시
- **조회 기능 목록**
- [x] 과정, 레벨, 미션에 대한 입력을 순서대로 `입력받는다.`
- [x] 해당 입력에 대한 페어 매칭 결과를 출력한다.
- **예외 목록**
- [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다.
- [x] 각 과정, 레벨, 미션은 모두 존재하야 한다.
- [x] 만약 미션이 없는 레벨이라면 예외 처리한다.
- [x] 조회할 매칭 결과가 없다면 예외 처리한다.

## 3. 페어 초기화 선택시
- **초기화 기능 목록**
- [x] 모든 레벨의 모든 페어 매칭 기록을 초기화 한다
6 changes: 4 additions & 2 deletions src/main/java/pairmatching/Application.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package pairmatching;

import pairmatching.controller.PairMatchingController;

public class Application {
public static void main(String[] args) {
// TODO 구현 진행

PairMatchingController pairMatchingController = new PairMatchingController();
pairMatchingController.run();
}
}
83 changes: 83 additions & 0 deletions src/main/java/pairmatching/controller/PairMatchingController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package pairmatching.controller;

import java.util.List;
import pairmatching.exception.NoPariResultException;
import pairmatching.exception.PairAlreadyExistException;
import pairmatching.service.PairMatchingService;
import pairmatching.util.InputValidator;
import pairmatching.view.InputView;
import pairmatching.view.OutputView;

public class PairMatchingController {
public static final String RETRY = "네";
private final InputView inputView = new InputView();
private final OutputView outputView = new OutputView();
private final PairMatchingService pairMatchingService = new PairMatchingService();

public void run() {
try {
determineMenuSelect(InputValidator.validateSelectMenu(inputView.inputSelectMenu()));
} catch (IllegalArgumentException exception) {
outputView.printMessage(exception.getMessage());
run();
}
}

private void determineMenuSelect(final String validatedSelectMenu) {
if (validatedSelectMenu.equals(InputValidator.PAIR_MATCHING)) {
requestPairMatching();
}
if (validatedSelectMenu.equals(InputValidator.PAIR_VIEW)) {
requestPairView();
}
if (validatedSelectMenu.equals(InputValidator.PAIR_RESET)) {
requestPairReset();
}
}

private void requestPairMatching() {
List<String> courseInformation = InputValidator.validateCourseInformation(inputView.inputCourseInformation());
try {
outputView.printPairMatchingResult(pairMatchingService.pairMatch(courseInformation));
run();
} catch (PairAlreadyExistException exception) {
requestRetry(courseInformation);
} catch (IllegalArgumentException exception) {
outputView.printMessage(exception.getMessage());
requestPairMatching();
}
}

private void requestRetry(final List<String> courseInformation) {
try {
if (InputValidator.validateRetryInput(inputView.inputRetry()).equals(RETRY)) {
outputView.printPairMatchingResult(pairMatchingService.retryPairMatching(courseInformation));
run();
}
} catch (IllegalArgumentException exception) {
outputView.printMessage(exception.getMessage());
requestRetry(courseInformation);
}
}

private void requestPairView() {
try {
List<String> courseInformation = InputValidator.validateCourseInformation(
inputView.inputCourseInformation());
outputView.printPairMatchingResult(pairMatchingService.findPairMatchResult(courseInformation));
run();
} catch (NoPariResultException exception) {
outputView.printMessage(exception.getMessage());
run();
} catch (IllegalArgumentException exception) {
outputView.printMessage(exception.getMessage());
requestPairView();
}
}

private void requestPairReset() {
outputView.printResetMessage();
pairMatchingService.deleteAllMatchingResult();
run();
}
}
64 changes: 64 additions & 0 deletions src/main/java/pairmatching/domain/CourseInformation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package pairmatching.domain;

import java.util.List;
import java.util.Objects;
import pairmatching.domain.enums.Course;
import pairmatching.domain.enums.Level;
import pairmatching.domain.enums.Mission;
import pairmatching.message.ErrorMessage;

public class CourseInformation {
public static final int COURSE_INDEX = 0;
public static final int LEVEL_INDEX = 1;
public static final int MISSION_INDEX = 2;
private final Course course;
private final Level level;
private final Mission mission;

private CourseInformation(final Course course, final Level level, final Mission mission) {
this.course = course;
this.level = level;
this.mission = mission;
}

public static CourseInformation of(final List<String> inputInformation) {
CourseInformation courseInformation = new CourseInformation(
Course.findCourse(inputInformation.get(COURSE_INDEX)),
Level.findLevel(inputInformation.get(LEVEL_INDEX)),
Mission.findMission(inputInformation.get(MISSION_INDEX))
);
return validateCourseInformation(courseInformation);
}

private static CourseInformation validateCourseInformation(final CourseInformation courseInformation) {
if (!courseInformation.level.isExistsMission(courseInformation.mission)) {
throw new IllegalArgumentException(ErrorMessage.NO_MISSION_IN_LEVEL_ERROR);
}
return courseInformation;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CourseInformation that = (CourseInformation) o;
return course == that.course && level == that.level && mission == that.mission;
}

@Override
public int hashCode() {
return Objects.hash(course, level, mission);
}

public Course getCourse() {
return course;
}

public Level getLevel() {
return level;
}
}
39 changes: 39 additions & 0 deletions src/main/java/pairmatching/domain/Crew.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package pairmatching.domain;

import java.util.Objects;
import pairmatching.domain.enums.Course;

public class Crew {
private final Course course;
private final String name;

public Crew(final Course course, final String name) {
this.course = course;
this.name = name;
}

public boolean containsCourse(final Course course) {
return this.course == course;
}

public String getName() {
return name;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Crew crew = (Crew) o;
return course == crew.course && Objects.equals(name, crew.name);
}

@Override
public int hashCode() {
return Objects.hash(course, name);
}
}
50 changes: 50 additions & 0 deletions src/main/java/pairmatching/domain/Crews.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package pairmatching.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Crews {
private final List<Crew> crews;

public Crews(final List<Crew> crews) {
this.crews = crews;
}

public List<Pair> makePairList() {
if (crews.size() % 2 == 0) {
return createEvenPair();
}
return createOddPair();
}

private List<Pair> createOddPair() {
List<Pair> pairs = new ArrayList<>();
for (int index = 0; index < crews.size(); index++) {
if (index == crews.size() - 3) {
pairs.add(new Pair(List.of(crews.get(index), crews.get(index + 1), crews.get(index + 2))));
break;
}
if (index % 2 == 1) {
pairs.add(new Pair(List.of(crews.get(index - 1), crews.get(index))));
}
}
return pairs;
}

private List<Pair> createEvenPair() {
List<Pair> pairs = new ArrayList<>();
for (int index = 0; index < crews.size(); index++) {
if (index % 2 == 1) {
pairs.add(new Pair(List.of(crews.get(index - 1), crews.get(index))));
}
}
return pairs;
}

public List<String> getCrewNameList() {
return crews.stream()
.map(Crew::getName)
.collect(Collectors.toList());
}
}
29 changes: 29 additions & 0 deletions src/main/java/pairmatching/domain/Pair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package pairmatching.domain;

import java.util.List;

public class Pair {
public static final String SEPARATOR = " : ";
private final List<Crew> pair;

public Pair(final List<Crew> pair) {
this.pair = pair;
}

public boolean containsPair(List<Pair> pairs) {
return pairs.stream()
.map(input -> input.pair)
.anyMatch(pair -> pair.containsAll(this.pair));
}

@Override
public String toString() {
StringBuilder log = new StringBuilder();
pair.stream()
.map(Crew::getName)
.limit(pair.size() - 1)
.forEach(name -> log.append(name).append(SEPARATOR));
log.append(pair.get(pair.size() - 1).getName());
return log.toString();
}
}
11 changes: 11 additions & 0 deletions src/main/java/pairmatching/domain/PairMatching.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pairmatching.domain;

public class PairMatching {
private final CourseInformation courseInformation;
private final Crews crews;

public PairMatching(final CourseInformation courseInformation, final Crews crews) {
this.courseInformation = courseInformation;
this.crews = crews;
}
}
26 changes: 26 additions & 0 deletions src/main/java/pairmatching/domain/enums/Course.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pairmatching.domain.enums;

import java.util.Arrays;
import pairmatching.message.ErrorMessage;

public enum Course {
BACKEND("백엔드"),
FRONTEND("프론트엔드");

private String name;

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

public static Course findCourse(final String inputCourse) {
return Arrays.stream(Course.values())
.filter(course -> course.containsName(inputCourse))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(ErrorMessage.NO_COURSE_ERROR));
}

private boolean containsName(final String inputCourse) {
return name.equals(inputCourse);
}
}
Loading