Skip to content

Conversation

@ha0day
Copy link

@ha0day ha0day commented Dec 12, 2022

No description provided.

ha0day added 30 commits December 1, 2022 23:19
 - 남은 투입금액 계산
- 남은 상품 수량 계산
- 남은 금액이 남은 상품의 최저 가격보다 적은 경우
- 모든 상품이 소진된 경우 잔돈 반환
Copy link

@juno-junho juno-junho left a comment

Choose a reason for hiding this comment

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

사실 저는 어떻게 하셨나 궁금해서 봤는데 예외도 엄청 꼼꼼히 체크하시고, 그 자신만의 논리 체계가 있으신것 같아요
사실 뭐 진행한 프리코스에 대해서 정답이 있는 구조가 있는 것도 아니고, 어떻게 구현하셨는지가 메서드를 한가지 역할을 하도록 분리해라, 메서드와 변수명을 명확하게 하라 같은 리팩토링 기술보다 훨씬 중요하니까요. 역시 전공자답습니다 ㅋㅋ
그 특히나 마지막에 동전 Math.min으로 할수 있다는게 왜 전 생각을 못했는지 모르겠어요 ㅋㅋ

역시 코드 보니 저는 5시간 내에 최대한 빨리 구현하려고 해서 빼먹은 부분이 많이 보이네요
하영님 최종 코테 준비만 하면 될것 같습니다ㅋㅋ

public static void main(String[] args) {
// TODO: 프로그램 구현
VendingMachineController vendingMachineController=new VendingMachineController();
vendingMachineController.setVendingMachine();

Choose a reason for hiding this comment

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

main 메서드에서 set -> runVendingMachine() 이라는 함수를 통해서 어떻게 보면 두가지 일을 하고 있는것 같아요. 코드를 봤는데, controller에서 run메서드 실행 전에 set은 반드시 되어야 하니까 run 메서드 안에서 setVendingMachine 메서드를 호출하는 방식이 좋지 않을까 생각해봐요!

private static int amountOfInput;

public void setVendingMachine() {
balance = new Balance(InputView.readBalance());
Copy link

@juno-junho juno-junho Dec 12, 2022

Choose a reason for hiding this comment

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

그리고 static을 통해 클래스 변수로 지정하신 특별한 이유가 있나요?
balance를 인스턴스 변수로 선언하고 setter를 통해서가 아니라 생성자를 통해서 this.balance = new Balance(InputView...) 로 설정해주면 setVendingMachine 메서드를 없앨수도 있을것 같아요.

static 변수(클래스 변수)를 피해야 하는 이유는 여러가지지만 제가 명확히 기억하는 것은 2가지 인데,

  1. 사용하지 않더라도 프로그램 시작과 끝까지 메모리 내에 존재해 메모리 효율성이 떨어진다.
  2. 동시성 문제를 고려해줘야 한다. -> 한 클래스에 여러 곳에서 접근해 로직을 실행하는 도중 다른 곳에서 또 접근한다면 thread safe하지 않은 문제가 발생해서 Map도 ConcurrentMap 타입을 사용하는 것으로 저는 알고 있어요!
    추가적인 자료는 구글에 찾아봐도 나오지만 첨부해 두겠습니다!
    static 사용을 피해야 하는 이유

**추가
InputView랑 OutputView를 생성자로 받아 생성한다면 STATIC 메서드를 없앨 수 있을거같아요


다시 보니 setVendingMachine이 자판기 설정을 하는 메서드네요.. 나름 의미가 있는 메서드라는걸 코드 보면서 느꼈습니다. 단순히 객체를 초기화해주는게 아니었네요 (자판기 보유 동전 설정 + 상품 설정 역할을 하네요..)

this.message = message;
}

public String fullMessage() {

Choose a reason for hiding this comment

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

getMessage라 해도 괜찮을것 같아요!
메서드는 동사로 만드는게 의미 전달에 좋을것 같아요.
fullMessage대신 getFullMessage라 하는게 좋지 않을까요?


public static int validateBalance(String input) throws IllegalArgumentException {
int balance = validateNum(input);
validateNegative(balance);

Choose a reason for hiding this comment

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

저는 음수인것을 validate를 안해줬네요 ㅎㅎ

public static int readAmountOfInput() {
System.out.println(AMOUNT_OF_INPUT.fullMessage());
try {
return validateAmountOfInput(Console.readLine());

Choose a reason for hiding this comment

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

저는 투입금액 도 10으로 나눠 떨어지는것 validate를 해줬는데 꼭 해줘야할 필요는 없는것 같네요 ㅋㅋ

}
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
saveProducts();

Choose a reason for hiding this comment

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

저는 다시 입력 받는것 또한 빼먹었네요..

Copy link
Author

Choose a reason for hiding this comment

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

다시 입력 받는 게 매우 귀찮은 부분이었죠..하하


public void runVendingMachine() {
while (canBuy()) {
buy();

Choose a reason for hiding this comment

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

이렇게 받으면 buy()애서 구매할 상품명을 입력 먼저 받고 아래 OutputView.printAmountOfInput(amountOfInput); 통해서 투입금액이 출력되지 않나요? 순서가 바뀐것 같은데 실행은 잘 되시나보네요

그 위에서 한번 출력을 하고 시작하네요

import static vendingmachine.model.Validator.validateNum;
import static vendingmachine.model.Validator.validatePrice;

public class Price {

Choose a reason for hiding this comment

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

따로 클래스 뺀 이유가 있으신가요? Product안에서 int로 처리해줘도 될것 같은데 특별한 이유가 있는지 궁금해요

Copy link
Author

@ha0day ha0day Dec 13, 2022

Choose a reason for hiding this comment

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

특별한 이유가 있다기 보다는 얼마 전에 원시 타입 포장 관련 글(https://tecoble.techcourse.co.kr/post/2020-05-29-wrap-primitive-type/)을 보고 처음 설계할 때 적용해 보려고 분리를 했었는데..
리팩토링 하다 보니 결국 검증 과정도 Validator 클래스로 다 넘겨서ㅋㅋㅋ 저도 끝에는 굳이 분리할 필요가 있었나 생각하긴 했어요ㅎㅎ

private final int balance;
List<Integer> numbers = new ArrayList<>();
private final Map<Coin, Integer> coins = new EnumMap<>(Coin.class);
private final Map<Coin, Integer> changeCoins = new EnumMap<>(Coin.class);

Choose a reason for hiding this comment

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

오 이런게 있는 줄 몰랐어요 ㅋㅋ 저는 LinkedHashMap 써서 Coin enum 순서대로 넣어줬거든요

Copy link
Author

Choose a reason for hiding this comment

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

저도 처음 써봤어요ㅋㅋㅋㅋ 오히려 LinkedHashMap은 한번도 안 써봤네요..

for (Coin coin : Coin.values()) {
int numberOfBalanceCoin = coins.get(coin);
int neededCoins = change / coin.get();
int inputCoins = Math.min(neededCoins, numberOfBalanceCoin);

Choose a reason for hiding this comment

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

전 왜 이 생각을 못했죠
사실 이거 어떻게 구현하셨는지가 제일 궁금했는데 진짜 간단하게 하셨네요

전 neededCoin과 numberOfBalanceCoin 을 if문으로 경우 나눠서 처리해줬거든요

Copy link
Author

Choose a reason for hiding this comment

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

조금이라도 도움이 되었다니 다행이에요!

@juno-junho
Copy link

juno-junho commented Dec 12, 2022

하영님 혹시나 해서 하는 말인데 저는 자판기 미션 구현한게 리팩토링도 거의 안했고, 정말 한 7시간? 정도만에 테스트 통과되게끔만 만든거라서 코드가 너무 지저분해요.
그래서 제가 봐줬다해서 똑같이 안봐주셔도 되요 ㅋㅋ 제가 하영님 코드를 보고 싶었던 거지 제 코드를 봐달라고 한게 아니니 진짜 신경안쓰셔도 됩니다!

민정님이랑 같이 하영님을 맨 처음 봐서 그런지 잘 되셨으면 좋겠다는 마음이 커요 ㅋㅋ 그리고 하영님은 지금까지 꼼꼼하게 잘 하시는거 같아서 저는 합격하실거라 믿어의심치 않습니다! (심지어 stream 없이 10줄 규칙을 지키신거면 진짜 대단하다 생각해요)
아마 화요일 오늘은 제가 못올거고 수요일 부터는 안나오실수도 있다고 말씀하셨으니 아마 스벅에 모이는건 마지막이 될수도 있을것 같아 리뷰로 대신 전달해드려요!

리펙토링 하다 테스트가 깨지는 경우가 있다고 했는데, intellij가 사용하는 기능을 통해서 리팩토링을 하시면 오류 범위를 낮추실수 있을거에요.

메서드 분리 하고 싶은 부분 : ctrl + alt+ m (extract method)
return으로 합치기(inline) -> ctrl + alt+ n
상수(public static)로 빼기 : ctrl + alt+ c
변수로 빼기 : ctrl + alt+ v
분리하고 싶은 부분을 드래그해서 오른쪽 마우스 -> refactor 누르시면 리팩토링 기능이 있어요. ctrl + alt+ m 통해서 메서드 분리하시면 10줄 규칙 지키시는 것도 크게 문제가 되지 않을거에요

추가적으로 제가 자주 쓰는 intellij 단축키는
ctrl + e -> enter 누르면 바로 전 작업하던 페이지로 넘어가요!
ctrl + alt+ L : 코드 자동 정렬
ctrl + alt+ O : 불필요한 import 정리 (사용하지 않는 import 삭제)
메서드 호출 괄호 ( )안에 커서 놓고 ctrl + p 누르면 어떤 parameter 요구하는지 쉽게 알 수 있어요
try catch로 감싸고 싶은 부분 드래그 -> ctrl + alt+ t -> 6 번 누르면 자동으로 감싸져요
(F6으로 변수명 한번에 변경하시는건 아시죠?)

이번 기회를 통해서 만날수 있게 되어서 정말 반가웠고, 주변에 같이 준비하는 사람 한명 없이 혼자 개발공부를 해오면서 정말 혼자 사막 위를 걷는 기분이었는데, 전 스터디 시작하고 정말 삶이 즐거워 진것 같아요.
우테코 합격 여부를 떠나서 나중에 취업해서도 어차피 비슷한 일을 하고 살것이기 때문에 이번이 끝이 아니라 앞으로도 잘 알고 지냈으면 좋겠어요 ㅎㅎ
비록 월요일(어제) 본게 마지막이 될수도 있겠지만 아니길 바래봅니다! 수요일날 1차 합격하고 봐요! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants