-
Notifications
You must be signed in to change notification settings - Fork 109
[SCG] 최연우 로또 1-2단계 미션 제출합니다 #160
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
base: monsaumon
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # 1단계 기능 요구사항 | ||
| - [X] 로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다. | ||
| - [X] 로또 1장의 가격은 1000원이다. | ||
| - [X] 새로운 프로그래밍 요구사항 | ||
| - [X] 배열 대신 컬렉션을 사용한다. | ||
| - [X] 줄여 쓰지 않는다(축약 금지). | ||
| - [X] 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. | ||
| - [X] 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. | ||
|
|
||
| # 2단계 기능 요구사항 | ||
| - [X] 로또 당첨 번호를 받아 일치한 번호 수에 따라 당첨 결과를 보여준다. | ||
|
|
||
| ## 새로운 프로그래밍 요구사항 | ||
| 모든 원시 값과 문자열을 포장한다. | ||
| 일급 컬렉션을 쓴다. | ||
|
|
||
| ## 기존 프로그래밍 요구사항 | ||
| 자바 코드 컨벤션을 지키면서 프로그래밍한다. | ||
| 기본적으로 Java Style Guide을 원칙으로 한다. | ||
| indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다. | ||
| 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. | ||
| 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. | ||
| 3항 연산자를 쓰지 않는다. | ||
| else 예약어를 쓰지 않는다. | ||
| else 예약어를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. | ||
| 힌트: if문에서 값을 반환하는 방식으로 구현하면 else 예약어를 사용하지 않아도 된다. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import domain.Cashier; | ||
| import domain.Lotto; | ||
| import domain.LottoResult; | ||
| import domain.LottoTicket; | ||
| import domain.NumberListGenerator; | ||
| import domain.RandomNumberListGenerator; | ||
| import view.InputView; | ||
| import view.OutputView; | ||
|
|
||
| public class Application { | ||
| public static final Integer TICKET_LENGTH = 6; | ||
|
|
||
| public static void main(String[] args) { | ||
| InputView inputView = new InputView(); | ||
| OutputView outputView = new OutputView(); | ||
| NumberListGenerator numberListGenerator = new RandomNumberListGenerator(TICKET_LENGTH); | ||
| Cashier cashier = new Cashier(numberListGenerator); | ||
|
|
||
| Integer price = inputView.inputPrice(); | ||
| Lotto lotto = cashier.generateTickets(price); | ||
| outputView.showLottoTickets(lotto); | ||
|
|
||
| LottoTicket winnerTicket = inputView.getWinnerTicket(); | ||
| LottoResult result = cashier.getResults(lotto, winnerTicket); | ||
| outputView.showLottoResults(result, cashier.getProfitRate(result, price)); | ||
| } | ||
| } | ||
|
Comment on lines
+13
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 지난 미션의 랜덤값 테스트를 반영하여 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요구사항에 없더라도, 가능하면 테스트 코드도 함께 작성해보면 학습에 좋을 것 같아요~😄 LottoTicket, Lotto, Cashier 간 역할 분배에 대한 고민 해결에도 도움이 될 거에요!😄 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class Cashier { | ||
| public static final Integer THREE_CORRECT = 3; | ||
| public static final Integer FOUR_CORRECT = 4; | ||
| public static final Integer FIVE_CORRECT = 5; | ||
| public static final Integer SIX_CORRECT = 6; | ||
| private final NumberListGenerator numberListGenerator; | ||
|
|
||
| public Cashier(NumberListGenerator numberListGenerator) { | ||
| this.numberListGenerator = numberListGenerator; | ||
| } | ||
|
|
||
| public Lotto generateTickets(Integer price) { | ||
| validatePrice(price); | ||
| Integer numberOfTickets = calculateNumberOfTickets(price); | ||
| List<LottoTicket> generatedTickets = new ArrayList<>(); | ||
| for (Integer i = 0; i < numberOfTickets; i++) { | ||
| generatedTickets.add(new LottoTicket(numberListGenerator.generate())); | ||
| } | ||
|
|
||
| return new Lotto(generatedTickets); | ||
| } | ||
|
Comment on lines
+18
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
이 문장의 핵심은 이제 이 값을 그럼 값을 왜 포장해야하는가? 먼저 값을 포장하는 것은 값이 보장하지 않는다면, 아래와 같은 실수가 일어날 수 있습니다. 인수로 전달된 a와 b 값은 어떤 값인지, 전달받은 이제 위 내용을 참고하여, 현재 코드에서 값 포장을 위한 리펙터링 진행주시면 될 것 같아요! 진행하시면서
사실 이 문제도 완전히 해결된 건 아니거든요.😮 |
||
|
|
||
| public LottoResult getResults(Lotto lotto, LottoTicket winnerTicket) { | ||
| List<Integer> results = lotto.getResults(winnerTicket); | ||
| return new LottoResult( | ||
| Collections.frequency(results, THREE_CORRECT), | ||
| Collections.frequency(results, FOUR_CORRECT), | ||
| Collections.frequency(results, FIVE_CORRECT), | ||
| Collections.frequency(results, SIX_CORRECT) | ||
| ); | ||
| } | ||
|
|
||
| public Double getProfitRate(LottoResult result, Integer price) { | ||
| Integer totalProfit = 5000 * result.getThreeCorrectCount() | ||
| + 50000 * result.getFourCorrectCount() | ||
| + 1500000 * result.getFiveCorrectCount() | ||
| + 2000000000 * result.getSixCorrectCount(); | ||
|
|
||
| return totalProfit.doubleValue() / price; | ||
| } | ||
|
Comment on lines
+39
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기서 또한, |
||
|
|
||
| private void validatePrice(Integer price) { | ||
| if (price < 0) { | ||
| throw new IllegalArgumentException("잘못된 입력입니다."); | ||
| } | ||
| if (price < 1000) { | ||
| throw new IllegalArgumentException("돈이 부족합니다."); | ||
| } | ||
| if (price % 1000 != 0) { | ||
| throw new IllegalArgumentException("1000원 단위로 입력해주세요."); | ||
| } | ||
| } | ||
|
|
||
| private Integer calculateNumberOfTickets(Integer price) { | ||
| return price / 1000; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class Lotto { | ||
| private final List<LottoTicket> tickets; | ||
|
|
||
| public Lotto(List<LottoTicket> tickets) { | ||
| this.tickets = tickets; | ||
| } | ||
|
|
||
| public List<Integer> getResults(LottoTicket winnerTicket) { | ||
| List<Integer> results = new ArrayList<>(); | ||
| for (LottoTicket ticket : tickets) { | ||
| results.add(ticket.getResult(winnerTicket)); | ||
| } | ||
| return results; | ||
| } | ||
|
|
||
| public List<LottoTicket> getTickets() { | ||
| return tickets; | ||
| } | ||
|
|
||
| public int getNumberOfTickets() { | ||
| return tickets.size(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package domain; | ||
|
|
||
| public class LottoResult { | ||
| private final Integer threeCorrectCount; | ||
| private final Integer fourCorrectCount; | ||
| private final Integer fiveCorrectCount; | ||
| private final Integer sixCorrectCount; | ||
|
|
||
|
Comment on lines
+3
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| public LottoResult(Integer threeCorrectCount, | ||
| Integer fourCorrectCount, | ||
| Integer fiveCorrectCount, | ||
| Integer sixCorrectCount) { | ||
| this.threeCorrectCount = threeCorrectCount; | ||
| this.fourCorrectCount = fourCorrectCount; | ||
| this.fiveCorrectCount = fiveCorrectCount; | ||
| this.sixCorrectCount = sixCorrectCount; | ||
| } | ||
|
|
||
|
|
||
| public Integer getThreeCorrectCount() { | ||
| return threeCorrectCount; | ||
| } | ||
|
|
||
| public Integer getFourCorrectCount() { | ||
| return fourCorrectCount; | ||
| } | ||
|
|
||
| public Integer getFiveCorrectCount() { | ||
| return fiveCorrectCount; | ||
| } | ||
|
|
||
| public Integer getSixCorrectCount() { | ||
| return sixCorrectCount; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package domain; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
|
|
||
|
|
||
| public class LottoTicket { | ||
| private final List<Integer> ticket; | ||
|
|
||
| public LottoTicket(List<Integer> ticket) { | ||
| validate(ticket); | ||
| Collections.sort(ticket); | ||
| this.ticket = ticket; | ||
| } | ||
|
|
||
| static private void validate(List<Integer> ticket) { | ||
| int length = ticket.size(); | ||
| Set<Integer> ticketSet = new HashSet<>(ticket); | ||
| if (ticketSet.size() != length) { | ||
| throw new RuntimeException(); | ||
| } | ||
| } | ||
|
|
||
| public Integer getResult(LottoTicket winnerTicket) { | ||
| Integer count = 0; | ||
| for (Integer number : winnerTicket.getTicket()) { | ||
| count += Boolean.compare(ticket.contains(number), false); | ||
| } | ||
|
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도 마찬가지입니다! |
||
| return count; | ||
| } | ||
|
|
||
| public List<Integer> getTicket() { | ||
| return ticket; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public interface NumberListGenerator { | ||
| List<Integer> generate(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package domain; | ||
|
|
||
| import java.util.*; | ||
|
|
||
| public class RandomNumberListGenerator implements NumberListGenerator { | ||
| private static final Integer UPPER_BOUND = 46; | ||
| private static final Integer LOWER_BOUND = 1; | ||
|
|
||
| private final Integer length; | ||
|
|
||
| public RandomNumberListGenerator(final Integer length) { | ||
| this.length = length; | ||
| } | ||
|
|
||
| @Override | ||
| public List<Integer> generate() { | ||
| List<Integer> numberList = new ArrayList<>(); | ||
| for (Integer i = LOWER_BOUND; i < UPPER_BOUND; i++) { | ||
| numberList.add(i); | ||
| } | ||
|
Comment on lines
+18
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
IDE에서 바꾸라고 하는 이유는 무엇일까요?🤔 요구사항이 잘못되었다고 느껴졌을 때, 이를 설득시키는 것도 중요하다 생각합니다. 이런 맥락에서 잘못된 이유는 확실히 짚고 넘어가면 좋을 것 같아요!😄 |
||
| Collections.shuffle(numberList); | ||
| return numberList.subList(0, length); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package view; | ||
|
|
||
| import domain.LottoTicket; | ||
| import java.util.Arrays; | ||
| import java.util.Scanner; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class InputView { | ||
| private final Scanner scanner; | ||
|
|
||
| public InputView() { | ||
| scanner = new Scanner(System.in); | ||
| } | ||
|
|
||
| public Integer inputPrice() { | ||
| System.out.println("구입 금액을 입력해 주세요."); | ||
| return Integer.valueOf(scanner.nextLine()); | ||
| } | ||
|
|
||
| public LottoTicket getWinnerTicket() { | ||
| System.out.println("지난 주 당첨 번호를 입력해 주세요."); | ||
| return new LottoTicket( | ||
| Arrays.stream(scanner.nextLine().split(", ")).map(Integer::valueOf).collect(Collectors.toList())); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| package view; | ||
|
|
||
| import domain.Lotto; | ||
| import domain.LottoResult; | ||
| import domain.LottoTicket; | ||
| import java.util.List; | ||
|
|
||
| public class OutputView { | ||
| public void showLottoTickets(Lotto lotto) { | ||
| System.out.println(); | ||
| System.out.println(lotto.getNumberOfTickets() + "개를 구매했습니다."); | ||
| for (LottoTicket lottoTicket : lotto.getTickets()) { | ||
| showLottoTicket(lottoTicket); | ||
| } | ||
| } | ||
|
|
||
| public void showLottoResults(LottoResult result, Double profitRate) { | ||
| showLottoStatistics(result); | ||
| showProfitRate(profitRate); | ||
| } | ||
|
|
||
| public void showLottoStatistics(LottoResult result) { | ||
| System.out.println("\n당첨 통계\n---------"); | ||
| System.out.println("3개 일치 (5000원)- " + result.getThreeCorrectCount() + "개"); | ||
| System.out.println("4개 일치 (50000원)- " + result.getFourCorrectCount() + "개"); | ||
| System.out.println("5개 일치 (1500000원)- " + result.getFiveCorrectCount() + "개"); | ||
| System.out.println("6개 일치 (2000000000원)- " + result.getSixCorrectCount() + "개"); | ||
| } | ||
|
|
||
| public void showProfitRate(Double profitRate) { | ||
| System.out.printf("총 수익률은 %.2f입니다.", profitRate); | ||
| if (profitRate > 1) { | ||
| System.out.print("(기준이 1이기 때문에 결과적으로 이득이라는 의미임)"); | ||
| return; | ||
| } | ||
|
|
||
| if (profitRate == 1) { | ||
| System.out.print("(기준이 1이기 때문에 결과적으로 본전이라는 의미임)"); | ||
| return; | ||
| } | ||
|
|
||
| System.out.print("(기준이 1이기 때문에 결과적으로 손해라는 의미임)"); | ||
| } | ||
|
|
||
| private void showLottoTicket(LottoTicket lottoTicket) { | ||
| List<Integer> ticket = lottoTicket.getTicket(); | ||
| System.out.println(ticket); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
만약 또한,
때문에, 값을 감싼 객체는 자신의 값을 책임지고 관리할 수 있어야 합니다.🤔 |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
따로 분리하거나, 빼도 괜찮을 것 같아요~