[우아한 테크코스 프리코스 6기 BE] 3주차 회고 - 로또

Haiseong Jeong·2023년 11월 8일
0

늦은 코드리뷰 요청

이번 주 과제의 난이도가 전주보다 올라간 것 같았다. 원래 계획은 코드리뷰를 받아 피드백을 통해 이번주 과제를 진행하는것이 계획이였는데 마음이 급해져 우선 급한 과제부터 하게 되었다. 어느 정도 구현의 끝이 보일 즈음, 코드 리뷰를 더 늦기전에 받아야겠다는 생각이 들었다. 그러나 대부분 과제를 열심히 진행하는 중이라 리뷰를 달아주는 사람은 많지 않았다.

타인의 코드리뷰

다른사람들이 생각하는 정답은 무엇일까 궁금했다. 그래서 다른 지원자들의 코드리뷰를 들어가 주고받은 의견들을 읽었다. 어떤 pr은 30분넘게 코드리뷰를 하여 pr에 들어가는 것 조차 안되고 유니콘이 뜨는 분도 있었다. 몇번 새로고침 후에 pr에 들어가 구경을 할 수 있었다. 정말 많은 분들이 의견을 남겨주신 덕분에 다양한 분들이 의견을 나누는 장이였다. 내가 궁금했던 부분들도 많은 의견을 제시해주셔서 많은 도움이 되었다.

정답

이번주 과제 초반까지 항상 나는 정답인 코드를 만들고자 끊임없이 고민했다. 프리코스 커뮤니티에서 토론하기를 돌아다니며 나와 비슷한 고민을 하는사람들의 토론을 보고 많은 여론이 쏠리는 방향으로 다음주 코드를 개선하고자 하였다. 이것이 뭔가 잘못되었다는것을 알게 되었다.

관점의 차이

사람마다 의견이 갈리는 부분이 많았다. 하나하나 메시지를 읽어보며 내가 한 생각은 사람마다 관점이 다르다는 것이였다. 관점에 따라 다르게 역할이 해석되고 코드의 방향이 달라졌다. 결론적으로 정답이라는게 있는게 아니라 다양한 관점과 그에 따르는 코드라는 결과물, 그리고 거기서 오는 장단점이 있는것이라는 생각이 들었다.

유연한 사고의 필요성

그래서 내가 내린 결론은 지금 프리코스에서 어떻게 코드를 짤것인가 하는 고민은 지금 당장의 코드를 잘짜고 아름답게 짜기 위함도 있지만, 앞으로 프로그래밍 설계와 구현에서의 선택의 갈림길에서 어떤 선택을 할지 미리 고민해보는 연습을 하는 것 같다. 두 길 모두 장점과 단점이 있을 것이다. 이 장점과 단점을 고려하여 프로그래머는 최적의 결정을 내리는 사람이다. 한가지 방법만 고집할게 아니라 유연한 사고로 상황에 맞는 선택을 해야한다는 교훈을 얻었다.

로또

이번주의 미션은 로또다. 이번주 과제가 지난 과제보다 어려웠다고 생각된 이유는 예외상황에서 프로그램을 종료 시키는것이 아니라 정상적인 입력이 들어올때까지 계속해서 입력을 받아야 하는 조건이 있어서 이다. 또한 상금(돈) 에 대한 연산을 하는 만큼 조금 더 신중하게 검증과 예외처리가 필요하다고 생각되었다. (물론 실제돈은 아니지만..)

오버플로우

처음에 총상금을 int형으로 계산하려고 했다. 그런데 1등 상금의 액수를 다시 확인하고 생각이 달라졌다.

1등 : 20,000,000원

1등 상금이 20억이다. 이는 꽤 위험한 숫자라고 생각했다. 왜냐하면 랜덤으로 로또를 뽑았을때 완전히 같은 로또가 나오고 운좋게 이 로또가 1등 판정을 받는다면 40억이 되는데 이는 int형의 범위를 넘어선다.

-2,147,483,648 ~ 2,147,483,647

이는 int형이 4bite = 32bit 중 맨 앞자리를 부호로, 나머지 31자리를 수를 표현하는 데 사용하기 때문이다. 따라서 우리는 int형 보다 큰 범위의 숫자를 담을 자료형이 필요하다. 그것은 long 이다.

-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

이 크기라면 1등 로또가 2^32 개 나와도 오버플로우가 나지 않을 것이다. 로또 하나의 가격이 1000원 (대충 2^10 원) 이다. 2^22개(약 4,000,000개)의 로또가 모두 1등에 당첨될 확률을 피하기만 하면 된다. (완벽한 방어는 아니지만 int형을 사용했을때와 비교하면 일어날 수 없는 불가능한 확률이다.)

그래서 돈과 관련된 값은 long을 사용했다. 또한 만약에 대비하여 다음 메서드를 추가해주었다.

    private static final long MINIMUM_AMOUNT = 0L;
    
	private void validateOverflow(long money) {
        if (money < MINIMUM_AMOUNT) {
            throw new IllegalStateException(OVERFLOW_ERROR_MESSAGE);
        }
    }

만약 오버플로우가 발생하여 음수가 될 경우, IllegalStateException을 throw 한다.

getter에 대한 고민

getter의 사용을 지양하라는 말을 항상 들어왔다. 그러나 프로그래밍을 하다 보면 getter를 사용해야 할 시점이 생긴다. 이번 주 과제를 진행하면서 나름의 기준을 만들어 보았다.

  • getter를 사용할 수밖에 없는가? -> getter 말고 다른 객체에게 메시지를 보낼 방법을 다시 생각해 보자.
  • 정말 정말 getter가 필요한 것 같다. -> getter를 사용하는 목적이 그 객체의 상태를 읽어와 판단하고 어떤 행위를 시키기 위함인가? -> 객체는 자기 자신의 상태에 따라 자율적으로 판단하고 행동할 수 있어야 한다. 따라서 getter를 사용하면 안된다.
  • 객체가 가진 상태가 다른 객체의 행동에 필요해 getter를 써야 하는 상황이다. -> getter를 사용한다. (예를 들어.. Model이 가진 상태를 View가 출력해주어야 하는 경우)

위에서 언급한 출력 예시에서 어떤 분들은 DTO를 만들어 정보를 넘겨주는 방식을 사용하셨다. 나는 그 방법보다는 원시 값을 getter로 받아와 인자로 넘겨주어 출력하는 방식을 사용했다. 과제들에서 Dto를 만들정도의 복잡한 정보를 넘겨주는 일이 없었기 때문이다. 다만, Model의 객체를 바로 View에 넘겨주는 것은 MVC 패턴에서 View가 Model에 의존하게 하는 행위이므로, View에는 원시 값을 넘겨주어 출력하도록 하였다.

출력 메시지를 enum으로 만드는 것에 대한 고민

지난주 코드리뷰를 다니다보니 몇몇분들이 OutputView의 출력 메시지들을 enum으로 묶어 .getMessage() 등의 메서드를 이용해 관리하는것을 봤다. 나는 지금까지 OutputView의 상수를 이용해 관리했다. 이 두가지 방법의 장단점을 비교해봤다.

  • enum을 이용
    • 장점 : OutputView를 깔끔하게 유지할 수 있다.
  • OutputView의 상수
    • 장점 : 출력에 필요한 메시지를 관련 메시지와 가까이에 위치시킬 수 있다.

단점을 적지 않은 이유는 한 방법의 장점을 반대로 하면 다른 방법의 단점이 되기 때문이다.

결론적으로 나는 상수로 관리하는 방법을 택했다. 이유는 다음과 같다.

  • 문자열을 사용하는 클래스에서 메시지를 관리하는게 자연스럽다.
    • 출력 형식을 바꿀때 OutputView가 변경되는것이 자연스럽다. 물론 enum을 사용해도 OutputViewEnum 등의 클래스만 변경하여 나쁘지 않지만 내가 보기에는 전자의 방식이 더 자연스럽다.
  • 메시지가 enum으로 분리되면 메시지를 알 필요가 없는 객체에서도 메시지에 접근이 가능하다. 크게 문제가 되는 상황은 아니지만 좋은 상황도 아니다.
  • 규모가 더 커진다면 해당 enum을 찾기가 어려워진다. 물론 (Command + click)을 이용해 자동으로 파일로 찾아가지만 그럴 수 없는 환경 (vim 등) 에서는 이 파일을 찾기가 어려울 것이다.
  • enum을 쓰는 이유에 대한 생각 : enum은 열거형이다. 서로 관련이 있는 상수들의 집합을 의미한다. 출력 메시지 enum 역시 서로 관련있는 상수의 집합이라고 생각할 수 있지만 내 생각에 여기서 '관련있다' 라는 말의 의미는 '같은 종류'를 의미하는 것 같다. enum의 역할은 허용 가능한 값들을 제한하여 유형 안전(type safe)을 제공하는 역할도 있다. 그러나 단순 메시지 출력을 하는 의도로 enum을 쓰면 이 기능을 쓰지 않는데 그런 의미에서 enum을 쓸 이유가 있나 생각이 들었다.

만약 출력할 메시지가 너무많아 화면을 꽉 채울정도가 된다면 enum을 도입하는것보다 OutputView를 더 쪼개는게 좋지 않을까 생각한다.

바닷가재 이야기


https://www.youtube.com/watch?v=n6lqjBeKq-Q

바닷가재 이야기

스트레스에 대해 여러분께 해줄 말이 있어요.
그리고 이 스트레스를 어떻게 바라봐야 할지에 대해서요.
매우 중요한 문제라고 생각합니다.
강의를 들었던 많은 사람들이 이것만큼은 잊지 못하겠다고 하더군요.

하루는 치과에 앉아 있었습니다.
기사를 읽고 있었는데 '바닷가재는 어떻게 자라나?'에 대한 얘기였죠.
뭐라는거야.. 바닷가재가 어쨌다는 거야.
그러나 곧 관심이 생겼죠.
그들이 말하길, 바닷가재는 연하고 흐물흐물한 동물인데, 아주 딱딱한 껍질 안에서 산다고 했죠.

그런데 그 딱딱한 껍질은, 절대 늘어나지 않는다고 했습니다.
그러면 바닷가재는 어떻게 자라는 것일까요?
자, 바닷가재는 자랄수록 껍데기는 그들을 점점 더 조여옵니다.
그들은 압박을 받고, 아주 불편한 상황에 놓이게 됩니다.
그러면 그들은 포식자로부터 안전한 바위 밑으로 들어갑니다.

그리고 자신의 껍질을 버리고 새로운 껍질을 만듭니다.
그런데 결국 이들이 또다시 자라면 새 껍데기도 불편해지게 되죠.
그러면 다시 바위로 밑으로 들어갑니다.
이 과정을 셀 수 없이 반복하는 겁니다.
바닷가재가 자랄 수 있도록 자극을 주는 것은 불편함을 느끼는 것입니다.

그런데 만약 바닷가재에게 의사가 있었다면 그들은 절대 자랄 수 없을 것입니다.
웬만하면 불편함을 느끼기 시작하자마자 의사에게 달려가서 신경 안정제를 처방받아먹고 다시 기분이 좋아질 테니까요.
절대로 자신의 껍데기를 버리지 않을 것입니다.
우리가 깨달아야 하는 것은
당신에게 스트레스가 일어났을 때, 그것은 당신이 성장할 때가 됐음을 의미한다는 것입니다.

당신이 이 역경을 제대로 이용하다면, 우리는 그것을 통해 성장할 수 있습니다.

이번주는 참 힘들었다. 주말 내내 비가 와서 혼자 집에서 모니터만 보고 있었다. 과제를 하며 혼자 고민할 거리가 너무 많았는데 고민을 하면 할수록 스트레스를 받았다. 이 스트레스를 성장통이라고 생각한다. 이 역경을 통해 한층 성장할 수 있었던것 같다.

커뮤니티를 다시 돌아보다

사실 1주차, 2주차에는 커뮤니티를 잘 활용하지 못한 것 같다. 그러나 이번주 커뮤니티의 힘과 어떤식으로 이용해야 할지를 느낀 주차였다. 물론 스스로 고민하는 시간이 필수적이다. 우테코 멘토님들 역시 그 주의 과제는 스포없이 스스로 해결해볼것을 강조하신다. 하지만 제출이 완료된 코드들에 대해서는 리뷰를 받고 소통하는것이 정말 중요한것 같다. 사실 저번주까지는 어떤식으로 코드리뷰를 봐야 할지도 잘 감이 안오고 그냥 다른사람이 내 코드를 잘 봐줬으면 하는 마음이 컸는데 사실 다른사람의 코드를 읽고 리뷰들을 보는것 만으로도 실력이 많이 는다는게 느껴졌다. 그래서 커뮤니티의 기능을 100% 느껴보는 한주가 되었으면 한다.

마지막 주차도 화이팅

시간이 정말 금방갔다. 벌써 마지막 주차라니. 실감이 안난다. 마지막 주차 과제도 힘내서 열심히 해봐야겠다!!

profile
나는 개발자다. 5000만큼 코딩한다.

0개의 댓글