Skip to content

Commit

Permalink
Merge pull request #57 from Re-4aliens/refactor/#45_matching-refactor…
Browse files Browse the repository at this point in the history
…ing-and-fix-git-conflict

Refactor/#45 매칭 도메인 리펙토링 및 로직 고도화 (git 충돌 해결)
  • Loading branch information
suhyun0918 authored Feb 15, 2024
2 parents aca32a1 + 903aa98 commit 464ff56
Show file tree
Hide file tree
Showing 55 changed files with 1,362 additions and 676 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/aliens/backend/block/domain/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ public static Block of(Member blockedMember, Member blockingMember) {
block.blockedMember = blockedMember;
return block;
}

public Long getBlockingMemberId() {
return blockingMember.getId();
}

public Long getBlockedMemberId() {
return blockedMember.getId();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.aliens.backend.block.domain.repository;

import com.aliens.backend.auth.domain.Member;
import com.aliens.backend.block.domain.Block;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface BlockRepository extends JpaRepository<Block, Long> {
List<Block> findAllByBlockingMember(Member blockingMember);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
@Component
public class MatchingRuleProperties {
@Value("${matching.rule.max-matches.partner}")
private String maxPartners;
private Integer maxPartners;

@Value("${matching.rule.max-matches.normal-partner}")
private String maxNormalPartners;
private Integer maxNormalPartners;

@Value("${matching.rule.max-tries}")
private String maxTries;
private Integer maxTries;

public Integer getMaxNormalPartners() {
return Integer.parseInt(maxNormalPartners);
return maxNormalPartners;
}

public Integer getMaxTries() {
return Integer.parseInt(maxTries);
return maxTries;
}

public Integer getMaxPartners() {
return Integer.parseInt(maxPartners);
return maxPartners;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,35 @@
@Component
public class MatchingTimeProperties {
@Value("${matching.request.time.hours}")
private String matchingRequestAvailableTime;
private Long requestAvailableTime;

@Value("${matching.valid.time.hours}")
private String matchingValidBeginHours;
private Integer validBeginHours;

@Value("${matching.valid.day-of-week.if.monday.hours}")
private String mondayMatchingValidHours;
private Long mondayMatchingValidHours;

@Value("${matching.valid.day-of-week.if.thursday.hours}")
private String thursdayMatchingValidHours;
private Long thursdayMatchingValidHours;

@Value("${matching.valid.day-of-week.if.default.hours}")
private String defaultMatchingValidHours;
private Long defaultMatchingValidHours;

public Long getMatchingRequestAvailableTime() {
return Long.parseLong(matchingRequestAvailableTime);
public Long getRequestAvailableTime() {
return requestAvailableTime;
}

public Integer getMatchingValidBeginHours() {
return Integer.parseInt(matchingValidBeginHours);
public Integer getValidBeginHours() {
return validBeginHours;
}

public Long getMatchingValidHours(final DayOfWeek dayOfWeek) {
if (dayOfWeek.equals(DayOfWeek.MONDAY)) {
return Long.parseLong(mondayMatchingValidHours);
return mondayMatchingValidHours;
}
if (dayOfWeek.equals(DayOfWeek.THURSDAY)) {
return Long.parseLong(thursdayMatchingValidHours);
return thursdayMatchingValidHours;
}
return Long.parseLong(defaultMatchingValidHours);
return defaultMatchingValidHours;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.aliens.backend.global.validator;

import com.aliens.backend.mathcing.util.validator.LanguageValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

@Target({ PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {LanguageValidator.class})
@Documented
public @interface LanguageCheck {
String message() default "Invalid Language Input";

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };
}
116 changes: 14 additions & 102 deletions src/main/java/com/aliens/backend/mathcing/business/MatchingBusiness.java
Original file line number Diff line number Diff line change
@@ -1,125 +1,37 @@
package com.aliens.backend.mathcing.business;

import com.aliens.backend.global.property.MatchingRuleProperties;
import com.aliens.backend.mathcing.domain.MatchingApplication;
import com.aliens.backend.mathcing.service.model.Language;
import com.aliens.backend.mathcing.service.model.Participant;
import com.aliens.backend.mathcing.service.model.MatchingMode;
import com.aliens.backend.mathcing.service.model.Relationship;
import com.aliens.backend.mathcing.business.model.*;
import com.aliens.backend.mathcing.controller.dto.request.MatchingOperateRequest;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class MatchingBusiness {
private final MatchingRuleProperties matchingRuleProperties;

private List<Participant> participants = new ArrayList<>();
private Map<Language, Queue<Participant>> languageQueueWithParticipants = new HashMap<>();
private Relationship relationship;
private MatchingTypeGroup matchingTypeGroup;
private ParticipantGroup participantGroup;
private LanguageQueue languageQueue;

public MatchingBusiness(final MatchingRuleProperties matchingRuleProperties) {
this.matchingRuleProperties = matchingRuleProperties;
}

private void initialize(final List<MatchingApplication> matchingApplications) {
participants = MatchingApplication.toParticipantList(matchingApplications);
languageQueueWithParticipants = Language.createQueueWith(participants);
relationship = Relationship.NORMAL;
}

public List<Participant> operateMatching(final List<MatchingApplication> matchingApplications) {
initialize(matchingApplications);

matchParticipantsWith(MatchingMode.FIRST_PREFER_LANGUAGE);
matchParticipantsWith(MatchingMode.SECOND_PREFER_LANGUAGE);
matchParticipantsWith(MatchingMode.RANDOM);
matchParticipantsWith(MatchingMode.SPECIAL);

return participants;
}

private void matchParticipantsWith(final MatchingMode matchingMode) {
List<Participant> participants = null;
if (matchingMode.equals(MatchingMode.FIRST_PREFER_LANGUAGE)) {
participants = this.participants;
}
if (matchingMode.equals(MatchingMode.SECOND_PREFER_LANGUAGE)) {
participants = getParticipantsLessThan(matchingRuleProperties.getMaxNormalPartners());
languageQueueWithParticipants = Language.createQueueWith(this.participants);
}
if (matchingMode.equals(MatchingMode.RANDOM)) {
relationship = Relationship.SPECIAL;
participants = getParticipantsLessThan(matchingRuleProperties.getMaxNormalPartners());
}
if (matchingMode.equals(MatchingMode.SPECIAL)) {
participants = getParticipantsLessThan(matchingRuleProperties.getMaxPartners());
}
matchWith(matchingMode, participants);
}

private void matchWith(final MatchingMode matchingMode, final List<Participant> participants) {
Queue<Participant> candidates = null;
if (matchingMode.equals(MatchingMode.RANDOM)) {
candidates = new LinkedList<>(getParticipantsLessThan(matchingRuleProperties.getMaxPartners()));
}
if (matchingMode.equals(MatchingMode.SPECIAL)) {
candidates = new LinkedList<>(participants);
}
for (Participant participant : participants) {
if (matchingMode.equals(MatchingMode.FIRST_PREFER_LANGUAGE) ||
matchingMode.equals(MatchingMode.SECOND_PREFER_LANGUAGE)) {
candidates = languageQueueWithParticipants.get(participant.getPreferLanguage(matchingMode));
}
tryMatchBetween(participant, candidates);
}
}

private void tryMatchBetween(final Participant participant, final Queue<Participant> candidates) {
int tries = 0;
while (!isExceededMaxPartners(relationship, participant) && !isExceedMaxTries(tries) && !candidates.isEmpty()) {
Participant partner = candidates.poll();
tries++;
if (isValidMatching(relationship, participant, partner)) {
addMatching(participant, partner);
if (!isExceededMaxPartners(relationship, partner)) {
candidates.add(partner);
}
} else {
candidates.add(partner);
}
}
}

private void addMatching(final Participant participant, final Participant partner) {
participant.addPartner(relationship, partner.memberId());
partner.addPartner(relationship, participant.memberId());
}

private List<Participant> getParticipantsLessThan(int numberOfPartner) {
return participants.stream()
.filter(participant -> participant.getNumberOfPartners() < numberOfPartner)
.collect(Collectors.toList());
}
public void operateMatching(final MatchingOperateRequest matchingOperateRequest) {
initialize(matchingOperateRequest);

private boolean isValidMatching(final Relationship relationship,
final Participant participant,
final Participant partner) {
return participant != partner &&
!participant.isPartnerWith(partner) &&
!partner.isPartnerWith(participant) &&
!isExceededMaxPartners(relationship, partner);
matchingTypeGroup.matchParticipants(participantGroup, languageQueue);
}

private boolean isExceededMaxPartners(final Relationship relationship, final Participant participant) {
if (relationship.equals(Relationship.NORMAL)) {
return participant.getNumberOfPartners() >= matchingRuleProperties.getMaxNormalPartners(); // 4
}
return participant.getNumberOfPartners() >= matchingRuleProperties.getMaxPartners(); // 5
public List<Participant> getMatchedParticipants() {
return participantGroup.getParticipants();
}

private boolean isExceedMaxTries(int tries) {
return tries > matchingRuleProperties.getMaxTries();
private void initialize(final MatchingOperateRequest matchingOperateRequest) {
participantGroup = ParticipantGroup.from(matchingOperateRequest, matchingRuleProperties); // TODO : 이전 매칭 기록, 차단 목록 주고 만들도록 시킴
languageQueue = LanguageQueue.classifyByLanguage(participantGroup);
matchingTypeGroup = MatchingTypeGroup.init(matchingRuleProperties);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.aliens.backend.mathcing.business.model;

import com.aliens.backend.block.domain.Block;
import com.aliens.backend.mathcing.domain.MatchingApplication;

import java.util.List;

public class BlockHistoryGroup {
private final List<Block> blockHistories;

private BlockHistoryGroup(final List<Block> blockHistories) {
this.blockHistories = blockHistories;
}

public static BlockHistoryGroup of(final List<Block> blockHistories) {
return new BlockHistoryGroup(blockHistories);
}

public List<Block> getBlockHistoriesWith(MatchingApplication matchingApplication) {
List<Block> filteredBlockHistories = blockHistories.stream()
.filter(blockHistory -> blockHistory.getBlockingMemberId().equals(matchingApplication.getMemberId()))
.toList();
return filteredBlockHistories;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.aliens.backend.mathcing.business.model;

import com.aliens.backend.block.domain.Block;

import java.util.List;

public class BlockedPartnerGroup {
private final List<Long> blockedPartners;

public BlockedPartnerGroup(final List<Long> blockedPartners) {
this.blockedPartners = blockedPartners;
}

public static BlockedPartnerGroup from(final List<Block> blockHistories) {
List<Long> blockedPartners = blockHistories.stream()
.mapToLong(Block::getBlockedMemberId).boxed().toList();
return new BlockedPartnerGroup(blockedPartners);
}

public boolean contains(Participant participant) {
return blockedPartners.contains(participant.memberId());
}

@Override
public String toString() {
return "BlockedPartnerGroup{" +
"blockedPartners=" + blockedPartners +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.aliens.backend.mathcing.business.model;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class CandidateGroup {
private final Queue<Participant> candidateQueue;

private CandidateGroup(final Queue<Participant> candidateQueue) {
this.candidateQueue = candidateQueue;
}

public static CandidateGroup initWithEmpty() {
return new CandidateGroup(new LinkedList<>());
}

public static CandidateGroup of(ParticipantGroup participantGroup) {
return new CandidateGroup(new LinkedList<>(participantGroup.getParticipants()));
}

public void add(Participant participant) {
candidateQueue.add(participant);
}

public void addAll(List<Participant> participants) {
candidateQueue.addAll(participants);
}

public Participant poll() {
return candidateQueue.poll();
}

public boolean isEmpty() {
return candidateQueue.isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.aliens.backend.mathcing.business.model;

public enum Language {
KOREAN,
ENGLISH,
JAPANESE,
CHINESE
;
}
Loading

0 comments on commit 464ff56

Please sign in to comment.