-
Notifications
You must be signed in to change notification settings - Fork 8
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
[BE] feat: 리뷰어/리뷰이 매칭 기능 구현 (#38) #70
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7695e13
refactor: 도메인 수정
hjk0761 1ba0076
Merge branch 'develop' of https://github.com/hjk0761/2024-corea into …
hjk0761 1e1d95e
feat: 기본 랜덤 매칭 기능 구현
hjk0761 d5d2578
feat: 매칭 서비스 구현
hjk0761 8578595
refactor: 리뷰 사항 반영
hjk0761 09b9c58
Merge branch 'develop' into feat/#38
hjk0761 9c6da58
Merge branch 'develop' of https://github.com/hjk0761/2024-corea into …
hjk0761 86912c1
refactor: 리뷰 사항 반영
hjk0761 a9ec0b5
Merge branch 'feat/#38' of https://github.com/hjk0761/2024-corea into…
hjk0761 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
backend/src/main/java/corea/matching/domain/MatchingStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package corea.matching.domain; | ||
|
||
import java.util.List; | ||
|
||
public interface MatchingStrategy { | ||
|
||
List<Pair> matchPairs(List<Long> memberIds, int matchingSize); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package corea.matching.domain; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
@Getter | ||
public class Pair { | ||
|
||
private final Long fromMemberId; | ||
private final Long toMemberId; | ||
} |
29 changes: 29 additions & 0 deletions
29
backend/src/main/java/corea/matching/domain/PlainRandomMatching.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package corea.matching.domain; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
@Component | ||
public class PlainRandomMatching implements MatchingStrategy { | ||
|
||
@Override | ||
public List<Pair> matchPairs(List<Long> memberIds, int matchingSize) { | ||
List<Long> shuffledMemberIds = new ArrayList<>(memberIds); | ||
Collections.shuffle(shuffledMemberIds); | ||
|
||
return match(shuffledMemberIds, matchingSize); | ||
} | ||
|
||
private List<Pair> match(List<Long> shuffledMemberIds, int matchingSize) { | ||
List<Pair> reviewerResult = new ArrayList<>(); | ||
for (int i = 0; i < shuffledMemberIds.size(); i++) { | ||
for (int j = 1; j <= matchingSize; j++) { | ||
reviewerResult.add(new Pair(shuffledMemberIds.get(i), shuffledMemberIds.get((i + j) % shuffledMemberIds.size()))); | ||
} | ||
} | ||
return reviewerResult; | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
backend/src/main/java/corea/matching/domain/ReviewStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package corea.matching.domain; | ||
|
||
public enum ReviewStatus { | ||
|
||
COMPLETE, INCOMPLETE | ||
} |
7 changes: 7 additions & 0 deletions
7
backend/src/main/java/corea/matching/repository/MatchResultRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package corea.matching.repository; | ||
|
||
import corea.matching.domain.MatchResult; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface MatchResultRepository extends JpaRepository<MatchResult, Long> { | ||
} |
31 changes: 0 additions & 31 deletions
31
backend/src/main/java/corea/matching/service/Matching.java
This file was deleted.
Oops, something went wrong.
62 changes: 41 additions & 21 deletions
62
backend/src/main/java/corea/member/service/MatchingService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,55 @@ | ||
package corea.member.service; | ||
|
||
import corea.exception.CoreaException; | ||
import corea.exception.ExceptionType; | ||
import corea.matching.domain.MatchResult; | ||
import corea.matching.domain.Pair; | ||
import corea.matching.domain.Participation; | ||
import corea.matching.service.Matching; | ||
import corea.member.entity.MatchedGroup; | ||
import corea.matching.repository.MatchedGroupRepository; | ||
import lombok.AllArgsConstructor; | ||
import corea.matching.domain.PlainRandomMatching; | ||
import corea.matching.repository.MatchResultRepository; | ||
import corea.member.repository.MemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
@Service | ||
@AllArgsConstructor | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class MatchingService { | ||
|
||
private final MatchedGroupRepository matchedGroupRepository; | ||
private final Matching matching; | ||
private final PlainRandomMatching plainRandomMatching; | ||
private final MatchResultRepository matchResultRepository; | ||
private final MemberRepository memberRepository; | ||
|
||
public void matchMaking(final List<Participation> participations, final int matchingSize) { | ||
final ArrayList<Long> memberIds = new ArrayList<>(participations.stream() | ||
public void matchMaking(List<Participation> participations, int matchingSize) { | ||
validateParticipationSize(participations, matchingSize); | ||
List<Long> memberIds = participations.stream() | ||
.map(Participation::getMemberId) | ||
.toList() | ||
); | ||
|
||
final Map<Long, List<Long>> results = matching.matchGroup(memberIds, matchingSize); | ||
results.entrySet() | ||
.stream() | ||
.flatMap(entry -> entry.getValue() | ||
.stream() | ||
.map(memberId -> new MatchedGroup(entry.getKey(), memberId))) | ||
.forEach(matchedGroupRepository::save); | ||
.toList(); | ||
|
||
long roomId = participations.get(0).getRoomId(); | ||
|
||
List<Pair> results = plainRandomMatching.matchPairs(memberIds, matchingSize); | ||
|
||
results.stream() | ||
.map(pair -> new MatchResult( | ||
roomId, | ||
memberRepository.findById(pair.getFromMemberId()).orElseThrow( | ||
() -> new CoreaException(ExceptionType.MEMBER_NOT_FOUND, String.format("%d에 해당하는 멤버가 없습니다.", pair.getFromMemberId())) | ||
), | ||
memberRepository.findById(pair.getToMemberId()).orElseThrow( | ||
() -> new CoreaException(ExceptionType.MEMBER_NOT_FOUND, String.format("%d에 해당하는 멤버가 없습니다.", pair.getToMemberId())) | ||
), | ||
null)) | ||
//TODO: prLink 차후 수정 | ||
.forEach(matchResultRepository::save); | ||
} | ||
|
||
private void validateParticipationSize(List<Participation> participations, int matchingSize) { | ||
if (participations.size() <= matchingSize) { | ||
throw new CoreaException(ExceptionType.PARTICIPANT_SIZE_LACK); | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
backend/src/test/java/corea/fixture/ParticipationFixture.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package corea.fixture; | ||
|
||
import corea.matching.domain.Participation; | ||
|
||
import java.util.List; | ||
|
||
public class ParticipationFixture { | ||
|
||
public static List<Participation> PARTICIPATIONS_EIGHT() { | ||
return List.of( | ||
new Participation(1L, 1L), | ||
new Participation(1L, 2L), | ||
new Participation(1L, 3L), | ||
new Participation(1L, 4L), | ||
new Participation(1L, 5L), | ||
new Participation(1L, 6L), | ||
new Participation(1L, 7L), | ||
new Participation(1L, 8L) | ||
); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
backend/src/test/java/corea/matching/domain/PlainRandomMatchingTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package corea.matching.domain; | ||
|
||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class PlainRandomMatchingTest { | ||
|
||
private final PlainRandomMatching plainRandomMatching = new PlainRandomMatching(); | ||
|
||
@Test | ||
@DisplayName("아이디의 리스트가 들어오면 매칭 사이즈 만큼 매칭된 결과를 반환한다.") | ||
void matchPairs_1() { | ||
List<Long> memberIds = List.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L); | ||
int matchingSize = 3; | ||
|
||
List<Pair> result = plainRandomMatching.matchPairs(memberIds, matchingSize); | ||
|
||
assertThat(result).hasSize(matchingSize * memberIds.size()); | ||
} | ||
|
||
@Test | ||
@DisplayName("매칭을 수행할 때에, 본인을 제외한 멤버 중에서 매칭이 된다.") | ||
void matchPairs_2() { | ||
List<Long> memberIds = List.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L); | ||
int matchingSize = 3; | ||
|
||
List<Pair> result = plainRandomMatching.matchPairs(memberIds, matchingSize); | ||
|
||
for (Pair pair : result) { | ||
assertThat(pair.getFromMemberId()).isNotEqualTo(pair.getToMemberId()); | ||
} | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
backend/src/test/java/corea/member/service/MatchingServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package corea.member.service; | ||
|
||
import config.ServiceTest; | ||
import corea.exception.CoreaException; | ||
import corea.fixture.MemberFixture; | ||
import corea.fixture.ParticipationFixture; | ||
import corea.matching.domain.Participation; | ||
import corea.member.repository.MemberRepository; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThatCode; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
@ServiceTest | ||
class MatchingServiceTest { | ||
|
||
@Autowired | ||
private MatchingService matchingService; | ||
|
||
@Autowired | ||
private MemberRepository memberRepository; | ||
|
||
@Test | ||
@DisplayName("인원 수가 매칭 사이즈보다 큰 경우 매칭을 수행한다.") | ||
void matchMaking() { | ||
List<Participation> participations = new ArrayList<>(); | ||
int matchingSize = 3; | ||
|
||
for (int i = 0; i < 4; i++) { | ||
participations.add(new Participation(1L, memberRepository.save(MemberFixture.MEMBER_DOMAIN()).getId())); | ||
participations.add(new Participation(1L, memberRepository.save(MemberFixture.MEMBER_MANAGER()).getId())); | ||
} | ||
|
||
assertThatCode(() -> matchingService.matchMaking(participations, matchingSize)) | ||
.doesNotThrowAnyException(); | ||
} | ||
|
||
@Test | ||
@DisplayName("매칭을 수행할 때에, 인원 수가 매칭 사이즈보다 작거나 같으면 예외를 발생한다.") | ||
void matchMakingLackOfParticipationException() { | ||
List<Participation> participations = ParticipationFixture.PARTICIPATIONS_EIGHT(); | ||
int matchingSize = 9; | ||
|
||
assertThatThrownBy(() -> matchingService.matchMaking(participations, matchingSize)) | ||
.isInstanceOf(CoreaException.class) | ||
.hasMessage("참여 인원 수가 부족합니다."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
DELETE FROM MATCH_RESULT; | ||
DELETE FROM MEMBER; | ||
DELETE FROM ROOM; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
일단은 예외 던지고, 나중에는 바꿔나가면 괜찮을듯 🙂