2021 02 23
2021-02-23
refactoring 하면서 생긴 질문
- scanner는 어디에?
- Application 클래스의 메인 메서드에서 scanner 하나 생성해서 컨트롤러에게 넘겨줌
- View에서 밖에 안쓰이니 private static final?
- 애초에 scanner가 하는게 뭐야?
- util의 범위는 어디까지? util 클래스의 기준?
- util성 클래스란게 애초에 뭔뜻이야?
- 비즈니스 로직이라는건 또 뭔뜻이지?
- LottoResult 같은 경우, LottoBundle과 WinningLotto를 받아서 결과를 Map으로 돌려주도록 했다
- 이유? 우선 static 메서드 하나만 필요한거 같아서 굳이 모델?
- 너무 model에 들어가면 너무 의존적이지 않나 서로서로? (굳이 뭔상관인가 싶긴한데 처음 생각은 그랬음)
- Stream이 어떻게 돌아가지?
- 몇개가 겹치는지 검증하는 로직에서 두 가지 사이 고민
1. Stream으로 filter contains 이후 count
2. 본인 lotto를 복사하여 retainAll메서드 수행후 size() 반환
- 굳이 대놓고 새로운 객체를 생성하는 것 보단 "괜히" stream 생성이 오버헤드가 적지 않을까 싶어서 1번 채택
- stream의 오버헤드는? 얘는 복사 안하나?
- WinningLotto 내에 winningLotto 란 변수 이름 이상한데?
- Stream VS 배열 for?
- 스트림 잘 모르는데 우선 변환에 오버헤드,
- 최종연산하면 재사용못하니까 스트림 두 번 변환해야하고
- sum()은 어찌... 되는지 알아보자
- 대신 스트림이 더 단단해 보이긴하네 뭐랄까 주변에 결과에 영향을 안받아 보이는 군
public double checkProfitRate(final Map<LottoRank, Integer> gameResult) {
final int moneySpent = Arrays.stream(LottoRank.values())
.mapToInt(lottoRank -> SINGLE_LOTTO_GAME_COST * gameResult.get(lottoRank))
.sum();
final int moneyGain = Arrays.stream(LottoRank.values())
.mapToInt(lottoRank -> lottoRank.getPrizeMoney() * gameResult.get(lottoRank))
.sum();
<<<<< VS >>>>>
int spent = 0;
int gain = 0;
for (LottoRank lottoRank : LottoRank.values()) {
spent += gameResult.get(lottoRank) * SINGLE_LOTTO_GAME_COST;
gain += gameResult.get(lottoRank) * lottoRank.getPrizeMoney();
}
return (double) moneyGain / (double) moneySpent;
}
- 짜다보니 돈을 BigDecimal로 하려고했으나,,, GameMoney만 BigDecimal로 하고 나머지 돈계산은 거의 int로 했네
- 지금은 문제가 없어보임...
- 언제 부터 BigDecimal을 써야하고 언제부터 int가 문제가 생기나?
Refactoring 중점 사안
- 메시지에 변수를 섞어 쓸수있으면 써봐라
- 변경에 용이
- Lotto.LOTTO_SIZE vs Lotto.SIZE
- 굳이 의미가 중복된거를 두번쓰지마
- stream() 내부의 람다 표현식 :: 로 대체가능
- 함정은 :: 가 대체 뭔지 모름
- BigDecimal은 값 객체, DTO 대체 가능
- when to use DTO?
- 서로 다른 레이어로 데이터의 getter/setter만을 통해 "운반"에 집중하는 클래스
- BigDecimal 불변객체...?
- 찾아보자