Skip to content

Commit

Permalink
feat: 매칭 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
hjk0761 committed Jul 15, 2024
1 parent 176463e commit 3fcc807
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 0 deletions.
1 change: 1 addition & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {

// Etc
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

// Database
runtimeOnly 'com.h2database:h2'
Expand Down
33 changes: 33 additions & 0 deletions backend/src/main/java/corea/member/domain/Matching.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package corea.member.domain;

import corea.domain.Member;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.IntStream;

import static lombok.AccessLevel.PROTECTED;

@NoArgsConstructor(access = PROTECTED)
@Component
public class Matching {

public Map<Long, List<Long>> matchGroup(final List<Member> members, final int matchingSize) {
final Map<Long, List<Long>> matchedGroup = new HashMap<>();

final List<Long> memberIds = new ArrayList<>(members.stream().map(Member::getId).toList());
Collections.shuffle(memberIds);

final List<List<Long>> groupedMemberIds = IntStream.range(0, (members.size() + matchingSize - 1) / matchingSize)
.mapToObj(i -> memberIds.subList(i * matchingSize, Math.min(i * matchingSize + matchingSize, memberIds.size())))
.toList();

long groupId = 1L;
for (List<Long> l : groupedMemberIds) {
matchedGroup.put(groupId++, l);
}

return matchedGroup;
}
}
28 changes: 28 additions & 0 deletions backend/src/main/java/corea/member/entity/MatchedGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package corea.member.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Entity
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public class MatchedGroup {

@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;

private Long groupId;

private Long memberId;

public MatchedGroup(final Long groupId, final Long memberId) {
this(null, groupId, memberId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package corea.member.repository;

import corea.member.entity.MatchedGroup;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface MatchedGroupRepository extends JpaRepository<MatchedGroup, Long> {

Long findGroupIdByMemberId(final Long memberId);

List<Long> findMemberIdsByGroupId(final Long groupId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package corea.member.repository;

import corea.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {
}
27 changes: 27 additions & 0 deletions backend/src/main/java/corea/member/service/MatchingService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package corea.member.service;

import corea.member.domain.Matching;
import corea.member.entity.MatchedGroup;
import corea.domain.Member;
import corea.member.repository.MatchedGroupRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class MatchingService {

private final MatchedGroupRepository matchedGroupRepository;
private final Matching matching;

public void matchMaking(final List<Member> members, final int matchingSize) {
final Map<Long, List<Long>> results = matching.matchGroup(members, matchingSize);
results.entrySet().stream()
.flatMap(entry -> entry.getValue().stream()
.map(memberId -> new MatchedGroup(entry.getKey(), memberId)))
.forEach(matchedGroupRepository::save);
}
}
33 changes: 33 additions & 0 deletions backend/src/test/java/corea/member/domain/MatchingTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package corea.member.domain;

import corea.domain.Member;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

class MatchingTest {

private final Matching matching = new Matching();

@Test
@DisplayName("멤버 리스트를 받아서 매칭 결과를 반환한다.")
void matchGroup(){
List<Member> members = List.of(
new Member(1L, "[email protected]"),
new Member(2L, "[email protected]"),
new Member(3L, "[email protected]"),
new Member(4L, "[email protected]")
);
int matchingSize = 2;

Map<Long, List<Long>> results = matching.matchGroup(members, matchingSize);

assertThat(results).hasSize(2);
assertThat(results.get(1L)).hasSize(2);
assertThat(results.get(2L)).hasSize(2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package corea.member.service;

import corea.domain.Member;
import corea.member.repository.MatchedGroupRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
class MatchingServiceTest {

private final MatchingService matchingService;
private final MatchedGroupRepository matchedGroupRepository;

@Autowired
public MatchingServiceTest(MatchingService matchingService, MatchedGroupRepository matchedGroupRepository) {
this.matchingService = matchingService;
this.matchedGroupRepository = matchedGroupRepository;
}

@Test
@DisplayName("멤버 리스트를 받아 매칭 결과를 반환한다.")
void matchMaking() {
List<Member> members = List.of(
new Member(1L, "[email protected]"),
new Member(2L, "[email protected]"),
new Member(3L, "[email protected]"),
new Member(4L, "[email protected]")
);
int matchingSize = 2;

matchingService.matchMaking(members, matchingSize);

assertThat(matchedGroupRepository.findAll()).hasSize(4);
}

}

0 comments on commit 3fcc807

Please sign in to comment.