Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ea07d13
docs: 개발 기능 목록을 작성한다
Combi153 Dec 16, 2022
9d8afe3
feat: 기능 명령어 선택 기능을 구현한다
Combi153 Dec 16, 2022
036c63d
feat: 기능 명령어 검증 기능을 구현한다
Combi153 Dec 16, 2022
e1caaef
feat: 명령어 실행 기능을 구현한다
Combi153 Dec 16, 2022
e46b68c
feat: 과정, 레벨, 미션 선택 기능을 구현한다
Combi153 Dec 16, 2022
ca995b2
feat: 과정, 레벨, 미션 검증 기능
Combi153 Dec 16, 2022
a5c90ec
feat: 매칭 이력 확인 기능을 구현한다
Combi153 Dec 16, 2022
cfd1fe8
feat: 매칭 기능을 구현한다
Combi153 Dec 16, 2022
c360818
feat: 매칭 검증 및 기록 기능을 구현한다
Combi153 Dec 16, 2022
0f7ca80
feat: 매칭 검증 및 기록 기능을 구현한다
Combi153 Dec 16, 2022
abef637
feat: 애플리케이션 실행 기능을 구현한다
Combi153 Dec 16, 2022
4498a31
docs: 개발 기능 목록을 수정한다
Combi153 Dec 16, 2022
6dfa2ca
feat: 재매칭 선택 및 검증 기능을 구현한다
Combi153 Dec 16, 2022
fb9d733
feat: 매칭 조회 및 초기화 기능을 구현한다
Combi153 Dec 16, 2022
72e72fc
fix: Mission 클래스의 레벨과 미션을 함께 비교하는 함수를 수정한다
Combi153 Dec 16, 2022
9d76d5a
chore: 상수 메시지, 하드코딩 등을 수정한다
Combi153 Dec 16, 2022
4c18bc6
refactor: Controller 클래스를 분리한다
Combi153 Dec 16, 2022
66977af
refactor: 재매칭 명령어 입력 기능을 리팩토링한다
Combi153 Dec 16, 2022
eec48bc
chore: 클래스명 변경, 패키지 구조 변경을 반영한다
Combi153 Dec 16, 2022
ecf41e0
docs: 개발 기능 목록을 수정한다
Combi153 Dec 16, 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
41 changes: 41 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 페어매칭 프로그램

## 개발 기능 목록

- [x] 기능 명령어 선택 기능
- [x] 문자 한 개를 입력하는지 검증

- [x] 기능 명령어 검증 기능
- [x] 1, 2, 3, Q 중 하나인지 검증

- [x] 명령어 실행 기능
- [x] 명령어가 입력되면 각 명령에 맞는 기능 실행

- [x] 과정, 레벨, 미션 선택 기능
- [x] ", "로 구분되는 문자열인지 검증

- [x] 과정, 레벨, 미션 검증 기능
- [x] 각 보기에 부합하는지 검증

- [x] 매칭 이력 확인 기능

- [x] 매칭 기능
- [x] 파일 읽기
- [x] 크루원 이름 셔플
- [x] 2명(마지막 3명 허용)씩 매칭

- [x] 매칭 검증 기능
- [x] 같은 레벨 하 매칭 중복 검증
- [x] 매칭 실패 시 오류 발생
- 매칭 실패 경우
- [ ] 이름 중복 확인 기능

- [x] 재매칭 선택 및 검증 기능
- [x] 네, 아니오 중 하나인지 검증
- [ ] 재매칭 아니오 선택 후 출력문 변화

- [x] 매칭 조회 기능
- [x] 매칭 이력 없을 경우 오류
- [x] 매칭 이력 있는 경우 출력

- [x] 매칭 초기화 기능
7 changes: 6 additions & 1 deletion src/main/java/pairmatching/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package pairmatching;

import pairmatching.controller.MainController;
import pairmatching.view.InputView;
import pairmatching.view.OutputView;

public class Application {
public static void main(String[] args) {
// TODO 구현 진행
MainController mainController = new MainController(new InputView(), new OutputView());
mainController.runMain();
}
}
76 changes: 76 additions & 0 deletions src/main/java/pairmatching/controller/InputController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package pairmatching.controller;

import pairmatching.controller.command.MainCommand;
import pairmatching.controller.command.ReMatchingCommand;
import pairmatching.domain.choice.Choice;
import pairmatching.domain.choice.ChoiceMaker;
import pairmatching.view.InputView;
import pairmatching.view.OutputView;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class InputController {

private final InputView inputView;
private final OutputView outputView;

public InputController(InputView inputView, OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}

public MainCommand readValidCommand() {
return repeatUntilGettingValidValue(this::readCommand);
}

public Choice readValidChoice() {
return repeatUntilGettingValidValue(this::readChoice);
}

public ReMatchingCommand readValidReMatchingCommand() {
return repeatUntilGettingValidValue(this::readReMatchingCommand);
}

private MainCommand readCommand() {
outputView.printCommandGuide();
String inputCommand = inputView.readCommand();
return MainCommand.valueOfCommand(inputCommand);
}

private Choice readChoice() {
outputView.printChoiceGuide();
List<String> choices = inputView.readChoices();
ChoiceMaker choiceMaker = new ChoiceMaker();
return choiceMaker.createChoice(choices);
}

private ReMatchingCommand readReMatchingCommand() {
outputView.printReMatchingGuide();
String input = inputView.readReMatchingCommand();
return ReMatchingCommand.valueOfReMatchingCommand(input);
}

private <T> T repeatUntilGettingValidValue(Supplier<T> getSomething) {
while (true) {
try {
return getSomething.get();
} catch (IllegalArgumentException e) {
outputView.printErrorMessage(e.getMessage());
}
}
}

public <T> void repeatUntilGettingValidValue(Consumer<T> getSomething, T input) {
boolean isContinuing = true;
while (isContinuing) {
try {
getSomething.accept(input);
isContinuing = false;
} catch (IllegalArgumentException e) {
outputView.printErrorMessage(e.getMessage());
}
}
}
}
94 changes: 94 additions & 0 deletions src/main/java/pairmatching/controller/MainController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package pairmatching.controller;

import pairmatching.controller.command.MainCommand;
import pairmatching.controller.command.ReMatchingCommand;
import pairmatching.domain.choice.Choice;
import pairmatching.domain.crew.Crew;
import pairmatching.domain.matching.MatchingHistory;
import pairmatching.domain.matching.MatchingProgram;
import pairmatching.domain.matching.PairMatchingMachine;
import pairmatching.view.InputView;
import pairmatching.view.OutputView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class MainController {

private final InputView inputView;
private final OutputView outputView;
private final InputController inputController;

public MainController(InputView inputView, OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
this.inputController = new InputController(inputView, outputView);
}

public void runMain() {
try {
runProgram();
} catch (IOException e) {
outputView.printErrorMessage(e.getMessage());
}
}

private void runProgram() throws IOException {
executeCommand();
}

private void executeCommand() throws IOException {
MainCommand command;
MatchingProgram program = new MatchingProgram(new MatchingHistory(), new PairMatchingMachine());
do {
command = inputController.readValidCommand();
decideAndExecute(command, program);
} while (!command.isCommandOf(MainCommand.QUITTING));
}

private void decideAndExecute(MainCommand command, MatchingProgram program) throws IOException {
if (command.isCommandOf(MainCommand.MATCHING)) {
executeMatchingCommand(program);
}
if (command.isCommandOf(MainCommand.CHECKING)) {
executeCheckingCommand(program);
}
if (command.isCommandOf(MainCommand.INITIALIZING)) {
executeInitializingCommand(program);
}
}

private void executeMatchingCommand(MatchingProgram program) throws IOException {
List<Set<Crew>> pairs = new ArrayList<>();
while (pairs.isEmpty()) {
Choice choice = inputController.readValidChoice();
if (program.hasMatched(choice)) {
executeReMatchingCommand(program, choice);
}
if (!program.hasMatched(choice)) {
pairs = program.matchAndRecord(choice);
}
}
outputView.printMatchingResult(pairs);
}

private void executeReMatchingCommand(MatchingProgram program, Choice choice) throws IOException {
ReMatchingCommand command = inputController.readValidReMatchingCommand();
if (command.isCommandOf(ReMatchingCommand.RE_MATCHING)) {
program.deleteHistory(choice);
}
}

private void executeCheckingCommand(MatchingProgram program) {
Choice choice = inputController.readValidChoice();
List<Set<Crew>> pairs = program.show(choice);
outputView.printMatchingResult(pairs);
}

private void executeInitializingCommand(MatchingProgram program) {
program.truncateHistory();
outputView.printInitializingMessage();
}
}
32 changes: 32 additions & 0 deletions src/main/java/pairmatching/controller/command/MainCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package pairmatching.controller.command;

import java.util.Arrays;

public enum MainCommand {
MATCHING("1"),
CHECKING("2"),
INITIALIZING("3"),
QUITTING("Q");

private static final String ERROR_MESSAGE = "[ERROR] %s는 기능이 아닙니다.\n";
private final String command;

MainCommand(String command) {
this.command = command;
}

public static MainCommand valueOfCommand(String inputCommand) {
return Arrays.stream(values())
.filter(value -> inputCommand.equals(value.getCommand()))
.findAny()
.orElseThrow(() -> new IllegalArgumentException(String.format(ERROR_MESSAGE, inputCommand)));
}

public String getCommand() {
return command;
}

public boolean isCommandOf(MainCommand command) {
return this.command.equals(command.getCommand());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pairmatching.controller.command;

import java.util.Arrays;

public enum ReMatchingCommand {
RE_MATCHING("네"),
NON_RE_MATCHING("아니오");

private static final String ERROR_MESSAGE = "[ERROR] %s는 재매칭 명령어가 아닙니다.\n";
private final String command;

ReMatchingCommand(String command) {
this.command = command;
}

public static ReMatchingCommand valueOfReMatchingCommand(String inputCommand) {
return Arrays.stream(values())
.filter(value -> inputCommand.equals(value.getCommand()))
.findAny()
.orElseThrow(() -> new IllegalArgumentException(String.format(ERROR_MESSAGE, inputCommand)));
}

public String getCommand() {
return command;
}

public boolean isCommandOf(ReMatchingCommand command) {
return this.command.equals(command.getCommand());
}
}
42 changes: 42 additions & 0 deletions src/main/java/pairmatching/domain/choice/Choice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package pairmatching.domain.choice;

import pairmatching.domain.item.Course;
import pairmatching.domain.item.Mission;

import java.util.Objects;

public class Choice {

private final Course course;
private final Mission mission;

public Choice(Course course, Mission mission) {
this.course = course;
this.mission = mission;
}

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

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

public boolean hasCourseOf(Course course) {
return this.course.equals(course);
}

public boolean hasSameLevel(Choice choice) {
return mission.isSameLevel(choice.mission);
}
}
17 changes: 17 additions & 0 deletions src/main/java/pairmatching/domain/choice/ChoiceMaker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package pairmatching.domain.choice;

import pairmatching.domain.item.Course;
import pairmatching.domain.item.Level;
import pairmatching.domain.item.Mission;

import java.util.List;

public class ChoiceMaker {

public Choice createChoice(List<String> choices) {
Course course = Course.valueOfCourse(choices.get(0));
Level level = Level.valueOfLevel(choices.get(1));
Mission mission = Mission.valueOfMissionAndLevel(choices.get(2), level);
return new Choice(course, mission);
}
}
26 changes: 26 additions & 0 deletions src/main/java/pairmatching/domain/crew/Crew.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pairmatching.domain.crew;

import pairmatching.domain.item.Course;

public class Crew {

private final Course course;
private final String name;

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

public String getName() {
return name;
}

@Override
public String toString() {
return "Crew{" +
"course=" + course +
", name='" + name + '\'' +
'}';
}
}
Loading