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

내기 기능 구현 #589

Merged
merged 25 commits into from
Oct 1, 2024
Merged

내기 기능 구현 #589

merged 25 commits into from
Oct 1, 2024

Conversation

ay-eonii
Copy link
Contributor

PR의 목적이 무엇인가요?

안내면 진다 기능을 추가합니다.
API

  • 안내면진다 목록 조회
  • 안내면진다 생성
  • 안내면진다 상세조회
  • 안내면진다 참여
  • 안내면진다 결과 조회
  • 안내면진다 결과 강제 도출

이슈 ID는 무엇인가요?

설명

  • DB와의 연관성을 줄이기 위해 Domain 객체와 Entity 객체를 분리해서 설계했습니다.
  • N 분후 추첨을 진행하는 서비스 기획에 따라 1분당 스케줄러가 작동하도록 구현했습니다.
    • 특정 스레드가 N 분동안 대기 하는 것은 낭비가 심하다고 생각해 스케줄링을 사용하는 방식을 채택했습니다.
    • 테스트의 경우는 1ms 마다 동작합니다.

질문 혹은 공유 사항 (Optional)

  • 도메인별 예외처리의 경우 추후에 보완할 예정입니다.
  • 프론트의 우선적인 swagger 문서 조회 및 테스트를 위해 먼저 dev 서버에 배포하고자 합니다.

@ay-eonii ay-eonii added BE 백엔드 관련 이슈입니다. 🌱 기능추가 feature (새로운 기능 구현) labels Sep 29, 2024
@hoyeonyy
Copy link
Contributor

pr 제목 진짜 열받네요.

@ay-eonii ay-eonii changed the title Feature/#566 내기 기능 구현 Sep 29, 2024
@ay-eonii ay-eonii linked an issue Sep 29, 2024 that may be closed by this pull request
7 tasks
@Mingyum-Kim
Copy link
Contributor

안내면진다 목록 조회
안내면진다 생성
안내면진다 상세조회
안내면진다 참여
안내면진다 결과 조회
안내면진다 결과 강제 도출

ㅋㅋㅋㅋㅋㅋㅋㅋ
좀 무섭네요

Copy link
Contributor

@ksk0605 ksk0605 left a comment

Choose a reason for hiding this comment

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

일단 정렬기능을 같이 개발하고 난 후에 머지하는 것으로 하시죠!
3일만에 신기능 개발하느라 고생많았습니다 ㅋㅋ

Comment on lines +13 to +15
participant.getId(),
"" // TODO : profileUrl 추가
);
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 24 to 28
@Scheduled(fixedRateString = "${bet.schedule}") // 1분
public void performScheduledTask() {
List<Bet> bets = betFinder.findAllDrawableBet();

bets.forEach(Bet::draw);
Copy link
Contributor

Choose a reason for hiding this comment

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

fixedDelay는 이전 작업이 완료된 시점으로부터 주어진 시간 간격에 맞춰 작업을 실행하고
cron 표현식을 사용할 때는 항상 지정된 시간이 되면 항상 xx분 00초에 작동되는 방식이라고 합니다.

저희 도메인에는 cron 표현식이 더 적절한 듯해서 해당 부분 수정해야할 것 같아요!

Comment on lines 28 to 30
public BetFindAllResponses findAllBets(long darakbangId) {
List<Bet> bets = betFinder.findAllByDarakbangId(darakbangId);
return BetFindAllResponses.toResponse(bets);
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 71 to 74
// TODO : 예외처리 공통화
BetEntity betEntity = betRepository.findByIdAndDarakbangId(betId, darakbangId)
.orElseThrow(IllegalArgumentException::new);

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

@ksk0605 ksk0605 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

@pricelees pricelees left a comment

Choose a reason for hiding this comment

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

분량이 상당히 많네요..오우.. 고생하셨어요

private final BetFinder betFinder;
private final BetWriter betWriter;

@Scheduled(cron = "${bet.schedule}") // 1분
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 55 to 65
List<DarakbangMember> darakbangMembers = betDarakbangMemberRepository.findAllDarakbangMemberByBetId(
betEntity.getId());
List<Participant> participants = darakbangMembers.stream()
.map(darakbangMember -> new Participant(darakbangMember.getId(), darakbangMember.getNickname()))
.toList();
return Bet.builder()
.betDetails(betEntity.toBetDetails())
.moimerId(betEntity.getMoimerId())
.loserId(betEntity.getLoserDarakbangMemberId())
.participants(participants)
.build();
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

Choose a reason for hiding this comment

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

오 맞습니다! 보니까 ParticiapantFinder의 로직과 겹치는 부분도 있어서 함께 분리해봤습니다.

import mouda.backend.bet.domain.Bet;
import mouda.backend.bet.domain.BetDetails;

public record BetCreateRequest(
Copy link
Contributor

Choose a reason for hiding this comment

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

여기는 valid를 쓰지 않나용?

Copy link
Contributor

Choose a reason for hiding this comment

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

아직 valid 를 고려하지 않았어요. 예외처리 공통화와 함께 진행하려합니다. 꼼꼼한 리뷰 감사해요!

Comment on lines +51 to +70
public static BetEntity from(Bet bet) {
BetDetails betDetails = bet.getBetDetails();

return BetEntity.builder()
.id(bet.getId())
.title(betDetails.getTitle())
.bettingTime(betDetails.getBettingTime())
.loserDarakbangMemberId(bet.getLoserId())
.moimerId(bet.getMoimerId())
.build();
}

public static BetEntity create(Bet bet, long darakbangId) {
return BetEntity.builder()
.title(bet.getBetDetails().getTitle())
.bettingTime(bet.getBetDetails().getBettingTime())
.moimerId(bet.getMoimerId())
.darakbangId(darakbangId)
.build();
}
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

@ksk0605 ksk0605 Oct 1, 2024

Choose a reason for hiding this comment

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

개인적인 의견을 말씀드리면 엔티티와 도메인의 분리는 의존성 때문도 있지만 도메인 로직의 순수성을 지킨다는 목적에 더 가까워요.

기존처럼 도메인과 엔티티가 합쳐진 형태는 말 그대로

  1. 도메인 로직을 수행하는 역할
  2. DB의 데이터를 가져오는 역할
    이 합쳐진 형태니 SRP를 위반한다 라고 볼 수도 있구요.

물론 상돌 말처럼 의존성의 관리도 매우 중요하다고 생각합니다!
다른 팀원들의 동의하에 Factory 혹은 Mapper 클래스를 도입해볼 수 있겠습니다.
패턴은 일관적이면 좋으니까요!


public List<Bet> sort(List<Bet> bets) {
List<Bet> mutableBets = new ArrayList<>(bets);
LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

코드 전반적으로 withSecond, withNano가 중복되는데 이걸 한곳에 모아서 조금 더 의미있게 바꿀 수 있겠네요.

Copy link
Contributor

Choose a reason for hiding this comment

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

BettingTime 객체로 추상화했어요! 좋은 리뷰 감사합니다.

@ksk0605 ksk0605 merged commit 09c6e65 into develop-backend Oct 1, 2024
1 check passed
@ss0526100 ss0526100 deleted the feature/#566 branch October 17, 2024 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BE 백엔드 관련 이슈입니다. 🌱 기능추가 feature (새로운 기능 구현)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

내기 기능 추가
5 participants