Skip to content

Commit

Permalink
refactor(OutputView) : LottoApplication 및 기타 도메인에서 상금 결과를 출력하는 부분을 분리함
Browse files Browse the repository at this point in the history
- LottoReward, RewardCoordinator에서 출력 내용을 다루는 메서드 제거
- 출력 관련 부분은 전부 OutputView에서 관리하도록 함
- 출력을 할때 사용할 RewardDto 구현
- Test는 바뀐 내용에 의해 수정하거나 삭제함
  • Loading branch information
leegwichan committed Nov 16, 2022
1 parent 1484b17 commit ca4a0b4
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 81 deletions.
5 changes: 3 additions & 2 deletions src/main/java/lotto/LottoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lotto.lotto.Lotto;
import lotto.lotto.LottoShop;
import lotto.reward.RewardCoordinator;
import lotto.reward.dto.RewardDto;
import lotto.setting.LottoApplicationSetting;
import lotto.view.InputView;
import lotto.view.OutputView;
Expand Down Expand Up @@ -56,7 +57,7 @@ private void showRewardResult() {

WinningNumber winningNumber = setting.createWinningNumber(winningNumbers, bonusNumbers);
RewardCoordinator rewardCoordinator = setting.createRewardCoordinator(winningNumber, purchasePrice);
String rewardResult = rewardCoordinator.getRewardResult(lottos);
output.print(rewardResult);
RewardDto rewardDto = rewardCoordinator.getRewardDto(lottos);
outputView.printRewardResult(rewardDto);
}
}
26 changes: 12 additions & 14 deletions src/main/java/lotto/reward/RewardCoordinator.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package lotto.reward;

import lotto.lotto.Lotto;
import lotto.reward.dto.RewardDto;
import lotto.setting.LottoReward;
import lotto.winningnumber.WinningNumber;
import java.util.LinkedHashMap;
import java.util.List;

public class RewardCoordinator {
Expand All @@ -21,7 +23,7 @@ public RewardCoordinator(WinningNumber winningNumber,
this.purchasePrice = purchasePrice;
}

public String getRewardResult(List<Lotto> lottos) {
public RewardDto getRewardDto(List<Lotto> lottos) {
int[] totalResult = new int[rewards.size()];
long totalReward = 0;

Expand All @@ -30,10 +32,11 @@ public String getRewardResult(List<Lotto> lottos) {
if (index == NOT_REWARD){
continue;
}

totalResult[index]++;
totalReward += rewards.get(index).getPrize();
}
return printResult(totalResult, totalReward);
return new RewardDto(getRewardResult(totalResult), getPriceRatio(totalReward));
}

private int getRewardIndex(Lotto lotto) {
Expand All @@ -48,20 +51,15 @@ private int getRewardIndex(Lotto lotto) {
return NOT_REWARD;
}

private String printResult(int[] totalResult, long totalReward) {
StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append("\n당첨 통계\n---\n");
for (int index = totalResult.length-1; index >= 0; index--) {
String result = rewards.get(index).getRewardInfo() + " - " + totalResult[index] + "개\n";
stringBuilder.append(result);
private LinkedHashMap<LottoReward, Integer> getRewardResult(int[] totalResult) {
LinkedHashMap<LottoReward, Integer> rewardResult = new LinkedHashMap<>();
for (int index = rewards.size()-1; index >= 0; index--) {
rewardResult.put(rewards.get(index), totalResult[index]);
}
stringBuilder.append("총 수익률은 " + formattedRate(totalReward) + "%입니다.");

return stringBuilder.toString();
return rewardResult;
}

private String formattedRate(long totalReward) {
return String.format("%.1f", (double) totalReward / purchasePrice * 100);
private double getPriceRatio(long totalReward) {
return (double) totalReward / purchasePrice * 100;
}
}
23 changes: 23 additions & 0 deletions src/main/java/lotto/reward/dto/RewardDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package lotto.reward.dto;

import lotto.setting.LottoReward;
import java.util.LinkedHashMap;

public class RewardDto {

private LinkedHashMap<LottoReward, Integer> rewardResult;
private double priceRatio;

public RewardDto(LinkedHashMap<LottoReward, Integer> rewardResult, double priceRatio){
this.rewardResult = rewardResult;
this.priceRatio = priceRatio;
}

public LinkedHashMap<LottoReward, Integer> getRewardResult() {
return rewardResult;
}

public double getPriceRatio() {
return priceRatio;
}
}
39 changes: 8 additions & 31 deletions src/main/java/lotto/setting/LottoReward.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,19 @@ public enum LottoReward {
this.prize = prize;
}

public String getRewardInfo() {
// form : 3개 일치 (5,000원)
return getMatchInfo() + " " + getPriceInfo();
}

private String getMatchInfo() {
return countMatchInfo() + bonusMatchInfo();
}

private String countMatchInfo() {
return countMatch + "개 일치";
}

private String bonusMatchInfo() {
if (bonusMatch == 0) {
return "";
}
if (bonusMatch == 1) {
return ", 보너스 볼 일치";
}
return ", 보너스 볼 " + bonusMatch + "개 일치";
}

private String getPriceInfo() {
return "(" + shipShapedPrice() + "원)";
}

private String shipShapedPrice() {
return new DecimalFormat("###,###").format(prize);
}

public boolean isSatisfyMatchingCondition(int currentMatch, int currentBonusMatch) {
return currentMatch >= countMatch && currentBonusMatch >= bonusMatch;
}

public long getPrize() {
return prize;
}

public int getCountMatch() {
return countMatch;
}

public int getBonusMatch() {
return bonusMatch;
}
}
44 changes: 44 additions & 0 deletions src/main/java/lotto/view/OutputView.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import device.output.Output;
import lotto.lotto.dto.LottoDto;
import lotto.lotto.dto.LottoListDto;
import lotto.reward.dto.RewardDto;
import lotto.setting.LottoReward;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -29,4 +33,44 @@ private String getNumbers(LottoDto lottoDto) {
.map(number -> String.valueOf(number))
.collect(Collectors.joining(", ","[","]"));
}

public void printRewardResult(RewardDto rewardDto) {
output.print("\n당첨 통계\n---");
printRewardResult(rewardDto.getRewardResult());
printPriceRatio(rewardDto.getPriceRatio());
}

private void printRewardResult(LinkedHashMap<LottoReward, Integer> rewardResult) {
rewardResult.forEach(((lottoReward, count) -> {
output.print(getLottoRewardInfo(lottoReward) + " - " + count + "개");
}));
}

private String getLottoRewardInfo(LottoReward lottoReward) {
return getCountMatchInfo(lottoReward.getCountMatch())
+ getBonusMatchInfo(lottoReward.getBonusMatch())
+ " " + getPrizeInfo(lottoReward.getPrize());
}

private String getCountMatchInfo(int countMatch) {
return countMatch + "개 일치";
}

private String getBonusMatchInfo(int bonusMatch) {
if (bonusMatch == 0) {
return "";
}
if (bonusMatch == 1) {
return ", 보너스 볼 일치";
}
return ", 보너스 볼 " + bonusMatch + "개 일치";
}

private String getPrizeInfo(long prize) {
return "(" + new DecimalFormat("###,###").format(prize) + "원)";
}

private void printPriceRatio(double priceRatio) {
output.print("총 수익률은 " + String.format("%.1f", priceRatio) + "%입니다.");
}
}
19 changes: 8 additions & 11 deletions src/test/java/lotto/reward/RewardCoordinatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.mockito.Mockito.when;

import lotto.lotto.Lotto;
import lotto.reward.dto.RewardDto;
import lotto.setting.LottoReward;
import lotto.winningnumber.WinningNumber;
import org.junit.jupiter.api.Test;
Expand All @@ -18,27 +19,23 @@ void getRewardResultTest() {
WinningNumber winningNumber = mock(WinningNumber.class);
List<LottoReward> rewards = mockLottoRewards();
List<Lotto> lottos = mockLottos();
String excepted = "\n당첨 통계\n---\n" +
"5개 일치, 보너스 볼 일치 (30,000,000원) - 1개\n" +
"6개 일치 (2,000,000,000원) - 1개\n" +
"총 수익률은 200.0%입니다.";
double exceptedRatio = 4000L / 2000 * 100;

String result = new RewardCoordinator(winningNumber, rewards, 2000).getRewardResult(lottos);
RewardDto result = new RewardCoordinator(winningNumber, rewards, 2000).getRewardDto(lottos);

assertThat(result).isEqualTo(excepted);
assertThat(result.getPriceRatio()).isEqualTo(exceptedRatio);
assertThat(result.getRewardResult().size()).isEqualTo(1);
}

List<LottoReward> mockLottoRewards() {
LottoReward mockLottoReward = mock(LottoReward.class);
when(mockLottoReward.isSatisfyMatchingCondition(anyInt(), anyInt())).thenReturn(false, true, true);
when(mockLottoReward.getRewardInfo()).thenReturn( "5개 일치, 보너스 볼 일치 (30,000,000원)", "6개 일치 (2,000,000,000원)");
when(mockLottoReward.getPrize()).thenReturn(2000L);
return List.of(mockLottoReward, mockLottoReward);
return List.of(mockLottoReward);
}

List<Lotto> mockLottos() {
Lotto mock1 = mock(Lotto.class);
Lotto mock2 = mock(Lotto.class);
return List.of(mock1, mock2);
Lotto mockLotto = mock(Lotto.class);
return List.of(mockLotto, mockLotto, mockLotto);
}
}
23 changes: 0 additions & 23 deletions src/test/java/lotto/setting/LottoRewardTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,6 @@

public class LottoRewardTest {

@DisplayName("getRewardInfoTest")
@ParameterizedTest(name = "{displayName} Case {index}")
@ArgumentsSource(RewardInfoTestData.class)
void getRewardInfoTest(LottoReward lottoReward, String expected) {
String result = lottoReward.getRewardInfo();

assertThat(result).isEqualTo(expected);
}

static class RewardInfoTestData implements ArgumentsProvider {

@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
return Stream.of(
Arguments.of(LottoReward.FIRST, "6개 일치 (2,000,000,000원)"),
Arguments.of(LottoReward.SECOND, "5개 일치, 보너스 볼 일치 (30,000,000원)"),
Arguments.of(LottoReward.THIRD, "5개 일치 (1,500,000원)"),
Arguments.of(LottoReward.FOURTH, "4개 일치 (50,000원)"),
Arguments.of(LottoReward.FIFTH, "3개 일치 (5,000원)")
);
}
}

@DisplayName("isSatisfyMatchingConditionTest")
@ParameterizedTest(name = "{displayName} Case {index}")
@ArgumentsSource(SatisfyMatchingConditionTestData.class)
Expand Down

0 comments on commit ca4a0b4

Please sign in to comment.