우아한 테크 코스 6기 - 프리코스 3주 차
부제 : 갑자기 이러시면 당황스러워요 호달달😱
두치팍치 쿵 쿵 치 팍 치 예 ~미션을 확인합시다!
이번주. 일단 다들 독감 조심하세욧
목요일부터 기침이 콜록콜록 나오더니 월요일에는 고열과 후두염,, 사실 지금도 말을 못하는 상황이다.....
진짜 살면서 걸려 본 감기 중 제일 아팠던것같다ㅜㅜ
나는 코로나에 한번도 안걸려서 COVID-19 고통은 모르지만 같이 아팠던 어머니 왈, 로나코가 덜 아프다.
암튼 아파도 우테코에 영혼과 체력과 온몸을 갈아넣었던 다사다난 3주 차!
먼저 미션을 확인했을때 너무너무너무너무넘우 당황했다. 왜냐고? 이젠 예외 발생시키고 프로그램 종료가 아니라 재입력을 받으라네?
그와중에 공통 피드백도 더 다양해지고 요구사항 무슨일이냑우요 흑흑 너무 많아... 진챠 많아...
그 래 도 재밌다고 생각하며 즐 겨 보 자 고 ~ !
과제 시작
하...아파.... 일단 그냥 몸이 너무 아파
과제에 혼신을 불태워도 너무 아파서 진짜 정신을 못차렸다.
오죽하면 전공수업을 빼고 병원을 갔겠냐구요ㅠㅠ 진료확인서로 출석인정해주셔서 다행이지 정말,,
일단 과제를 시작하기 앞서 이번에는 Enum을 적용하는 것이 요구사항 중 하나였다.
하지만 나는야 코린이😎 Enum 들어본것 같긴한데 아무코토 모르지!
일단 같이 자바 스터디하는 스터디원들에게 SOS를 쳤다.
나 Enum 몰롸! 알아야해! 그래서 공부했다. 공부하고 스터디원들에게 설명도 듣고 질문도 주고받고
그 결과 하루만에 Enum 완전 정복..ㅎㅎ
Enum 클래스 만들줄 도 모르던 내가 아주 고냥 이번 과제에서는 자유자재로 Enum을 사용하게 되었다. 아 이럴때 너무 조하~ 뿌듯행!
혹시 Enum에 대해 잘 모르겠다면 아래 블로그 구경해보시길
Enum을 사용한 상수값 관리
열거 타입(Enum Type)의 등장
medium.com
열심히 공부한것들을 토대로 도메인 설계부터 했다.
최종코테때는 시간이 엄청 부족하기 때문에 최대한 구현부터 빨리 하고 패키지 분리를 하는 것이 최선의 순서라고 생각은 하지만 일단 나는 MVC 패턴과 비즈니스 로직에 대해 배우는 마음으로 이번주까지 이런식으로 진행할 것 같다.
열심히 README.md부터 작성하고나서는 구현을 시작했다. 설계대로 패키지 나누고~ 기능별 메서드 작성하고~ 모여라 헤쳐라 둠칫둠칫을 하고나서 실행을 해보니 와~ 이런 개판이 없군요?
service에 view 코드를 넣고, 객체는 넘겨주지 않아 계속 새롭게 생성되고....
이렇게 코드는 무진장 더러운데 하필이면 또 아팠다!
이때가 제일 아픈 날이라 2시간정도 열내고 2시간동안 씻고 정신차리다가
코딩을 이어갔다. 내가 내 머리채를 잡고 일어났다.
역시 사람은 고난을 좀 겪어야 성장을 한다고(?) 아플때 코딩을 하니 너무 잘 풀렸다ㅋㅋㅋㅋㅋㅋ
제정신이 아니라 그런가
어쨌거나 저쨌거나 각 패키지 별 역할을 생각하며 코드를 다시 수정하니 생각보다 쉽게 해결되었다.
근데 다들 그거 알지.. 잘 풀린다 싶으면? 또 엄청난 에러가 나를 기다리고 있다는 것..
테스트를 실행하는데 분명이 내가 실행하는 것에선 잘 됐는데 갑자기 오류가 왜 발생해요..
아무리 코드를 씹고 뜯고 맛보고 즐기진못했지만 계속 보아도 자세히 보아도 잘못된게 없는데ㅜ?
불행 중 다행으로 에러 메시지가 있어 하나하나 읽어보며 코드를 따라갔다.
그리고 도착한 곳은 생성한 로또 번호들을 정렬하는 Collection.sort!!
이 오류에 관련된 자세한 것은 아래 소감문 중 오류 해결 파트에서 작성해놓았다.
진짜 머리아프게 한 오류였지만, 그 원인과 원리를 파악하고 나서 이번 미션 중 가장 의미있는 과정이라고 생각되었다.
그리고 이 기회에 스트림까지 공부를 하게되어 꽤나 유익했다.
개인적인 생각이지만 내 기준 가장 도움이 많이 되었던 스트림 설명 블로그를 아래에 첨부한다.
스트림(Stream)
스트림 컬렉션이나 배열에 데이터를 담고 원하는 결과를 얻기 위해 for문과 iterator를 이용해서 코드를 작성했다. 그러나 이러한 방식은 코드의 독해성이 떨어지고 재사용성도 떨어진다. 또한 Coll
velog.io
진짜 이번 주 정말 역대급이었다ㅜㅜ
잘 버티고 잘 이겨냈어 나 자신!!!!!!!!!!!
진짜 너무 힘들었는데 너무 재밌고 너무 너무 너무 🫠
앞으로도 잘 할 거 야 :)
과제 결과
3주 차 과제 코드는 아래에!
https://github.com/coenfflOo/java-lotto-6/tree/coenfflOo
GitHub - coenfflOo/java-lotto-6: 우아한테크코스 3주차 미션
우아한테크코스 3주차 미션. Contribute to coenfflOo/java-lotto-6 development by creating an account on GitHub.
github.com
확실히 저번 주 부터 문제 난이도가 슬슬 상승한 탓인지 이번 fork 수는 2.2K, pull request 수는 2046이였다.
아파도 가능한 시간에 미친듯이 집중하고 공부한 덕에 2주 차보다는 여유롭게 제출했지만 왜일까? 이 뭔가 말할 수 없는 찝찝함은...
자꾸 뭔가 아쉽고 부족한 것 같다.
이런 나.. 제법 노력형 (예비) 코딩 천재같아요..ㅎ
이제 벌써 한 주 밖에 안남은게 믿겨지지 않지만 남은 한 주 미션을 해결하면서 더 성장해봐야겠다!
ㅇㅏ악 아쉬워~~~ 4주 차 꽃을 피워보게따! (꽃향기만 남.기고 갔.단다. 뚬두두뚜두두둔뚜두둥뚜두)
이번주 소감! 사실 여기 적은건 되게되게 많은데 소감문 제출 분량이 5000자 이내라서 조금 날리고 올렸다..ㅎㅎ
🤑 소감
벌써 3주 차라니.. 믿기지 않으면서도 시간 참 빠르다 싶은데, 그 짧고도 빠르게 흐른 시간동안 성장한 제가 너무나도 느껴져 뿌듯하기도하고 아쉽기도 합니다. 더 좋은 코드로 구현해보고, 더 많은 예외들을 찾아보고, 피드백의 내용을 모두 받아들이려 노력했는데 저의 고민의 흔적들이 코드에 잘 담겼을 지 모르겠습니다. 특히나 이번주에는 고열과 후두염으로(다들 독감조심하세요..) 누워있으면서도 코드 생각을 하다가 갑자기 번쩍!하고 코드의 답이 생각이 나 아픈 몸을 이끌고 노트북을 열어 코드를 수정한 기억이 추억으로 남게되었습니다. 제가 언제 또 이렇게 열정적일 수 있을까요ㅎㅎ 유독 이번 주의 요구사항이 다양하게 추가되어 더 어렵고 힘든 한 주 였지만 그만큼 더 알찬 3주 차였습니다.
☻ 잘한 점 & 배운 점 & 알게 된 점
☁️ Enum은 처음인걸?
- 정말 No-Base 에 가까웠기 때문에 Enum의 정의부터 공부했습니다.
- 일단 Enum을 적용하라는 요구사항이 주어졌을 때 살짝 절망감을 느꼈습니다. 언젠가 만나겠지라는 생각은 했었으나 벌써 나올지 몰랐을 뿐더러, 제가 Enum에 대한 지식이 거의 ‘없을 무’에 가까웠기 때문입니다. 그래서 자바 스터디에 이 주제를 공부해서 이야기를 나누기로 했습니다.
- Enum에 대해 구글링도 하고 자바 책들도 찾아보며 공부한 뒤 스터디원들에게 공부한 것에 대해 설명하고, 각종 피드백과 질문을 받으며 토론하는 시간을 가졌더니 짧은 시간에 Enum에 대한 개념뿐만 아니라 사용법까지 숙지하게 되었습니다.
- input,output, validation에는 입출력과 유효성 검사 시 사용하는 메시지들을, Number와 Result에는 각각 로또에 필요한 상수들, 결과 상금과 관련된 상수들을 포함했습니다.
- Enum에 대해 공부를 한 뒤 어떻게 이 Enum이라는 클래스를 적용시키는 가에 대해 고민을 했습니다. 그래서 정말 많이 사용되거나 오타 방지가 필요한 데이터들을 Enum으로 만들어야겠다는 생각을 하게되었습니다.
- 다른 기능들을 구현하면서 최대한 매직넘버를 제거하고 싶었는데 Enum에 들어가기엔 애매하다고 판단된 값들은 해당 클래스에서 private static final로 상수로 처리했습니다.
- Enum 클래스를 생성할 줄 도 몰랐는데 프리코스를 통해 많이 성장중입니다.
- Enum 클래스를 일반 클래스에서 Enum으로 선언하여 사용해야하는 것인줄 알았던 제가 Enum에 대해 개념을 확립하고 프로젝트 내에서 자유롭게 사용할 수 있게된 점이 정말 놀랍습니다. 매 주차마다 새로운 요구사항이나 개념에 대해 공부할거리가 생기고 그 공부하는 과정이 즐거워서 프리코스가 끝나가는 것이 아쉬울 정도입니다.
☁️ 매주 고민되는 도메인 설계
- 그래도 이번엔 도메인 설계에 1.5시간..!
- 이번에는 ‘constant’와 ‘util’이라는 패키지를 추가하여 구현했습니다. constant에 enum 클래스들을, util에 유효성검사와 번호 생성기능을 포함시키면 되겠다고 생각하였고 결과적으로 constant, domain, controller, service, util, view의 패키지로 이루어지게 되었습니다.
- constant, controller, domain, service, util, view가 각각 어떤 역할인지에 대한 고민은 계속되었습니다.
- 이 부분에 대해 다른 스터디원에게도 질문을 많이 받았습니다. 그래서 지난 주에 공부했던 mvc 패턴과 제가 구현한 코드들을 다시 살펴보며 정답은 아니지만, 제 나름대로의 역할을 부여해보았습니다.
- 먼저 constant는 자주 사용되는 변수들을 저장하는 곳이라고 생각하여 enum 객체들을 모두 두었습니다. controller는 프로그램의 전반적인 진행을 담았습니다. domain에는 프로그램을 구현하는 데에 필요한 객체들과 그 객체들과 관련된 데이터를 관리하는 기능 정도만 담았습니다. service에서는 domain의 데이터들을 가공한다는 느낌으로 프로그램에서 원하는 값들을 얻을 수 있는 메서드들을 구현했습니다. util에는 유효성 검사 메서드들과 입력받는 메서드, 랜덤 수를 발생시키는 메서드와 같이 데이터를 생성하는데에 사용하는 역할이라고 생각하며 구현했습니다. 마지막으로 view에서는 입출력을 구현했는데 이번에는 이전 미션들과는 다르게 입력부분에서 파라미터를 사용하여 코드의 재사용성을 높여보았습니다.
- 코드 리뷰가 너무 기대됩니다.
- 이렇게까지 패키지를 분리해본 것은 처음입니다. 지난 주 코드 리뷰들을 참고하여 따라하듯이 설계를 해보았는데 제 나름대로는 만족스럽지만 다른 분들이 보시기엔 어떤것들이 부족하고 아쉬운지 궁금합니다. 프리코스에도 실력자분들이 많아서 매운 리뷰와 이를 통해 성장할 4주차가 더 기대됩니다.
☁️ public과 private 적절히 활용하기
- 지난주 미션에서 가장 아쉬웠던 부분이었습니다.
- 지난 주 구현과정에서 public과 private에 대한 구별없이 너무 무분별하게 사용하여 코드 리뷰로 지적은 받은 전적이 있습니다. 그래서 이번에는 구현 시작부터 끝까지 public과 private을 최대한 생각하며 구현하려고 노력했습니다. 다른 클래스에서도 사용되는 메서드는 public으로, 다른 클래스에서 사용되지 않지만 동일한 클래스 내에서 다른 메서드에 사용되는 것들은 private으로 구현하였습니다.
- protected와 default도 사용해보고 싶습니다.
- public과 private 외에도 같은 패키지 안의 모든 클래스와, 다른 패키지의 자식 클래스에서 접근이 가능한 protected, 접근 지정자가 없을 시 같은 패키지 안의 클래스에서만 접근이 가능한 default(생략) 접근제어자가 존재합니다. 하지만 한번도 사용해본 적이 없어서 언젠가 이러한 접근 제어자들까지 다양하게 활용할 수 있는 프로그래머가 되고싶다는 생각이 들었습니다.
- 접근 제어자를 다양하게 사용하면 캡슐화와 안정성, 테스트 용이성이 더 높아지지 않을까 하는 기대가 됩니다.
☺︎ 오류 해결
🌩️ 불변의 테스트 코드
- 모든 코드들을 구현한 뒤에, 우테코에서 제공해준 테스트를 돌렸습니다. 다른 테스트들은 모두 통과가 되었는데 기능 테스트에서 계속 실패했습니다. 처음에는 코드에 문제가 있는가하여 코드를 다시 뜯어보고, 따로 실행도 해보았습니다. 하지만 전혀 문제를 발견할 수 없었습니다. 그래서 어디서 오류가 났는지 알아보기 위해 상세 페이지를 확인했습니다.
- 오류 코드를 하나하나 해석하며 오류가 발생한 코드 줄을 따라가니 구매하여 생성된 로또번호들을 정렬하는 코드에서 최종적으로 오류가 발생했다고 나타나있었습니다. 처음엔 문제가 발생하는 코드를 확인하면 금방 해결할 줄 알았는데 아무리 고민해도 Collection.sort가 왜 문제인지 이해가 가지 않았습니다. 그래서 다시 오류 코드를 읽어보았고 거기서 놀라운 내용을 발견했습니다.
- 제가 실행했을 때 생성되는 리스트들은 가변이 가능하여 Collection 클래스로 정렬이 가능하지만 테스트 코드의 경우 정해져있는 리스트들을 담기 때문에 불변의 객체라는 것이었습니다.
- Collection.sort()를 사용하려면 리스트가 수정 가능해야 하고 리스트가 변경되기 때문에 원래의 순서가 유지되지 않습니다. 하지만 Stream.sorted().toList()의 경우엔 스트림을 이용하여 정렬된 새로운 리스트를 생성하고 원본 리스트는 변경되지 않습니다. 새로운 정렬된 리스트를 얻을 수 있어 기존 리스트는 원래 순서가 보존됩니다.
- 이 문제를 해결하기 위해 몇시간을 공들인 만큼 허무하지 않고(?) 꽤나 의미있는 지식을 얻게되서 고민한 시간이 아깝지 않았습니다.
🌩️ 의존성 그게 뭔데 날 울려..
- 도메인 설계대로 구현한 뒤 실행을 했을 때 아주 그냥 ‘개판’이었습니다. 패키지 분리는 정말 잘했지만 내부의 코드들을 구현을 하면서 의존성이 완전히 높아졌고 서로 사용하는 객체에 대한 정보를 주고받지 못해 자꾸 새로운 객체를 생성한다는 것이 가장 큰 문제점이었습니다. 그래서 구현한 코드들을 다시 읽어보며 어디서 어떤 객체의 데이터가 필요한지부터 파악했습니다.
- 의존성을 낮추기 위해 메인에서 필요한 객체들을 생성하고 생성한 객체들을 컨트롤러 클래스의 생성자로 넘겨주었습니다. 그리고 컨트롤러의 객체에 전달받은 값을 할당하였습니다. 컨드롤러에서 선언된 객체들로 값들을 주고받게끔 수정하고 service 패키지 내에 구현된 입출력관련 코드들은 모두 제거하여 view 패키지 내의 클래스로 이동하였습니다.
- 위에서 작성했듯 각 패키지마다의 정리한 역할을 생각하며 코드를 수정하였더니 훨씬 쉽게 코드를 파악할 수 있었습니다. 코드의 의존성을 정리하면서 데이터 공유도 자연스럽게 수정할 수 있었고 모든 기능이 잘 작동되게 되었습니다. 제 개인적인 생각으론 구현하는 단계에서 기능 구현에 중점을 두고 컨트롤러는 나중에 작성하다보니 구현 순서를 제대로 파악하지 못해 생긴 상황이라 판단되었습니다.
- 지난 주에도 이러한 점들이 신경쓰여 이번에는 최대한 컨트롤러를 우선적으로 구현하며 기능들도 구현해야겠다고 생각했지만 어떤 메서드가 필요한지 파악하지 않은 상태에서 컨트롤러를 구성하는 하는것이 저에겐 꽤 어려운 일이었습니다. 다음 미션때에는 하나의 기능을 구현하고 그 기능에 대한 컨트롤러를 함께 구현하는 방식으로 의존성과 데이터 공유에 집중하여 구현을 해봐야할 것 같습니다.
☹︎ 아쉬운 점
유효성 검사를 하여 예외처리를 하는 과정에서 해당 예시가 어떤 예외를 가지는지 먼저 체크하고 정리하고 시작했어야했는데, IllegalArgumentException으로 먼저 다 처리구현을 한 뒤 나중에서야 확인을 하고 수정하는 바람에 모든 예외들이 명확한 유형을 처리하고 있는지에 대한 확신이 없습니다. 뿐만아니라 이번엔 예외 처리 후 재입력까지 받아야만 했는데, 유효성 검사에서 그 부분을 구현했고 재입력부분을 유효성 검사 클래스에서 추가적으로 구현하다보니 너무 복잡하게 구현했나 라는 생각도 들어 예외 확인과 예외 처리에 대해 더 공부가 필요하다고 느껴졌습니다.
살아있는 문서 만드는 것 역시 목표 중 하나였는데, 처음부터 모든 도메인을 설계하고 그에 맞춰서 구현을 하게되다 보니 살아있는 문서를 만들지 못한 것 같아 아쉬움이 많이 남습니다. 물론 예외처리를 하거나 구현을 하면서 잘못 생각한 부분들에 대해서는 수정을 반복하며 구현을 진행하긴 했지만 README.md에 대한 파일 수정이 적었던 것 같아, 살아있는 문서를 만든다는 것에 대해 어떤 식으로 문서를 작성해야하는지에 대해 고민을 하게 된 계기가 되었습니다.
Enum 외의 매직넘버들의 상수 처리 과정에서 한가지 아쉬운점은 사용성이 매우 적거나 클래스 내부에서만 사용되는 상수의 경우 static이 꼭 필요한가라는 의문이 들었는데 static을 사용하지 않으면 지역변수로 변환되어 고민 끝에 static변수를 사용했다는 점입니다. 매직넘버의 경우 수정을 하려면 해당 메서드를 찾아 수정해야하지만 상수로 지정해둘 시 클래스 상단에 위치한 상수값만을 수정하면 된다는 점이 편리하여 사용된다고 판단했기 때문입니다. static에 대해 더 공부를 해야겠다는 생각이 들었습니다.
'공log > [WoowaTC]' 카테고리의 다른 글
[우아한 테크 코스] 최종 코딩 테스트 후기 (0) | 2024.01.18 |
---|---|
[우아한 테크 코스] 6기 프리코스 4주차 (0) | 2023.11.16 |
[우아한 테크 코스] 6기 프리코스 2주차 (1) | 2023.11.02 |
[우아한 테크 코스] 6기 프리코스 1주차 (1) | 2023.10.26 |
[우아한 테크 코스] 6기 준비 시작! (0) | 2023.10.19 |