본문 바로가기
2023-woowacourse-precourse

2023 우아한 테크코스 4주차 회고

by JHyun0302 2023. 11. 17.
728x90

2023년 11월 9일 ~ 2023년 11월15일, 7일간 우아한 테크코스 프리코스 4주차 과제가 진행되었다.

드디어 마지막 프리코스 여정의 끝났다!!

졸업 작품 발표 준비, 오픽 시험, 포토폴리오 정리... 그리고 우아한 테크코스까지...

많이 바빴지만 그만큼 성취감도 큰 1달이였다!!

 

마지막 4주차 과제는 "크리스마스 프로모션"이였다!!

(이 미션은 진짜 처음 보는...)

 

 

심지어 과제 진행도 Private으로 진행되었고 진행 방법도 1 ~ 3주차와 달랐다!

이메일을 통해 여러 번 과제 진행 방법을 공지하셨지만 private 레파지토리를 만들고 main 브랜치에 바로 작성해야했지만..

나의 불찰로 1 ~ 3 주차 과제와 같이 main 브랜치 대신 [Github ID] 브랜치를 파고 코드를 작성했다...

 

다행히도 요구사항을 꼼꼼히 읽어야 한다는 3주 차의 교훈 덕분에 제출 2일 전 잘못됨을 인지하고

새로 레파지토리를 생성하여 main 브랜치에 다시 커밋했다... (덕분에 내 57개 커밋 내역 ㅃ2...)

 

 

 

 

 


4주차 미션 소개 & 나의 로직 설명

 

 

4주차 미션 : https://github.com/JHyun0302/java-christmas-6-JHyun0302/tree/main

 

GitHub - JHyun0302/java-christmas-6-JHyun0302: 우아한 테크코스 프리코스 4주차 과제 (2023.11.9~2023.11.15)

우아한 테크코스 프리코스 4주차 과제 (2023.11.9~2023.11.15). Contribute to JHyun0302/java-christmas-6-JHyun0302 development by creating an account on GitHub.

github.com

 

 

진짜 살면서 처음 보는 문제였다... 1달 전에 받은 크리스마스 선물에 감동이...ㅜ

 

 

 

Safe!!

 

 

구현 끝내고 테스트 통과했을 때 뿌듯!!

 

4주차 과제도 MVC 패턴을 활용해 '나'의 개발 의도를 밝히고자 했다!

 

 

 

 

크리스마스 프로모션에서 내가 정의한 Model은 다음과 같다.

ReversationDay : 방문 예약 날짜, 요일
Order : 주문한 메뉴 & 수량, 음식 종류(애피타이저? 메인? 디저트? 음료?), 총 주문 금액, 증정품 수령 여부

 

 

 

 

View는 다음과 같다.

InputView
    - 예약 방문 날짜 입력 받기
    - 주문 입력 받기
    
OutputView
    - 모든 출력문 관리

 

 

 

 

그리고 Controller와 Service를 분리하여 비즈니스 로직은 Service, 화면을 그리는 역할은 Controller!!

 

 

Service는 다음과 같다. (Controller는 각각의 Service를 그리는 역할!)

InputReservationDayService : 예약 방문 날짜 입력
OrderMenuService : 주문 입력
ShowDetailInfoService : 주문 내역 출력에 필요한 비즈니스 로직

 

 

그 외에도 검증(validation), dto(메뉴 이름 & 수량), constant(정적 메시지, 메뉴, 이벤트 배지, 요일), Utils(크리스마스 디데이 할인, 평일 할인, 주말 할인, 특별 할인)을 정의했다.

 

 

 

 


고민 & 해결

 

 

1. enum의 사용
- 고민 : 4주 차 과제의 요구사항을 여러 차례 읽으면서 연관성 있는 상수를 파악하고 그들을 묶어야겠다고 생각했다. 하지만 그들을 묶을 때 어떤 정보들을 함께 관리해야 할지 막막했었다. 너무 적은 정보를 관리하면 enum 클래스가 많아지고 너무 많은 정보를 한 곳에서 관리하면 SRP 원칙에 어긋난다고 생각했기 때문...


- 해결 : enum 클래스의 개수보다 책임의 분리를 더 중점적으로 생각했습니다. 그래서 하나의 enum 클래스는 최소한의 정보를 담도록 구현하고 클래스 명을 명확하게 표기하였다!

 


2. 평일 & 주말 할인 계산
- 고민 : SalePolicy의 "평일 & 주말 할인" 계산 시 foodType(디저트 & 메인)가 필요하다. 그리고 2가지 구현 방법이 있다.
① Order 객체에서 foodType을 저장해 놓고 Getter를 통해 비교한다.

② if(Menu의 enum 클래스의 음식명 == Order 객체의 foodName) 일 때 그 음식이 (dessert 또는 main)인가?

 

- 해결 : ①번 방법을 선택했다.

② 경우 주문한 음식을 찾기 위해 Menu enum 클래스를 for 문을 통해 비교해야 하며 같은 값을 찾는다 하더라도 부가적인 조건문이 필요하므로 foodType도 Order 객체에 저장하여 구현하였다.

 


3. <혜택 내역>계산
- 고민 : totalSalePrice(총 혜택 금액) 정의할 때 증정품 샴페인값을 빼면 <혜택 내역>에서 문제가 생기고, 샴페인값을 더하면 <할인 후 예상 결제 금액>에 문제가 생김...

 

- 해결 : 변수명(totalSalePrice)을 명확히 하는 것과 코드의 일관성을 지키는 것에 초점을 두었다. 이벤트 배지도 구해야 하므로 totalSalePrice는 증정품 값도 포함된 값으로 정의하여 구현했다.

 

 

 

 


성장 포인트

 

 

1. 함수 라인 제한 : 3주 차 공통 피드백에서 함수 라인에 대한 기준을 읽었다. 그리고 3주 차 과제에서 main() 함수에 15라인으로 제한하지 못한 부분을 깨닫게 되었다. 4주 차 과제에서는 같은 실수를 반복하지 않기 위해 main() 함수도 리팩토링을 통해 15라인으로 제한시켰다!

2. 하드 코딩된 상숫값 관리 :
하드 코딩된 값을 한 곳에 관리하기 위해 constant 패키지에 하드 코딩이 필요한 상숫값을 정의하여 사용하도록 리팩토링하였다.

3. 3주 차 공통 피드백 문서에서 비즈니스 로직과 UI 로직을 분리
에 대해 읽었다. 그래서 두 로직을 철저히 분리하기 위해 모든 출력문은 OutputView에서 담당하고 Controller에서 화면을 그리는 것에만 집중시켰다. 그리고 비즈니스 로직은 Service에서 담당했습니다.

4. 입출력 책임 분리 & 템플릿 콜백 패턴 :
입출력에 관한 책임을 확실하게 나누기 위해 입력은 InputView에서 담당하고 모든 출력은 OutputView에서 담당하도록 분리하였다. 또한 InputView에서 입력에 실패한 경우 재시도를 위해 try-catch 문을 반복해서 사용해야만 했다. 그래서 반복을 없애기 위해 템플릿 콜백 패턴을 구현해 반복되는 try-catch문을 제거하였다!

 

 

 

 


느낀점

 

 

미리 받는 크리스마스 선물...

예기치 못한 상황을 가정하며 검증 로직 만들고 enum 클래스를 통해 책임을 분리하는 것이 쉽지 않았고

예외 상황을 상상하며 테스트 케이스를 작성하는 것도 꽤 시간이 오래 걸렸다..

 

하지만 고민한 시간이 길었던 만큼 성취감이 컸던 과제임은 틀림없다!

반응형