이번 4주차 과제는 지난 3주간의 기존 과제와는 달랐다. 지난 3주의 과제는 작년 프리코스에 나왔던 과제로 레퍼런스들이 상당했지만, 이번 과제는 완전 새로운 과제가 나올 것이 예상되었기에 1주일이 모자랄 수도 있겠다는 생각이 들었다.
https://github.com/Youthhing/java-christmas-6-Youthhing
GitHub - Youthhing/java-christmas-6-Youthhing
Contribute to Youthhing/java-christmas-6-Youthhing development by creating an account on GitHub.
github.com
역시나, 새로운 과제 크리스마스 프로모션 과제가 나왔다. 나온건 나온건데 기능 요구사항이 이전과 달랐다.
비즈니스팀의 개발 요구사항을 이메일 형식으로 정의한 것으로, 개발자가 쓴 개발을 위한 요구사항이 아닌 기획팀이 쓴 글이었다. 정리되지 않은 글이다보니 가장 먼저 걱정되었던 것은 놓치는 요구사항이 있으면 어떻게 하지? 라는 생각이었고 요구사항 분석을 더 꼼꼼히하려고 노력했다.
4주차 목표
기능 개발 순서에 대해 고민하자.
3주차 과제를 마친 코수타에서 기능을 분리하고 핵심 기능부터 구현하도록 노력해보란 조언을 들었다. 객체에 대한 분리를 고민하고 있는 상태에서 사용자의 흐름에 따라 기능을 개발하면, 이전 기능이 완료되어야 다음 기능이 정상작동한다면 그것은 객체 분리가 제대로 되지 않았다는 생각이 들었다.
따라서 도메인의 핵심 기능에 대한 고민을 했고 핵심 기능은 `할인`과 `주문`이었다. 따라서 주문한 메뉴 목록 개발부터 집중했고 메뉴 -> 날짜 -> 할인 순서로 기능 개발을 진행했다.
설계
나는 문제 해결에 초점을 맞춰 생각하기로 했다. 내가 해결해야하는 문제와 목표부터 정의했다.
오히려, 비즈니스팀에서 온 메일을 보니 과제라는 느낌이 덜 들어서일까, 목적이 명확해보였다. 크리스마스에 할인 이벤트를 하려고 하는데 요구사항에 맞는 프로그램을 보여달라. 즉, 12월 우테코 식당 크리스마스 이벤트에 따른 할인 혜택을 보여주는 시스템 개발이었다.
이어서, 지난 3번의 과제와 비슷하게 나만의 개발 문서를 정리했다. 요구사항을 문장으로 정리하고 관련 있는 부분으로 묶었는데 이 과정에서 도메인 분리가 잘 되었던 것 같다. 방문 날짜 , 주문 메뉴, 할인 혜택, 이벤트 배지등이 나왔고 예외로 신경써야할 내용까지 정리할 수 있었다.
이후 작성해야할 기능은 크게 연연하지 않기로 했다. 큰 틀에서만 정리를 하고 빠르게 개발을 진행했다. 돌아가는 쓰레기라도 만드는 것이 더 중요했기에, 기능은 위에서 생각한 도메인 별로 간단하게만 정리했고 실제 개발 과정에서 많은 수정이 있었다.
이어서, 개발 순서에 대한 고민을 했다. 메뉴 목록은 나와있었고, 핵심 기능은 당연히 주문과 할인이었기에 주문한 메뉴 목록부터 개발하자고 생각했다. 할인을 먼저 개발하지 않은 이유는 기능 테스트를 위해서였는데, 테스트 코드를 작성할때 메뉴 주문이 가능해야하지 않을까?라는 생각에 주문을 먼저 개발했다.
나중엔 이 부분이 조금 아쉬웠는데, 할인에 더 초점을 두고 주문 목록은 더미데이터들 사용하는 방법도 있지 않았을까 싶다. 필드에서 최소한의 기능만 만들고 테스트 코드를 리팩토링하는 방법도 있지 않았을까 싶긴한데... 어렵다. ㅎㅎ
사실, 요구사항 분석에서 더 집중해서일까? 문서 정리 틀을 잘 잡아서일까? 지난 3주보다 요구사항 및 기능 정리하는게 편했다.
구현
주문 목록 관리를 어떻게 하지: 일급 컬렉션
입력된 값을 적절히 파싱해서 주문 목록을 받고 나면 이를 관리해야한다. 이때 주문한 메뉴와 개수를 관리해야하는데 이를 어떤 컬렉션을 써서 관리할까에 대한 고민이 있었다.
1. List를 활용한 방법
같은 메뉴를 여러개 주문할 수 있었기에 List에 다 담아서 관리하는 방법을 먼저 생각했다. 중복된 값이 들어갈 수 있었기에 여러 메뉴를 주문해도 상관없지 않을까? 라는 생각이었다.
해당 방법을 사용하면 Stream을 활용해 총 주문 금액을 찾기 수월했다. 하지만 최종 출력 때 특정 메뉴의 개수를 찾을때에는 분류해서 count하는 로직을 짜기 어려웠다.
2. Map을 활용한 방법(사용)
`주문한 메뉴`에 대한 요구사항은 디저트와 메인 메뉴의 개수, 주문 내역의 총 금액, view에 출력을 위한 값을 전달하는 방법이 있었다. 우선, 주문 메뉴당 개수를 나타내는 것이 적절했다. 이후의 요구사항은 Map의 keySet과 values를 적절히 활용하는 방법을 통해 해결할 수 있었기에 최종적으로 Map을 선택했다.
private, public
주문한 메뉴 목록(Menus)에는 최종 주문한 메뉴 목록이 있었는데 요구사항에 `주문한 메뉴의 총 개수가 20개가 넘으면 안된다.`라는 내용이 있었다. 따라서, 주문 목록에서 Menu개수를 카운트하는 기능이 필요했는데, 이 기능의 활용은 검증하는 용도 밖에 없었다.
클래스 검증하는 validate함수는 생성자 내부에서 선언을 많이 하는데 그 외에는 딱히..? 쓸 필요 경우가 없었다. 그렇다면 이를 private으로 선언해도 되지 않을까? 하는 생각과 기능인데 테스트를 위해선 public으로 선언해야하지 않을까? 하는 고민이 되었다.
고민끝에 외부에서 사용하지 않는 메서드를 public으로 두기보단, private으로 두고 생성과정에서 제대로 에러가 나는지를 테스트하는 것으로 방향을 잡았다.
하지만, 이러한 경우엔 객체 분리를 제대로 하지 못할 경우가 높다는 이야기를 많이 들었는데.. 어떻게 나눌지 잘 모르겠다.
매직넘버 어디까지 분리하지?
이번엔 Enum을 조금 더 잘 사용해보고 싶었다. 연관성이 있는 값들은 Enum으로 묶어서 사용하자는 점, Enum으로 묶어서 한 곳에서만 관리할 수 있다는 점 등이 있었다.
우선, 에러메시지에 대한 고민이 있었다.
위와 같이 Enum을 활용한 에러메시지를 만들었는데, 이렇게 되면 `IllegalArgumentException`의 파라미터로 메시지를 넘겨줄때 getter를 써야해 코드가 길어지는게 불편했다.
에러메시지는 연관된 로직이 없으니 상수 클래스를 활용하는 것이 더 좋았을 것 같다.
또한, Menus, Discount등 여러 도메인에서 매직 넘버가 많이 존재했는데 어디까지 빼야할까? 에 대한 고민이 있었다.
경우에 따라 반환할 0, 주문 메뉴 제한 개수 등 아래와 같은 부분도 빼야할까 싶었다.
그래서 최종적으로 빼지 않았는데 코드리뷰에서 이야기가 나왔다. 매직 넘버를 상수화하는 기준이 있을까?
이야기를 마치고 나서 다시 한 번 매직넘버를 분리하는 이유에 대해 정리해봤다.
1. 의미를 알기 쉽다.
2. 변화가 생겼을 때 수정에 용이하다.
반대로 이런 글도 봤는데 변화에 용이한가, 의미를 명백하게 드러내야하는가에 초점을 맞춰 매직 넘버를 분리해야겠다.
final 어디까지 사용하지?
도현님이 공유해준 유튜브 자료에 final 키워드를 어디까지 작성할까? 에 대한 영상을 봤다. 그럼에도 마지막에 여기까지 사용해도 될까? 에 대한 고민이 들었다. final을 재할당을 방지하기 위한 키워드임을 생각하고 원시타입이 아닌 참조타입이 변수로 넘어가는 경우엔 final을 파라미터에 넣었는데 하하
통일성 있게 다 넣는것이 옳았던 것 같다. 원시타입이라고해서 재할당이 안되는게 아닌데..
책임 분리에 대한 아쉬움
public boolean canPresent() {
return calculateTotalMoney() >= 120000;
}
Menus 클래스에 위와 같은 코드를 작성했다. 증정 가능 여부를 판단하는 코드인데, 최종 금액이 12만원을 넘으면 해당 주문 목록은 증정이 가능하다는 내용이다. 이 내용은 할인과 주문 목록중에 할인에 더 가까운 내용이었던 것 같다.
`calculateTotalMoney`가 이미 클래스에 있으니 Discount에서 아래와 총 주문 금액을 확인하고 증정 여부를 구분하는 것이 더 옳지 않았을까 하는 생각이 든다.
프리코스 최종 후기
1. 자바 진짜 중요하다.
프리코스를 진행하며, 아 이런 메서드.,,,있었는데 뭐지? 하면서 참고하는 자료들이 많았다. 특히 Map을 사용하는 과정에서 merge함수나 LocalDate등 메서드 사용 방법이 어색했다. 이러한 부분을 최종 코테에서 활용하려면 자바 공부 많이해야겠다.
2. 네트워크가 있다는게 너무 좋다.
비슷한 고민을 하며 노력하는 분들이 커뮤니티에 있다는 사실이 너무 도움이 됐다. 과제를 하며 느낀 고민에 대한 생각을 같이 공유하고 나누면서 많은 성장을 할 수 있었다. 좋은 코드를 작성할 수 있음에 대한 자신감이 높아졌다.
매직 넘버, ENUM, 꼬리 재귀 등 다양한 주제에 대한 사람들의 의견을 읽으며 소소하게 배우는 것들도 많고 성장하기 너무 좋은 환경인 것 같다.
꼭!!!! 붙어서!!!!!!!!! 1년동안 더 성장하고 싶다.
'BE > 우아한테크코스' 카테고리의 다른 글
[우아한테크코스 6기] 프리코스 - 3주차 (0) | 2023.11.15 |
---|---|
[우아한테크코스 6기] 프리코스 - 2주차 (0) | 2023.11.06 |
[우아한테크코스 6기] 프리코스 - 1주차 (0) | 2023.11.02 |
[우아한테크코스 6기] 프리코스 0주차 (1) | 2023.10.26 |