๐ ๊ธฐ๋ฅ ์๊ตฌ์ฌํญ
- ๋ก๋ ๊ฒ์ ๊ธฐ๋ฅ์ ๊ตฌํํด์ผ ํ๋ค. ๊ท์น์ ๋ชจ๋ฅด๋ฉด ๊ฒ์ํด ๋ก๋ ๊ท์น์ ์ฐพ์๋ณธ๋ค.
- ๋ก๋ ๊ตฌ์ ๊ธ์ก์ ์ ๋ ฅํ๋ฉด ๊ตฌ์ ๊ธ์ก์ ํด๋นํ๋ ๋ก๋๋ฅผ ๋ฐ๊ธํด์ผ ํ๋ค.
- ๋ก๋ 1์ฅ์ ๊ฐ๊ฒฉ์ 1000์์ด๋ค.
- ๋ก๋ ๋น์ฒจ ๊ธ์ก์ ๊ณ ์ ๋์ด ์๋ ๊ฒ์ผ๋ก ๊ฐ์ ํ๋ค.
- ์์ต๋ฅ ์ ๊ณ์ฐํด ์ถ๋ ฅํด์ผ ํ๋ค.
โ๐ป ์ ์ถ๋ ฅ ์๊ตฌ์ฌํญ
์ ๋ ฅ
โจ๏ธ- ๋ก๋ ๊ตฌ์ ๊ธ์ก
- ๋ก๋ ๋น์ฒจ๋ฒํธ
- ๋ก๋ ๋ณด๋์ค ๋ฒํธ
์ถ๋ ฅ
๐ฅ- ๊ตฌ์ ํ ๋ก๋ ๊ฐ์๋งํผ ์์ฑ๋ ๋ก๋๋ฒํธ ๋ชฉ๋ก
3๊ฐ๋ฅผ ๊ตฌ๋งคํ์ต๋๋ค.
[8, 21, 23, 41, 42, 43]
[1, 3, 6, 7, 33, 37]
[6, 16, 25, 29, 39, 45]
- ๋น์ฒจ ํต๊ณ
๋น์ฒจ ํต๊ณ
--------------
3๊ฐ ์ผ์น (5000์) - 1๊ฐ
4๊ฐ ์ผ์น (50000์) - 0๊ฐ
5๊ฐ ์ผ์น (1500000์) - 0๊ฐ
5๊ฐ ์ผ์น, ๋ณด๋์ค ๋ณผ ์ผ์น (30000000์) - 0๊ฐ
์ด ์์ต๋ฅ ์ 1.66์
๋๋ค.
ํ๋ก๊ทธ๋๋ฐ ์คํ ๊ฒฐ๊ณผ ์์
๐ป๊ตฌ์
๊ธ์ก์ ์
๋ ฅํด ์ฃผ์ธ์.
3000
3๊ฐ๋ฅผ ๊ตฌ๋งคํ์ต๋๋ค.
[8, 21, 23, 41, 42, 43]
[1, 3, 6, 7, 33, 37]
[6, 16, 25, 29, 39, 45]
์ง๋ ์ฃผ ๋น์ฒจ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.
1,2,3,4,5,6
๋ณด๋์ค ๋ณผ์ ์
๋ ฅํด์ฃผ์ธ์.
7
๋น์ฒจ ํต๊ณ
--------------
3๊ฐ ์ผ์น (5000์) - 1๊ฐ
4๊ฐ ์ผ์น (50000์) - 0๊ฐ
5๊ฐ ์ผ์น (1500000์) - 0๊ฐ
5๊ฐ ์ผ์น, ๋ณด๋์ค ๋ณผ ์ผ์น (30000000์) - 0๊ฐ
์ด ์์ต๋ฅ ์ 1.66์
๋๋ค.
…
### MVC ํจํด ๋ถ๋ฆฌ
###
- ๊ฐ์ ํด๋์ค ๋ด์์ ํธ์ถ๋๋ ๋ฉ์๋๋ private์ผ๋ก ์ ์ธ
- controller๊ฐ view ์์ญ์๊ฒ ์์ฒญํด์ ๋ฐ์ ๊ฐ์ model์์ญ์ผ๋ก ๋๊ฒจ์ฃผ๋ ๋ฐฉ์
main controller
public class MainController {
public void play() {
List<Lotto> userLotto = createUserLotto(); // ์ฌ์ฉ์ ๋ก๋ ์์ฑ
WinningLotto winningLotto = createWinningLotto(); // ๋น์ฒจ ๋ก๋ ์์ฑ
printLottoGameResult(userLotto, winningLotto); // ๋ก๋ ๊ฒ์ ๊ฒฐ๊ณผ ์ถ๋ ฅ
}
// ์ฌ์ฉ์ ๋ก๋ ์์ฑ
private List<Lotto> createUserLotto() {
int cost = InputController.inputCost(); // view ํธ์ถ, ์ฌ์ฉ์ ๋ก๋ ๊ตฌ์
๊ธ์ก ์
๋ ฅ
int count = User.getCount(cost); // model ํธ์ถ, ์ฌ์ฉ์ ๋ก๋ ๊ตฌ์
๊ฐฏ์ ๊ตฌํ๊ธฐ
OutputView.printPurchaseMessage(count); // view ํธ์ถ, ์ฌ์ฉ์ ๋ก๋ ๊ตฌ์
๊ฐฏ์ ์๋ด ๋ฉ์ธ์ง ์ถ๋ ฅ
List<Lotto> userLotto = User.getTotalLotto(count); // model ํธ์ถ, ์ฌ์ฉ์ ๊ตฌ์
๋ก๋ ๋ฆฌ์คํธ ๊ตฌํ๊ธฐ
OutputView.printUserLotto(userLotto); // view ํธ์ถ, ์ฌ์ฉ์ ๊ตฌ์
๋ก๋ ๋ฆฌ์คํธ ์ถ๋ ฅ
return userLotto;
}
// ๋น์ฒจ ๋ก๋ ์์ฑ
private WinningLotto createWinningLotto() {
String[] winningNumber = InputController.inputWinningNumber(); // view ํธ์ถ, ์ง๋์ฃผ ๋น์ฒจ ๋ฒํธ ์
๋ ฅ
int bonusNumber = InputController.inputBonusNumber(); // view ํธ์ถ, ์ง๋์ฃผ ๋ณด๋์ค ๋ฒํธ ์
๋ ฅ
List<Integer> winningNumbers = Convert.changeStringArrayToList(winningNumber); // string[] > list<Integer>
Lotto lotto = Lotto.getLotto(winningNumbers); // model ํธ์ถ, ๋น์ฒจ ๋ก๋ ์์ฑ
return new WinningLotto(lotto, bonusNumber);
}
// ๋ก๋ ๊ฒ์ ๊ฒฐ๊ณผ ์ถ๋ ฅ
private void printLottoGameResult(List<Lotto> userLotto, WinningLotto winningLotto) {
Map<Rank, Integer> statistics = Statistics.getWinningStatistics(userLotto, winningLotto); // model ํธ์ถ, ๋น์ฒจ ํต๊ณ ๊ตฌํ๊ธฐ
OutputView.printWinningStatistics(statistics); // view ํธ์ถ, ๋น์ฒจ ํต๊ณ ์ถ๋ ฅ
int winningMoney = Statistics.getTotalWinningMoney(statistics); // model ํธ์ถ, ๋น์ฒจ ๊ธ์ก ๊ตฌํ๊ธฐ
double yield = Statistics.getTotalYield(winningMoney, userLotto.size()); // model ํธ์ถ, ์ด ์์ต๋ฅ ๊ตฌํ๊ธฐ
OutputView.printTotalYield(yield); // view ํธ์ถ, ์ด ์์ต๋ฅ ์ถ๋ ฅ
}
}
model.Lotto
public class Lotto {
private final List<Integer> numbers;
public Lotto(List<Integer> numbers) {
this.numbers = numbers;
}
// ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์ซ์๋ก ์์ฑ๋ ๋ก๋ ๋ฐํ
public static Lotto getLotto(List<Integer> numbers) {
return new Lotto(numbers);
}
public List<Integer> getNumber() {
return this.numbers;
}
// ๋น์ฒจ ๋ฒํธ์ ์ฌ์ฉ์ ๋ก๋ ๋ฒํธ ์ค ์ผ์นํ๋ ๋ฒํธ๊ฐ ๋ช๊ฐ์ธ์ง ๋ฐํ
public int getMatchCount(Lotto winningLotto) {
List<Integer> user = numbers;
List<Integer> winning = winningLotto.getNumber();
List<Integer> win = new ArrayList<>();
for (Integer i : winning) {
win.add(Integer.valueOf(String.valueOf(i)));
}
user.retainAll(win);
return user.size();
}
// ๋ณด๋์ค ๋ฒํธ๋ฅผ ํฌํจํ๊ณ ์๋์ง true/false ๋ฐํ
public boolean isContainsBonusNumber(int bonusNo) {
return numbers.contains(bonusNo);
}
}
model.Rank
public enum Rank {
FIRST(6, 2_000_000_000), // 1๋ฑ
SECOND(5, 30_000_000), // 2๋ฑ
THIRD(5, 1_500_000), // 3๋ฑ
FOURTH(4, 50_000), // 4๋ฑ
FIFTH(3, 5_000), // 5๋ฑ
MISS(0, 0);
private static final int WINNING_MIN_COUNT = 3;
private int countOfMatch;
private int winningMoney;
private Rank(int countOfMatch, int winningMoney) {
this.countOfMatch = countOfMatch;
this.winningMoney = winningMoney;
}
public int getCountOfMatch() {
return countOfMatch;
}
public int getWinningMoney() {
return winningMoney;
}
public static Rank valueOf(int countOfMatch, boolean matchBonus) {
if (countOfMatch < WINNING_MIN_COUNT) {
return MISS;
}
if (SECOND.matchCount(countOfMatch) && matchBonus) {
return SECOND;
}
for (Rank rank : values()) {
if (rank.matchCount(countOfMatch) && rank != SECOND) {
return rank;
}
}
throw new IllegalArgumentException(countOfMatch + "๋ ์ ํจํ์ง ์์ ๊ฐ์
๋๋ค.");
}
private boolean matchCount(int countOfMatch) {
return this.countOfMatch == countOfMatch;
}
}
model.Statistics
public class Statistics {
private static final int LOTTO_TICKET_PRICE = 1000;
// ๋น์ฒจ ํต๊ณ ๊ตฌํ๊ธฐ
public static Map<Rank, Integer> getWinningStatistics(List<Lotto> userLotto, WinningLotto winningLotto) {
Map<Rank, Integer> statistics = initStatistics();
registerMatchStatistics(userLotto, winningLotto, statistics);
return statistics;
}
// ์ด ๋น์ฒจ ๊ธ์ก ๋ฐํ
public static int getTotalWinningMoney(Map<Rank, Integer> statistics) {
int totalWinningMoney = 0;
for (Rank rank : Rank.values()) {
int winningMoney = rank.getWinningMoney();
int amount = statistics.get(rank);
totalWinningMoney += winningMoney * amount;
}
return totalWinningMoney;
}
// ์ด ์์ต๋ฅ ๋ฐํ
public static double getTotalYield(double winningMoney, int amount) {
double amountPaid = (amount * LOTTO_TICKET_PRICE);
return winningMoney / amountPaid;
}
// ํต๊ณ ์ด๊ธฐํ
private static Map<Rank, Integer> initStatistics() {
Map<Rank, Integer> statistics = new HashMap<>();
for (Rank rank : Rank.values()) {
statistics.put(rank, 0);
}
return statistics;
}
// ๋งค์น ํต๊ณ ๊ฒฐ๊ณผ ๋ฑ๋ก
private static void registerMatchStatistics(List<Lotto> userLotto, WinningLotto winningLotto, Map<Rank, Integer> statistics) {
for (Lotto lotto : userLotto) {
Rank rank = winningLotto.match(lotto);
statistics.put(rank, statistics.getOrDefault(rank, 0) + 1);
}
}
}
model.User
public class User {
private static final int LOTTO_TICKET_PRICE = 1000;
// ์ฌ์ฉ์ ๋๋ค ๋ก๋ ๋ฆฌ์คํธ ๋ฐํ
public static List<Lotto> getTotalLotto(int count) {
List<Lotto> userLotto = new ArrayList<>();
// ๋๋ค ๋ก๋ ์์ฑ
for (int i = 0; i < count; i++) {
Lotto lotto = RandomLottoNumber.getRandomLotto();
userLotto.add(lotto);
}
return userLotto;
}
// ๋ก๋ ๊ตฌ์
๊ฐฏ์ ๊ณ์ฐ ๋ฉ์๋
public static int getCount(int cost) {
return cost / LOTTO_TICKET_PRICE;
}
}
model.Validator
public class Validator {
private static final String ERROR_COST_MESSAGE = "[ERROR] ๋ก๋ ํ์ฅ ๋น 1000์ ์
๋๋ค.\n1000์ ์ด์, 1000์ ๋จ์๋ก ์
๋ ฅํด ์ฃผ์ธ์. \n";
private static final String ERROR_BONUS_NUMBER_MESSAGE = "[ERROR] 1~45 ์ฌ์ด์ ๋ณด๋์ค ์ซ์๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์. \n";
private static final String ERROR_WINNING_NUMBER_LENGTH_MESSAGE = "[ERROR] 6๊ฐ์ ๋น์ฒจ ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์. \n";
private static final int MIN_LOTTO_COST = 1000;
private static final int MIN_RANDOM_NUMBER = 1;
private static final int MAX_RANDOM_NUMBER = 45;
private static final int LOTTO_COST_REMAINDER = 0;
// ๋ณด๋์ค ๋๋ฒ_๋ฒ์_1~45_์ฒดํฌ
public static boolean isValidBonusNumber(int bonusNumber) {
boolean check = true;
if (bonusNumber < MIN_RANDOM_NUMBER || bonusNumber > MAX_RANDOM_NUMBER) {
System.out.println(ERROR_BONUS_NUMBER_MESSAGE);
check = false;
}
return check;
}
// ๋น์ฒจ ๋ฒํธ split ์ต๋ 6๊ฐ
public static boolean isValidNumberLength(String[] numbers) {
boolean check = true;
if (numbers.length != 6) {
System.out.println(ERROR_WINNING_NUMBER_LENGTH_MESSAGE);
check = false;
}
return check;
}
// ๊ตฌ์
๊ธ์ก ์ฒดํฌ
public static boolean isValidCost(int cost) {
boolean check = true;
if (!(isValidCostMinCost(cost)) || !(isValidCostUnit(cost))) {
System.out.println(ERROR_COST_MESSAGE);
check = false;
}
return check;
}
// ๊ตฌ์
๊ธ์ก_๋จ์_1000์ ๋จ์์ธ์ง
private static boolean isValidCostUnit(int cost) {
return ((cost % MIN_LOTTO_COST) == LOTTO_COST_REMAINDER);
}
// ๊ตฌ์
๊ธ์ก_์ต์๊ธ์ก_1000์์ธ์ง
private static boolean isValidCostMinCost(int cost) {
return cost >= MIN_LOTTO_COST;
}
}
model.WinningLotto
public class WinningLotto {
private final Lotto lotto;
private final int bonusNo;
public WinningLotto(Lotto lotto, int bonusNo) {
this.lotto = lotto;
this.bonusNo = bonusNo;
}
public Rank match(Lotto userLotto) {
int matchCount = userLotto.getMatchCount(lotto);
boolean matchBonus = userLotto.isContainsBonusNumber(bonusNo);
return Rank.valueOf(matchCount, matchBonus);
}
}
'๐ป > Java CleanCode Study' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ช์ฌ๋ค๋ฆฌ ๊ฒ์ # 2022.04.18~2022.05.02 (0) | 2022.06.12 |
---|---|
๐๋ธ๋์ญ ๊ฒ์ # 2022.03.13~2022.04.09 (0) | 2022.06.12 |
Could not find method testCompile() for arguments [{group=junit, name=junit, version=4.12}] (0) | 2022.04.22 |
[ERROR] - Could not find or load main class worker.org.gradle.process.internal.worker.GradleWorkerMain (0) | 2022.02.26 |
[JAVA] test code ์์ฑ๋ฒ (0) | 2022.02.26 |