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

Step4 코드리뷰 요청드립니다 #21

Open
wants to merge 2 commits into
base: junwoochoi
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/main/java/WebMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import dto.LotteryRequestDto;
import handlebars.CustomHandlebarsTemplateEngine;
import lotto.*;
import spark.ModelAndView;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static spark.Spark.*;
import static view.InputView.COMMA;

public class WebMain {
private static final String LOTTERIES = "lotteries";
private static final String INPUT_MONEY = "inputMoney";
public static final String WINNING_NUMBER = "winningNumber";
public static final String BONUS_NUMBER = "bonusNumber";
public static final String YIELD = "yield";
public static final String RESULTS = "results";

public static void main(String[] args) {
port(8080);

get("/", (req, res) -> {
req.session(true);
return render("/index.html");
});
post("/buyLotto", (req, res) -> {
final LotteryRequestDto requestDto = new LotteryRequestDto(req.queryParams("inputMoney"), req.queryParams("manualNumber"));

final List<Lottery> lotteries = LottoShop.sell(requestDto.getInputMoney(), requestDto.getManualLottoInputs());

req.session().attribute(LOTTERIES, lotteries);
req.session().attribute(INPUT_MONEY, requestDto.getInputMoney());

final Map<String, Object> responseParams = new HashMap<>();
responseParams.put(LOTTERIES, lotteries.stream()
.map(Lottery::toString)
.collect(Collectors.toList()));
return render(responseParams, "/show.html");
});

post("/matchLotto", (req, res) -> {
final List<Lottery> lotteries = req.session().attribute(LOTTERIES);
final Money inputMoney = req.session().attribute(INPUT_MONEY);

req.session().attribute(LOTTERIES, lotteries);

final String[] winningNumber = req.queryParams(WINNING_NUMBER)
.trim()
.split(COMMA);
final String inputBonusNumber = req.queryParams(BONUS_NUMBER).trim();

final WinningNumbers winningNumbers = WinningNumbers.of(
Arrays.stream(winningNumber)
.map(String::trim)
.map(Integer::parseInt)
.collect(Collectors.toList())
, Integer.parseInt(inputBonusNumber)
);

final Results results = ResultsFactory.create(lotteries, winningNumbers, inputMoney);
final Map<String, Object> responseParams = new HashMap<>();
responseParams.put(YIELD, results.getYield());
for (Prize prize : Prize.values()) {
responseParams.put(prize.name(), results.getCountOfPrize().getOrDefault(prize, 0));
}

req.session().invalidate();
Copy link

Choose a reason for hiding this comment

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

저도 session 을 활용해봐야 겠네요! 배워갑니다

return render(responseParams, "/result.html");
});
}

private static String render(String templatePath) {
return render(null, templatePath);
}

public static String render(Map<String, Object> model, String templatePath) {
return new CustomHandlebarsTemplateEngine().render(new ModelAndView(model, templatePath));
}
}
40 changes: 40 additions & 0 deletions src/main/java/dto/LotteryRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dto;

import lotto.Money;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static view.InputView.COMMA;

public class LotteryRequestDto {
Copy link
Member

Choose a reason for hiding this comment

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

오, 요렇게 dto를 분리해서, 파싱 로직을 분리한 부분이 인상깊네요! 배우고갑니당 :)


public static final String LINE_BREAK_REGEX = "\\r?\\n";
private Money inputMoney;
private List<List<Integer>> manualLottoInputs;

public LotteryRequestDto(String inputMoney, String manualLottoInputs) {
this.inputMoney = Money.of(Long.parseLong(inputMoney));
this.manualLottoInputs = Arrays.stream(manualLottoInputs.split(LINE_BREAK_REGEX))
.map(LotteryRequestDto::parseLine)
.collect(Collectors.toList());
}

private static List<Integer> parseLine(String eachLine) {
return Arrays.stream(eachLine.split(COMMA))
.map(String::trim)
.mapToInt(Integer::parseInt)
.boxed()
.collect(Collectors.toList());
}

public Money getInputMoney() {
return inputMoney;
}

public List<List<Integer>> getManualLottoInputs() {
return Collections.unmodifiableList(manualLottoInputs);
}
}
52 changes: 52 additions & 0 deletions src/main/java/handlebars/CustomHandlebarsTemplateEngine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package handlebars;

import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.cache.GuavaTemplateCache;
import com.github.jknack.handlebars.io.ClassPathTemplateLoader;
import com.github.jknack.handlebars.io.TemplateLoader;
import com.github.jknack.handlebars.io.TemplateSource;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.eclipse.jetty.io.RuntimeIOException;
import spark.ModelAndView;
import spark.TemplateEngine;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class CustomHandlebarsTemplateEngine extends TemplateEngine {

protected Handlebars handlebars;

public CustomHandlebarsTemplateEngine() {
this("/templates");
}

public CustomHandlebarsTemplateEngine(String resourceRoot) {
final TemplateLoader templateLoader = new ClassPathTemplateLoader();
templateLoader.setPrefix(resourceRoot);
templateLoader.setSuffix(null);

this.handlebars = new Handlebars(templateLoader);
this.handlebars.registerHelper("length", new LengthHelper());
this.handlebars.registerHelper("plusOne", new PlusOneHelper());
Comment on lines +32 to +33
Copy link

Choose a reason for hiding this comment

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

👍

Choose a reason for hiding this comment

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

다들 커스텀 헬퍼를 잘 쓰셨군요 ㅠㅠ.. 저는 자바스크립트 단 코드만 주구장창 찾았는데.. 참고하도록 하겠습니다 !


// Set Guava cache.
Cache<TemplateSource, Template> cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(1000).build();

handlebars = handlebars.with(new GuavaTemplateCache(cache));
}

@Override
public String render(ModelAndView modelAndView) {
try {
String viewName = modelAndView.getViewName();
Template template = handlebars.compile(viewName);
return template.apply(modelAndView.getModel());
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/handlebars/LengthHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package handlebars;

import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;

import java.util.List;

public class LengthHelper implements Helper<List<String>> {

@Override
public Object apply(List<String> context, Options options) {
if (context == null || context.isEmpty()) {
return 0;
}
return context.size();
}
}
13 changes: 13 additions & 0 deletions src/main/java/handlebars/PlusOneHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package handlebars;

import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;

public class PlusOneHelper implements Helper<Integer> {

@Override
public CharSequence apply(Integer context, Options options) {
final int plusOne = context + 1;
return String.valueOf(plusOne);
}
}
17 changes: 15 additions & 2 deletions src/main/java/lotto/Lottery.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
import java.util.TreeSet;
import java.util.stream.Collectors;

import static view.InputView.COMMA;


public class Lottery {

public static final int LOTTO_NUMBER_COUNT = 6;
public static final long LOTTO_PRICE = 1000;

private Set<LottoNo> numbers;
protected Set<LottoNo> numbers;

private Lottery(Set<Integer> lottoNumbers) {
protected Lottery(Set<Integer> lottoNumbers) {
validateNumbers(lottoNumbers);
this.numbers = lottoNumbers.stream()
.map(LottoNo::of)
Expand All @@ -36,6 +38,9 @@ public Result checkResult(WinningNumbers winningNumbers) {
}

private void validateNumbers(Set<Integer> lottoNumbers) {
if (lottoNumbers == null) {
throw new IllegalArgumentException("입력값이 NULL입니다.");
}
if (lottoNumbers.size() != LOTTO_NUMBER_COUNT) {
throw new IllegalArgumentException("로또의 갯수가 잘못되었거나 중복된 숫자가 있습니다.");
}
Expand All @@ -52,4 +57,12 @@ private int correctCount(WinningNumbers winningNumbers) {
return LOTTO_NUMBER_COUNT + (LOTTO_NUMBER_COUNT - combinedSize);
}

@Override
public String toString() {
return "["
+ numbers.stream()
.map(String::valueOf)
.collect(Collectors.joining(COMMA))
+ "]";
}
}
3 changes: 3 additions & 0 deletions src/main/java/lotto/RandomLottoGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ public Lottery generate() {

return Lottery.of(lottoNumbers);
}



}
43 changes: 7 additions & 36 deletions src/main/java/lotto/WinningNumbers.java
Original file line number Diff line number Diff line change
@@ -1,62 +1,33 @@
package lotto;

import spark.utils.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.TreeSet;

public class WinningNumbers {
public class WinningNumbers extends Lottery {
Copy link

Choose a reason for hiding this comment

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

상속 적용하신것 👍


private List<LottoNo> winningNumbers;
private LottoNo bonusNumber;

private WinningNumbers(List<Integer> numbers, Integer bonusNumber) {
validateParams(numbers, bonusNumber);
protected WinningNumbers(List<Integer> numbers, Integer bonusNumber) {
super(new TreeSet<>(numbers));
Comment on lines +7 to +12
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
Member Author

Choose a reason for hiding this comment

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

한번 참고해보겠습니다 ㅎㅎ 감사합니다

validateBonusNumber(bonusNumber);
this.bonusNumber = LottoNo.of(bonusNumber);
this.winningNumbers = numbers.stream()
.map(LottoNo::of)
.collect(Collectors.toList());
}

private void validateParams(List<Integer> numbers, Integer bonusNumber) {
validateNumbers(numbers);
validateBonusNumber(bonusNumber, numbers);
}

public static WinningNumbers of(List<Integer> numbers, Integer bonusNumber) {
return new WinningNumbers(numbers, bonusNumber);
}

private void validateNumbers(List<Integer> numbers) {
if (CollectionUtils.isEmpty(numbers)) {
throw new IllegalArgumentException("winning numbers cannot be empty");
}

if (numbers.size() != Lottery.LOTTO_NUMBER_COUNT) {
throw new IllegalArgumentException("winning numbers size should be LOTTO_NUMBER_COUNT");
}

if (numbers.stream().distinct().count() != numbers.size()) {
throw new IllegalArgumentException("winning numbers can not have duplicate numbers");
}
}

private void validateBonusNumber(Integer bonusNumber, List<Integer> winningNumbers) {
private void validateBonusNumber(Integer bonusNumber) {
if (Objects.isNull(bonusNumber)) {
throw new IllegalArgumentException("bonus number can not be null or empty");
}

if (winningNumbers.contains(bonusNumber)) {
if (this.numbers.contains(LottoNo.of(bonusNumber))) {
throw new IllegalArgumentException("bonus number is already in");
}
}

public List<LottoNo> getNumbers() {
return new ArrayList<>(winningNumbers);
}

public LottoNo getBonusNumber() {
return bonusNumber;
}
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/view/ResultView.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ public void printLottoResults(ResultsDto resultsDto) {
printHeader();

final Map<Prize, Integer> countOfPrize = resultsDto.getCountOfPrize();
final Set<Prize> prizes = countOfPrize.keySet();

printCountOfPrize(countOfPrize, prizes);
printCountOfPrize(countOfPrize);

printYield(resultsDto);
}
Expand All @@ -43,8 +42,8 @@ private static void printHeader() {
System.out.println("============");
}

private void printCountOfPrize(Map<Prize, Integer> countOfPrize, Set<Prize> prizes) {
prizes.stream()
private void printCountOfPrize(Map<Prize, Integer> countOfPrize) {
countOfPrize.keySet().stream()
.filter(prize -> prize != Prize.NONE)
.forEach(prize -> printEach(countOfPrize.get(prize), prize));
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/resources/templates/result.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,23 @@
</thead>
<tbody>
<tr>
<th>3개 일치 (5000원)- 3개</th>
<th>3개 일치 (5000원)- {{FIFTH_PRIZE}}개</th>
</tr>
<tr>
<th>4개 일치 (50000원)- 1개</th>
<th>4개 일치 (50000원)- {{SECOND_PRIZE}}개</th>
</tr>
<tr>
<th>5개 일치 (1500000원)- 0개</th>
<th>5개 일치 (1500000원)- {{THIRD_PRIZE}}개</th>
</tr>
<tr>
<th>5개 일치, 보너스 볼 일치(30000000원)- 0개</th>
<th>5개 일치, 보너스 볼 일치(30000000원)- {{SECOND_PRIZE}}개</th>
</tr>
<tr>
<th>6개 일치 (2000000000원)- 0개</th>
<th>6개 일치 (2000000000원)- {{FIRST_PRIZE}}개</th>
Comment on lines 75 to +88
Copy link

@nokchax nokchax Mar 27, 2020

Choose a reason for hiding this comment

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

PRIZE가 4개 일치 까지만 계산하도록 변경됐을때, 결과 페이지도 수정하지 않는 방법이 있지 않을까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

흠... 사실 이부분은 찝찝한데 일단은 그냥 냈던거라... 더 좋은 방법을 강구해보겠습니다 ㅎㅎ

</tr>
</tbody>
<tfoot>
<th><h4 class="text-center">총 수익률은 20%입니다.</h4></th>
<th><h4 class="text-center">총 수익률은 {{yield}}%입니다.</h4></th>
</tfoot>
</table>
</pre>
Expand Down
Loading