Skip to content

Commit

Permalink
refactor: 참여자 정산 현황 로직 리펙토링 (#110)
Browse files Browse the repository at this point in the history
* refactor: 참여자 정산 현황 로직 수정

* refactor: forEach -> stream 변경
  • Loading branch information
Arachneee authored Jul 26, 2024
1 parent d056d28 commit 14be9b3
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package server.haengdong.application;

import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -9,7 +8,7 @@
import server.haengdong.domain.action.BillActionRepository;
import server.haengdong.domain.action.MemberAction;
import server.haengdong.domain.action.MemberActionRepository;
import server.haengdong.domain.action.MemberBillReports;
import server.haengdong.domain.action.MemberBillReport;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.event.EventRepository;
import server.haengdong.exception.HaengdongErrorCode;
Expand All @@ -29,12 +28,10 @@ public List<MemberBillReportAppResponse> getMemberBillReports(String token) {
List<BillAction> billActions = billActionRepository.findByAction_Event(event);
List<MemberAction> memberActions = memberActionRepository.findAllByEvent(event);

MemberBillReports memberBillReports = MemberBillReports.createByActions(billActions, memberActions);
MemberBillReport memberBillReport = MemberBillReport.createByActions(billActions, memberActions);

List<MemberBillReportAppResponse> memberBillReportResponses = new ArrayList<>();
memberBillReports.getReports().forEach(
(member, price) -> memberBillReportResponses.add(new MemberBillReportAppResponse(member, price))
);
return memberBillReportResponses;
return memberBillReport.getReports().entrySet().stream()
.map(entry -> new MemberBillReportAppResponse(entry.getKey(), entry.getValue()))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package server.haengdong.domain.action;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class CurrentMembers {

private final Set<String> members;

public CurrentMembers() {
this(new HashSet<>());
}

private CurrentMembers(Set<String> members) {
this.members = members;
}

public static CurrentMembers of(List<MemberAction> memberActions) {
List<MemberAction> sortedMemberActions = getSortedMemberActions(memberActions);
Set<String> members = new HashSet<>();
Expand All @@ -34,4 +38,29 @@ private static List<MemberAction> getSortedMemberActions(List<MemberAction> memb
.sorted(Comparator.comparing(MemberAction::getSequence))
.toList();
}

public CurrentMembers addMemberAction(MemberAction memberAction) {
String memberName = memberAction.getMemberName();

Set<String> currentMembers = new HashSet<>(members);

if (memberAction.isIn()) {
currentMembers.add(memberName);
} else {
currentMembers.remove(memberName);
}
return new CurrentMembers(currentMembers);
}

public boolean isEmpty() {
return members.isEmpty();
}

public int size() {
return members.size();
}

public Set<String> getMembers() {
return Collections.unmodifiableSet(members);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public boolean isSameName(String name) {
return memberName.equals(name);
}

public boolean isIn() {
return status == MemberActionStatus.IN;
}

public boolean isSameStatus(MemberActionStatus memberActionStatus) {
return status == memberActionStatus;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,31 @@

import static java.util.stream.Collectors.toMap;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.function.Function;
import lombok.Getter;

@Getter
public class MemberBillReports {
public class MemberBillReport {

private final Map<String, Long> reports;

private MemberBillReports(Map<String, Long> reports) {
private MemberBillReport(Map<String, Long> reports) {
this.reports = reports;
}

public static MemberBillReports createByActions(List<BillAction> billActions, List<MemberAction> memberActions) {
public static MemberBillReport createByActions(List<BillAction> billActions, List<MemberAction> memberActions) {
PriorityQueue<BillAction> sortedBillActions = new PriorityQueue<>(billActions);
PriorityQueue<MemberAction> sortedMemberActions = new PriorityQueue<>(memberActions);

Map<String, Long> memberBillReports = initReports(memberActions);
Set<String> currentMembers = new HashSet<>();

CurrentMembers currentMembers = new CurrentMembers();
while (!sortedBillActions.isEmpty() && !sortedMemberActions.isEmpty()) {
if (isMemberActionTurn(sortedMemberActions, sortedBillActions)) {
addMemberAction(sortedMemberActions, currentMembers);
MemberAction memberAction = sortedMemberActions.poll();
currentMembers = currentMembers.addMemberAction(memberAction);
continue;
}
addBillAction(sortedBillActions, currentMembers, memberBillReports);
Expand All @@ -38,7 +36,7 @@ public static MemberBillReports createByActions(List<BillAction> billActions, Li
addBillAction(sortedBillActions, currentMembers, memberBillReports);
}

return new MemberBillReports(memberBillReports);
return new MemberBillReport(memberBillReports);
}

private static Map<String, Long> initReports(List<MemberAction> memberActions) {
Expand All @@ -58,25 +56,19 @@ private static boolean isMemberActionTurn(
return memberAction.getSequence() < billAction.getSequence();
}

private static void addMemberAction(PriorityQueue<MemberAction> sortedMemberActions, Set<String> currentMembers) {
MemberAction memberAction = sortedMemberActions.poll();
String memberName = memberAction.getMemberName();
if (memberAction.isSameStatus(MemberActionStatus.IN)) {
currentMembers.add(memberName);
return;
}
currentMembers.remove(memberAction.getMemberName());
}

private static void addBillAction(
PriorityQueue<BillAction> sortedBillActions,
Set<String> currentMembers,
CurrentMembers currentMembers,
Map<String, Long> memberBillReports
) {
BillAction billAction = sortedBillActions.poll();
if (currentMembers.isEmpty()) {
return;
}

Long pricePerMember = billAction.getPrice() / currentMembers.size();
for (String currentMember : currentMembers) {
Long price = memberBillReports.getOrDefault(currentMember, 0L) + pricePerMember;
for (String currentMember : currentMembers.getMembers()) {
Long price = memberBillReports.get(currentMember) + pricePerMember;
memberBillReports.put(currentMember, price);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static server.haengdong.domain.action.MemberActionStatus.OUT;

import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import server.haengdong.domain.event.Event;
Expand All @@ -27,4 +28,31 @@ void of() {
assertThat(currentMembers.getMembers())
.containsExactlyInAnyOrder("망쵸", "웨디");
}

@DisplayName("인원 변동 액션의 상태가 IN이면 현재 인원에 추가한다.")
@Test
void addMemberAction1() {
CurrentMembers currentMembers = new CurrentMembers();
Event event = new Event("이벤트", "token");
MemberAction memberAction = new MemberAction(new Action(event, 1L), "웨디", IN, 1L);

CurrentMembers addedCurrentMembers = currentMembers.addMemberAction(memberAction);
Set<String> members = addedCurrentMembers.getMembers();

assertThat(members).hasSize(1)
.containsExactly("웨디");
}

@DisplayName("인원 변동 액션의 상태가 OUT이면 현재 인원에서 제외한다.")
@Test
void addMemberAction2() {
Event event = new Event("이벤트", "token");
MemberAction memberAction1 = new MemberAction(new Action(event, 1L), "웨디", IN, 1L);
CurrentMembers currentMembers = new CurrentMembers().addMemberAction(memberAction1);
MemberAction memberAction2 = new MemberAction(new Action(event, 1L), "웨디", OUT, 1L);

CurrentMembers addedCurrentMembers = currentMembers.addMemberAction(memberAction2);

assertThat(addedCurrentMembers.getMembers()).hasSize(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.junit.jupiter.api.Test;
import server.haengdong.domain.event.Event;

class MemberBillReportsTest {
class MemberBillReportTest {

@DisplayName("액션 목록으로 참가자 정산 리포트를 생성한다.")
@Test
Expand All @@ -29,9 +29,9 @@ void createByActions() {
new MemberAction(new Action(event, 5L), "감자", OUT, 2L)
);

MemberBillReports memberBillReports = MemberBillReports.createByActions(billActions, memberActions);
MemberBillReport memberBillReport = MemberBillReport.createByActions(billActions, memberActions);

assertThat(memberBillReports.getReports())
assertThat(memberBillReport.getReports())
.containsAllEntriesOf(
Map.of(
"감자", 20_000L,
Expand Down

0 comments on commit 14be9b3

Please sign in to comment.