-
Notifications
You must be signed in to change notification settings - Fork 503
[페어 매칭 - 스터디] 조승현 미션 제출합니다 :) #147
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
base: main
Are you sure you want to change the base?
Changes from all commits
823effa
a8c1848
4784324
52365e6
e09784d
0a2beb8
0443fa4
6bbe90f
758efa0
bc26be2
59bc36a
1de38de
80b4a20
1769c1c
dd79965
278fd48
923ce8e
f0d92e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| - 사전 제공 정보 | ||
| * [x] 크루 목록이 담긴 파일을 읽어 리스트에 저장한다. | ||
| * [x] 미션 목록을 리스트에 저장한다. | ||
| * [x] 페어 정보를 관리하는 저장소를 설계한다. | ||
|
|
||
| - 페어 매칭 | ||
| * [x] 기능의 종류를 출력한다. | ||
| * [x] 기능 중 하나의 입력을 받는다. | ||
| * [x] 과정과 미션을 출력한다. | ||
| * [x] 매칭하고자 하는 과정, 레벨, 미션을 입력 받는다. | ||
|
|
||
| * [x] 크루 목록의 순서를 랜덤으로 섞는다. | ||
| * [x] 랜덤으로 섞인 페어 목록에서 페어 매칭을 할 때 앞에서부터 순서대로 두명씩 페어를 맺는다. | ||
| * [x] 홀수인 경우 마지막 남은 크루는 마지막 페어에 포함시킨다. | ||
| * [x] 같은 레벨에서 이미 페어로 만난적이 있는 크루끼리 다시 페어로 매칭 된다면 크루 목록의 순서를 다시 랜덤으로 섞어서 매칭을 시도한다. | ||
| * [x] 3회 시도까지 매칭이 되지 않거나 매칭을 할 수 있는 경우의 수가 없으면 에러 메시지를 출력한다. | ||
|
|
||
| * [x] 페어 매칭 결과를 출력한다. | ||
|
|
||
| - 페어 조회 | ||
| * [x] 과정과 미션을 출력한다. | ||
| * [x] 조회하고자 하는 과정, 레벨, 미션을 입력 받는다. | ||
|
|
||
| - 페어 초기화 | ||
| * [x] 커맨드를 호출하면 저장된 페어 매칭을 제거한다. | ||
| * [x] 초기화 완료 메시지를 출력한다. | ||
|
|
||
| - 종료 | ||
| * [x] 종료 커맨드를 입력하면 애플리케이션이 종료된다. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,11 @@ | ||
| package pairmatching; | ||
|
|
||
| import pairmatching.system.PairApplication; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO 구현 진행 | ||
| PairApplication pairApplication = new PairApplication(); | ||
| pairApplication.run(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.outputview.ErrorMessageOutputView; | ||
| import pairmatching.outputview.OutputView; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public abstract class AbstractController implements Controller { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Controller에서 오류가 발생할 경우 다시 해당 기능을 재요청 하기 위한 방법으로 |
||
| private final OutputView outputView = new ErrorMessageOutputView(); | ||
|
|
||
| @Override | ||
| public void process(Map<String, Object> model) { | ||
| try { | ||
| doProcess(model); | ||
| } catch (IllegalArgumentException e) { | ||
| model.put("errorMessage", e.getMessage()); | ||
| outputView.print(model); | ||
|
|
||
| doProcess(model); | ||
| } | ||
| } | ||
|
|
||
| abstract void doProcess(Map<String, Object> model); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public interface Controller { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Controller를 interface로 선언하신게 신선하네요! |
||
| void process(Map<String, Object> model); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.outputview.OutputView; | ||
| import pairmatching.repository.PairMatchingRepository; | ||
| import pairmatching.vo.PairMatchingInfo; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class FindPairController extends AbstractController { | ||
| private final OutputView outputView; | ||
| private final PairMatchingRepository pairMatchingRepository; | ||
|
|
||
| public FindPairController(OutputView outputView, PairMatchingRepository pairMatchingRepository) { | ||
| this.outputView = outputView; | ||
| this.pairMatchingRepository = pairMatchingRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| PairMatchingInfo pairMatchingInfo = (PairMatchingInfo) model.get("pairMatchingInfo"); | ||
| model.put("matchedPairNames", pairMatchingRepository.findAllNamesByPairMatchingInfo(pairMatchingInfo)); | ||
| outputView.print(model); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Randoms; | ||
| import pairmatching.model.Crew; | ||
| import pairmatching.model.Pair; | ||
| import pairmatching.outputview.OutputView; | ||
| import pairmatching.repository.CrewRepository; | ||
| import pairmatching.repository.PairMatchingRepository; | ||
| import pairmatching.system.util.PairsMaker; | ||
| import pairmatching.vo.PairMatchingInfo; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class MatchingPairController extends AbstractController { | ||
| public static final String CREW_MATCHING_FAILED_THREE_TIMES_MESSAGE = "크루 매칭이 3회 이상 실패하였습니다."; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 상수는
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 테스트코드를에서 적절한 에러 메시지가 출력되는 지 검증하는 코드를 작성할 때 저 상수들을 사용합니다! |
||
| private final CrewRepository crewRepository; | ||
| private final PairMatchingRepository pairMatchingRepository; | ||
| private final PairsMaker pairsMaker; | ||
| private final OutputView outputView; | ||
|
|
||
| public MatchingPairController(CrewRepository crewRepository, PairMatchingRepository pairMatchingRepository, PairsMaker pairsMaker, OutputView outputView) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분 컨벤션의 열제한(120)과 파라미터 갯수 제한을 초과한거 같아요! |
||
| this.crewRepository = crewRepository; | ||
| this.pairMatchingRepository = pairMatchingRepository; | ||
| this.pairsMaker = pairsMaker; | ||
| this.outputView = outputView; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| PairMatchingInfo pairMatchingInfo = (PairMatchingInfo) model.get("pairMatchingInfo"); | ||
| List<Crew> crews = crewRepository.findByCourse(pairMatchingInfo.getCourse()); | ||
| List<Pair> pairs; | ||
|
|
||
| pairs = makePairs(pairMatchingInfo, crews); | ||
| pairMatchingRepository.save(pairMatchingInfo, pairs); | ||
|
|
||
| model.put("matchedPairNames", pairMatchingRepository.findAllNamesByPairMatchingInfo(pairMatchingInfo)); | ||
| outputView.print(model); | ||
| } | ||
|
|
||
| private List<Pair> makePairs(PairMatchingInfo pairMatchingInfo, List<Crew> crews) { | ||
| List<Pair> pairs; | ||
| int notMatchedCount = 0; | ||
| do { | ||
| pairs = pairsMaker.makePairs(getShuffledCrewNames(crews)); | ||
| notMatchedCount++; | ||
| if (notMatchedCount == 3) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 숫자 3은 상수로 변경해주어도 좋을거 같아요! |
||
| throw new IllegalStateException(CREW_MATCHING_FAILED_THREE_TIMES_MESSAGE); | ||
| } | ||
| } while (pairMatchingRepository.hasDuplicatingAtSameLevel(pairMatchingInfo, pairs)); | ||
| return pairs; | ||
| } | ||
|
|
||
| private List<String> getShuffledCrewNames(List<Crew> crews) { | ||
| List<String> crewNames = crews.stream() | ||
| .map(Crew::getName) | ||
| .collect(Collectors.toList()); | ||
| return Randoms.shuffle(crewNames); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.model.Course; | ||
| import pairmatching.model.Crew; | ||
| import pairmatching.repository.CrewRepository; | ||
| import pairmatching.system.convertion.NamesToCrewConverter; | ||
|
|
||
| import java.io.BufferedReader; | ||
| import java.io.File; | ||
| import java.io.FileReader; | ||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| public class ReadingCrewsFileController extends AbstractController { | ||
|
|
||
| public static final String BACKEND_CREWS_FILE_DIRECTORY = "src/main/resources/backend-crew.md"; | ||
| public static final String FRONTEND_CREWS_FILE_DIRECTORY = "src/main/resources/frontend-crew.md"; | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 상대경로/절대경로와 파일 입출력에 대해서 이번에 첨 접했는데 |
||
| private final CrewRepository crewRepository; | ||
|
|
||
| public ReadingCrewsFileController(CrewRepository crewRepository) { | ||
| this.crewRepository = crewRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| try { | ||
| List<Crew> backEndCrews = NamesToCrewConverter.convert(readBackEndCrews(), Course.BACKEND); | ||
| crewRepository.saveAll(backEndCrews); | ||
|
|
||
| List<Crew> frontEndCrews = NamesToCrewConverter.convert(readFrontEndCrews(), Course.FRONTEND); | ||
| crewRepository.saveAll(frontEndCrews); | ||
| } catch (IOException e) { | ||
| throw new IllegalStateException("크루 파일 읽기에 문제가 발생했습니다."); | ||
| } | ||
| } | ||
|
|
||
| private static List<String> readBackEndCrews() throws IOException { | ||
| List<String> crewNames = new ArrayList<>(); | ||
| readFile(crewNames, BACKEND_CREWS_FILE_DIRECTORY); | ||
| return crewNames; | ||
| } | ||
|
|
||
| private static List<String> readFrontEndCrews() throws IOException { | ||
| List<String> crewNames = new ArrayList<>(); | ||
| readFile(crewNames, FRONTEND_CREWS_FILE_DIRECTORY); | ||
| return crewNames; | ||
| } | ||
|
|
||
| private static void readFile(List<String> crewNames, String fileDirectory) throws IOException { | ||
| File file = new File(fileDirectory); | ||
| FileReader fileReader = new FileReader(file); | ||
| BufferedReader bufferedReader = new BufferedReader(fileReader); | ||
| readLine(crewNames, bufferedReader); | ||
| bufferedReader.close(); | ||
|
Comment on lines
+53
to
+57
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 파일리더를 사용하는 것도 있다는 걸 배워서 감사합니다! |
||
| } | ||
|
|
||
| private static void readLine(List<String> crewNames, BufferedReader bufferedReader) throws IOException { | ||
| String line = ""; | ||
| while ((line = bufferedReader.readLine()) != null) { | ||
| crewNames.add(line); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.outputview.OutputView; | ||
| import pairmatching.repository.PairMatchingRepository; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class ResetPairController extends AbstractController { | ||
| private final PairMatchingRepository pairMatchingRepository; | ||
| private final OutputView outputView; | ||
|
|
||
| public ResetPairController(PairMatchingRepository pairMatchingRepository, OutputView outputView) { | ||
| this.pairMatchingRepository = pairMatchingRepository; | ||
| this.outputView = outputView; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| pairMatchingRepository.resetAll(); | ||
| outputView.print(model); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.model.Level; | ||
| import pairmatching.repository.MissionRepository; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| public class SavingMissionsController extends AbstractController { | ||
| private final MissionRepository missionRepository; | ||
|
|
||
| public SavingMissionsController(MissionRepository missionRepository) { | ||
| this.missionRepository = missionRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| saveMissions(getLevelOneMissionNames(), Level.LEVEL1); | ||
| saveMissions(getLevelTwoMissionNames(), Level.LEVEL2); | ||
| saveMissions(getLevelFiveMissionNames(), Level.LEVEL4); | ||
| } | ||
|
|
||
| private static List<String> getLevelFiveMissionNames() { | ||
| return Arrays.asList("성능개선", "배포"); | ||
| } | ||
|
|
||
| private static List<String> getLevelTwoMissionNames() { | ||
| return Arrays.asList("장바구니", "결제", "지하철노선도"); | ||
| } | ||
|
|
||
| private static List<String> getLevelOneMissionNames() { | ||
| return Arrays.asList("자동차경주", "로또", "숫자야구게임"); | ||
| } | ||
|
|
||
| private void saveMissions(List<String> missionNames, Level level) { | ||
| missionRepository.saveAllNamesWithLevel(missionNames, level); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.inputview.InputView; | ||
| import pairmatching.outputview.OutputView; | ||
| import pairmatching.vo.FeatureCommand; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class SelectingFeatureController extends AbstractController { | ||
| private final OutputView outputView; | ||
| private final InputView<FeatureCommand> inputView; | ||
|
|
||
| public SelectingFeatureController(OutputView outputView, InputView<FeatureCommand> inputView) { | ||
| this.outputView = outputView; | ||
| this.inputView = inputView; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| outputView.print(model); | ||
| model.put("featureCommand", inputView.getInput(model)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package pairmatching.controller; | ||
|
|
||
| import pairmatching.inputview.InputView; | ||
| import pairmatching.model.Course; | ||
| import pairmatching.model.Level; | ||
| import pairmatching.outputview.OutputView; | ||
| import pairmatching.repository.MissionRepository; | ||
| import pairmatching.vo.PairMatchingInfo; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class SelectingMissionController extends AbstractController { | ||
| private final OutputView outputView; | ||
| private final InputView<PairMatchingInfo> inputView; | ||
| private final MissionRepository missionRepository; | ||
|
|
||
| public SelectingMissionController(OutputView outputView, InputView<PairMatchingInfo> inputView, MissionRepository missionRepository) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분도 열제한(120)을 초과해서 inputView, 다음에 줄바꿈 해주셔야 할거 같아요! |
||
| this.outputView = outputView; | ||
| this.inputView = inputView; | ||
| this.missionRepository = missionRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public void doProcess(Map<String, Object> model) { | ||
| printMessage(model); | ||
| readInputIntoModel(model); | ||
| } | ||
|
|
||
| private void readInputIntoModel(Map<String, Object> model) { | ||
| putAllMissionsToModel(model); | ||
| model.put("pairMatchingInfo", inputView.getInput(model)); | ||
| } | ||
|
|
||
| private void printMessage(Map<String, Object> model) { | ||
| putCoursesNameToModel(model); | ||
| putMissionNamesToModel(model); | ||
| outputView.print(model); | ||
| } | ||
|
|
||
| private Object putAllMissionsToModel(Map<String, Object> model) { | ||
| return model.put("missions", missionRepository.findAll()); | ||
| } | ||
|
|
||
| private static Object putCoursesNameToModel(Map<String, Object> model) { | ||
| return model.put("courses", Course.getCourseNames()); | ||
| } | ||
|
|
||
| private void putMissionNamesToModel(Map<String, Object> model) { | ||
| model.put("level1Missions", missionRepository.findAllNamesByLevel(Level.LEVEL1)); | ||
| model.put("level2Missions", missionRepository.findAllNamesByLevel(Level.LEVEL2)); | ||
| model.put("level3Missions", missionRepository.findAllNamesByLevel(Level.LEVEL3)); | ||
| model.put("level4Missions", missionRepository.findAllNamesByLevel(Level.LEVEL4)); | ||
| model.put("level5Missions", missionRepository.findAllNamesByLevel(Level.LEVEL5)); | ||
| } | ||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package pairmatching.inputview; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Console; | ||
| import pairmatching.system.convertion.StringToFeatureCommandConverter; | ||
| import pairmatching.vo.FeatureCommand; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class GettingFeatureCommandInputView implements InputView<FeatureCommand> { | ||
| @Override | ||
| public FeatureCommand getInput(Map<String, Object> model) { | ||
| String input = readInput(); | ||
| return StringToFeatureCommandConverter.convert(input); | ||
| } | ||
|
|
||
| protected static String readInput() { | ||
| return Console.readLine(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5시간 동안 모든 기능을 구현하셨나보네요!
대단합니다!! 👍