Skip to content
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] 최소 시간을 보장하는 추천 로직 추가 #404

Merged
merged 9 commits into from
Nov 6, 2024

Conversation

ikjo39
Copy link
Contributor

@ikjo39 ikjo39 commented Oct 13, 2024

관련 이슈

작업 내용

최소 시간을 보장하는 로직을 추가하였습니다.

최소 시간 기준

최소 시간의 경우 30분, 60분, 120분과 같이 현재 시간 로직과 동일하게 30분 단위로 기준을 잡았습니다.

최소 시간 보장 로직

최소 시간 보장하는 로직을 어디에 둘지 고민했는데요. 제가 생각한 최소 요구사항은 아래와 같았습니다.

  • sort 기준을 Duration 크기의 역순으로 걸고 최소 시간보다 작은 것은 필터링한다.
  • 출력할 땐 참가자가 많은 순서대로 정렬 후 시간이 빠른 순(Earliest)으로 정렬한다.

적절한 위치를 고민하다 CandidateSchedule내에 mergeContinuous 안에 위치시켰습니다.
반복문을 필연적으로 돌아야 하는 곳에서 분기 처리 하는게 효율적이라 생각하였어요 :)

특이 사항

추천 로직 API 에 대해 요구사항이 변경되었습니다!
다만, 기존 로직과 충돌을 방지하기 위해 새로 추가된 @RequestParamminTime에 기본 값을 설정해두었습니다.

리뷰 요구사항

전체적으로 로직에서 불합리한 부분이 없는지와 테스트가 부족한 부분이 없는지 확인 부탁 드려요~

@ikjo39 ikjo39 added 🐈‍⬛ 백엔드 백엔드 관련 이슈에요 :) 🚀 기능 기능을 개발해요 :) labels Oct 13, 2024
@ikjo39 ikjo39 added this to the 6차(최종) 데모데이 milestone Oct 13, 2024
@ikjo39 ikjo39 self-assigned this Oct 13, 2024
Copy link

github-actions bot commented Oct 13, 2024

Test Results

165 tests  +130   165 ✅ +130   22s ⏱️ -3s
 32 suites + 28     0 💤 ±  0 
 32 files   + 31     0 ❌ ±  0 

Results for commit c848d79. ± Comparison against base commit 23c88c0.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@seokmyungham seokmyungham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다온 고생하셨습니다 😁
받으면 기분이 좋아지는 RC를 드립니다 🚀

Comment on lines 47 to 49
if (minSize < MINIMUM_MIN_SIZE) {
throw new MomoException(ScheduleErrorCode.INVALID_MIN_TIME);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서비스에서 이 검증을 수행한 다음에 추천 로직을 수행하는게 자연스러울 것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠 그러면 controller의 parameter 단에서 validation 라이브러리를 통해 검증하는건 어떨까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비즈니스 정책에 해당한다고 생각해서 비즈니스 로직이 수행되는 위치에서 수행되어야 할 것 같아요.

Comment on lines 50 to 55
if (minSize > subList.size()) {
return;
}
subList.stream()
.reduce(CandidateSchedule::merge)
.ifPresent(mergedSchedules::add);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (minSize > subList.size()) {
return;
}
subList.stream()
.reduce(CandidateSchedule::merge)
.ifPresent(mergedSchedules::add);
if (subList.size() >= minSize) {
subList.stream()
.reduce(CandidateSchedule::merge)
.ifPresent(mergedSchedules::add);
}

이건 어떤가요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early Return을 하는 것과 가독성을 고민하였는데요.
아래가 더 가독성이 좋아보이네요 :)

Comment on lines +141 to +142
recommendedResult
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다온이 만든 코드는 아니지만 😅
지금 dto 변환 작업을 두 번에 나눠서 하고 있는데 한 번에 하면 더 좋을 것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 작업은 리팩토링 이슈로 분리하여 다뤄봐도 좋을 것 같네요

@@ -98,9 +98,11 @@ MomoApiResponse<AttendeeScheduleResponse> findMySchedule(
@ApiSuccessResponse.Ok("추천 일정 조회 성공")
MomoApiResponse<RecommendedSchedulesResponse> recommendSchedules(
@PathVariable @Schema(description = "약속 UUID") String uuid,
@RequestParam @Schema(description = "추천 기준(이른 시간 순 / 길게 볼 수 있는 순)", example = "earliest")
@RequestParam @Schema(description = "추천 기준(이른 시간 순 / 길게 볼 수 있는 순 / 최소 시간 보장 순)", example = "earliest")
Copy link
Contributor

@seokmyungham seokmyungham Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최소 시간 보장은 추천 기준을 선택한 후 추가로 결정할 수 있는 하나의 옵션이라고 보는게 맞는 것 같아요.
함께 논의해봅시다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 동의합니다. 정렬과 옵션을 구분하는 것이 좋을 것 같습니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함께 결정하고 싶었던 사안이라 우선 구현이 잘 보이는 분리된 추천으로 시작하였는데요.
스크럼에서 얘기 나눈대로 이 부분은 최소 시간 보장의 옵션으로 수정하도록 할게요!

Copy link
Member

@hw0603 hw0603 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 다온!
정책 관련된 부분은 다른 팀원들이랑 전체 논의가 한 번 필요해 보이네요🤔

@@ -9,7 +9,9 @@
public enum RecommendedScheduleSortStandard {

EARLIEST_ORDER("earliest", new EarliestFirstSorter()),
LONG_TERM_ORDER("longTerm", new LongTermFirstSorter());
LONG_TERM_ORDER("longTerm", new LongTermFirstSorter()),
MIN_TIME_EARLIER_ORDER("minTime", new EarliestFirstSorter())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최소 시간 보장 기능이 정렬의 기준이 된다기보다는 별도의 옵션으로 존재해야 하지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스크럼에서 얘기 나눴듯이 옵션으로 통일하겠습니다!

@PathVariable String uuid,
@RequestParam String recommendType,
@RequestParam List<String> attendeeNames,
@RequestParam(value = "minTime", defaultValue = "0") int minTime
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기본값 설정👍

List<String> attendeeNames
List<String> attendeeNames,
@RequestParam @Schema(description = "최소 만남 시간(30분 단위의 분)", example = "0, 30, 60, 90")
int minTime
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최소 만남 시간이 30분단위여야 할까요? 뭔가 사용자 입장에서는 한시간 단위로 두고 정수 1, 2 3 이렇게 전달하는게 편할 것 같아서요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 정책적인 사인이라 스크럼으로 얘기 나눴었죠.
시간 단위로 나누는 것으로 결론내었으니 반영해보도록 할게요!

idx += subList.size();
}
return mergedSchedules;
}

private static void addWhenLongerOrEqualThanMinTime(
List<CandidateSchedule> subList, List<CandidateSchedule> mergedSchedules, int minSize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
List<CandidateSchedule> subList, List<CandidateSchedule> mergedSchedules, int minSize
private static void addIfLongerThanOrEqualToMinTime(

일반적으로 사용되는 메서드 명명법을 따라 볼까요? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 이 부분은 흥미롭네요.
일반적으로 사용되는 메서드 명명법을 참고할 만한 곳이 있으면 공유 요청 드려도 될까요?
추후 메서드 명명에 도움이 될 것 같습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음.. 별도로 레퍼런스가 있다기보다는 보통 영문에서 lt, lte, gt, gte 와 같은 표기를 많이 사용해서 그게 자연스럽다고 느꼈던 것 같아요.

자바 계열에서는 JUnit의 검증 메서드 명명법을 참고하기는 합니다. 저 메서드 보자마자 JUnit의 greaterThanOrEqualTo() 가 떠올랐어요ㅋㅋㅋ

if (minSize < MINIMUM_MIN_SIZE) {
throw new MomoException(ScheduleErrorCode.INVALID_MIN_TIME);
}
if (minSize > subList.size()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minSize 검증의 책임은 SeheduleService에게 있지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동의합니다!
재즈 리뷰에도 질문 남겼지만 그러면 controller의 parameter 단에서 validation 라이브러리를 통해 검증하는건 어떨까요?

Copy link
Contributor

@ehBeak ehBeak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다온 구현하시느라 고생 많으셨습니다~

간단한 코멘트 남겨요 :)
추가로, minSize에 대한 네이밍을 조금 더 구체적으로 바꾼다면, 가독성이 더 좋아질 것 같아요~~!~!

@@ -98,9 +98,11 @@ MomoApiResponse<AttendeeScheduleResponse> findMySchedule(
@ApiSuccessResponse.Ok("추천 일정 조회 성공")
MomoApiResponse<RecommendedSchedulesResponse> recommendSchedules(
@PathVariable @Schema(description = "약속 UUID") String uuid,
@RequestParam @Schema(description = "추천 기준(이른 시간 순 / 길게 볼 수 있는 순)", example = "earliest")
@RequestParam @Schema(description = "추천 기준(이른 시간 순 / 길게 볼 수 있는 순 / 최소 시간 보장 순)", example = "earliest")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 동의합니다. 정렬과 옵션을 구분하는 것이 좋을 것 같습니다~

@@ -9,7 +9,9 @@
public enum RecommendedScheduleSortStandard {

EARLIEST_ORDER("earliest", new EarliestFirstSorter()),
LONG_TERM_ORDER("longTerm", new LongTermFirstSorter());
LONG_TERM_ORDER("longTerm", new LongTermFirstSorter()),
MIN_TIME_EARLIER_ORDER("minTime", new EarliestFirstSorter())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 클래스는 빠른 순, 오래 만나는 순처럼 정렬하는 로직에 관련된 것 같아요.
그러나 MIN_TIME_EARLIER_ORDER은 정렬보다는 필터에 가까운 느낌입니다. 해당 상수를 따로 관리하면 어떨까요?

Copy link
Contributor Author

@ikjo39 ikjo39 Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최소 시간 보장이 '빠르게 만나요'의 옵션으로 정책이 확정되면서 MIN_TIME_EARLIER_ORDER이 필요하지 않아 삭제하였습니다!

@@ -154,7 +154,7 @@ void findMySchedule() {
void recommendSchedules() {
RestAssured.given().log().all()
.pathParam("uuid", meeting.getUuid())
.queryParams("recommendType", EARLIEST_ORDER.getType(), "attendeeNames", attendee.name())
.queryParams("recommendType", EARLIEST_ORDER.getType(), "attendeeNames", attendee.name(), "minimumTime", 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.queryParams("recommendType", EARLIEST_ORDER.getType(), "attendeeNames", attendee.name(), "minimumTime", 0)
.queryParams("recommendType", EARLIEST_ORDER.getType(), "attendeeNames", attendee.name())

이미 minimumTime의 기본값을 0으로 설정해 두었으니, 값을 설정하지 않아도 되겠네요 :)
만약 다온이 minimumTime 값을 의도하고 넣었다면, 개행만 부탁드릴게요~~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영하였습니다!

@hw0603 hw0603 changed the title [BE] 최소 시간을 보장 추천 로직 추가 [BE] 최소 시간을 보장하는 추천 로직 추가 Oct 28, 2024
Copy link
Member

@hw0603 hw0603 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Copy link
Contributor

@seunghye218 seunghye218 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍

Copy link
Contributor

@ehBeak ehBeak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생 많으셨어요~!!!!~~!!!!!!!!!!!!🚀🚀

@ikjo39 ikjo39 force-pushed the feat/398-recommend-min-duration branch from 3769f63 to c848d79 Compare November 6, 2024 06:40
@ikjo39 ikjo39 merged commit f41b097 into develop Nov 6, 2024
6 checks passed
@ikjo39 ikjo39 deleted the feat/398-recommend-min-duration branch November 6, 2024 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐈‍⬛ 백엔드 백엔드 관련 이슈에요 :) 🚀 기능 기능을 개발해요 :)
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[BE] 최소 만남 시간을 보장하는 약속을 추천하는 기능을 추가해요 :)
5 participants