현재 우테코 프리코스의 과제가 끝난 시점에서 1주일이 흘렀다.
4주차에 대한 코드를 다시 보면서 그 때 당시의 문제점들과 배운점들을 토대로 회고 및 느낀점을 작성해보고자 한다.
기능 요구 사항
기능 요구사항을 대충 훑어만 봐도 어마어마하다... 이걸 보는 순간 머리가 지끈거리면서 어떻게 구현해나아가야 할지에 대해서 머릿속이 복잡해져나갔었다.
게다가 출력에 대한 포맷을 보면 프로젝트 파일에서 products.md 파일과, promotions.md 파일이 있기 때문에 기타 추가 사항 및 변경사항들은 md 파일에서 이루어지며, md 파일에 대한 포맷이 변경될 경우 이를 사용하는 애플리케이션에서는 추가적인 변경사항이 없어야 완벽하게 구현했다고 볼 수 있다.
처음에 이러한 부분을 놓쳐서 다시 설계했었다.
비즈니스 로직 살펴보기
public enum PromotionPolicy {
BUY_2_GET_1,
MD_RECOMMENDED,
FLASH_SALE,
NONE;
// 필드 값...
public PromotionResult applyPromotion(Integer purchaseQuantity,
Product promotionProduct,
Product noPromotionProduct) {
// 전체 재고가 구매 수량을 충당할 수 있을 경우
if (totalQuantity >= purchaseQuantity) {
//... 로직
if (remainingQuantity > 0) {
//.. 프로모션 재고가 부족해서 일반 상품에서 재고를 차감해야 하는 경우
}
// 일반 재고가 부족할 경우
}
// 추가 증정품을 안가져간다고 할 경우
}
}
// 프로모션 혜택이 부족한 경우 추가 결제를 진행해야함
if ()) {
//추가 결제 여부를 묻는 단계
if (applyDecision.equalsIgnoreCase("Y")) {
if () {
// 일반 상품의 재고가 충분하여 결제를 진행 해야되는지...
}
if () {
// 일반 상품의 재고가 충분치 않은 경우....
}
}
return new PromotionResult(paidQuantity, freeQuantityGiven);
}
return new PromotionResult(0, 0);
}
재고와 구매수량에 따라 어떤 프로모션을 적용할 것인지에 대한 로직이다. 우테코 프리코스의 프로그램 요구 사항에는 하나의 메서드가 10줄이 넘어가지 않도록 구현하라고 되어있다.
처음에는 로직을 짜다가 분기점이 보일 때마다 메서드를 추출해서 한 메서드의 로직의 볼륨을 줄여보려고 애썼으나 메서드 추출을 하는 블록을 구분하는 거 자체가 쉽지 않았고, 데이터가 계속해서 여기저기 사용되다 보니 메서드 추출 자체가 어려웠었다.
그리고 해당 메서드를 호출하는 클라이언트 코드 또한 메서드가 10줄을 넘어가게 되면서 분리 또한 쉽지 않았다.
문제점 - 복잡한 요구사항 일 수록 정확히 분석할 것!!!
솔직히 위에 비즈니스 로직의 복잡한 if문으로 엮은 코드는 안나올 수 있었다.
내가 맨처음 부터 생길 수 있는 문제점이나, 이러한 분기들을 어느정도 숙지 한 채로 작성했다면 말이다. 위의 코드는 기능 구현 사항을 보자마자 떠올린 상태에서 작성한 코드이다. 코드가 매우 지저분한 상태...
그래서 어떤 결심을 하게 되었냐면 요구 기능 사항을 옆에 띄워놓고 아이패드로 하나하나 따라가면서 각 분기점에 대해서 생각하고 내가 지금 어떤 데이터를 추출해야 하는지, 그러기 위해서는 어떠한 문제점이 있고, 해당 문제점을 해결하려면 어떻게 해야되는지 부터 작성해나가기로 했다.
첫번째 문제
먼저 프로모션의 조건이 바뀔 경우에 대한 것부터 써내려가기 시작했다. 요구사항에는 2+1과 1+1이 존재한다. 만약 2+1의 물품을 구입할 경우 1개는 증정품인데 받을 거냐고 물어봐야 하는 비즈니스 요구사항이 있었고, 3개를 받을 경우에는 물어보지 않고 그냥 2개만 결제 1개는 증정품으로 구입하게 된다.
즉 2개를 살 경우 프로모션 혜택을 받을 거냐 안받을 거냐고 물어보고, 3개를 살 경우에는 물어보지 않고 3개중 1개는 프로모션 혜택으로 적용이 된다는 것.
그리고 1+1에 대한 상품도 똑같이 적용된다. 1개를 살 경우 물어보고, 2개를 살 경우에는 묻지 않는다.
이러한 문제를 먼저 해결하기 위해 처음에 코드를 작성해 나갈 때는 2+1 상품을 구매했을 때만을 가정한 코드를 작성해 나갔었다. 그러다 보니 2+1인 경우에는 제대로 작동하는데 3개 쨰에는 묻지 않고, 4개째에는 묻지 않고 5개째에는 다시 2+1, 2+1 이니 못받은 1가지 물건에 대해서 받을 건지 안받을 건지를 물어봐야 한다.
첫번째 문제만을 생각하며 코드를 작성하니 당연하게도 동적으로 코드가 작동하지 않는 문제점이 첫번째로 발생했다.
바로 그림을 그려가면서 현 상황을 분석해나갔다.
글로 써내려가면서 어떻게 코드가 흐르는지 작성해보니 수열을 발견할 수 있었다. 1+1이든 2+1이든 프로모션이 적용되려면 최소 구매 개수와, 증정품으로 나가는 개수를 알아야 되는데, 2개를 사면 물어보고, 5개를 사면 물어보고 8개를 사면 물어보고 11개를 사면 물어봐야 되는 일정한 패턴을 발견할 수 있었다. 바로 3개씩 늘어났을 때만 물어본다는 것. 즉 해당 프로모션에서는 수열공식을 적용해서 풀 수 있었다.
(수학을 잘하시는 분이라면 바로 문제에 최적의 코드를 작성했을 수도 있겠다... 라는 생각이 든다. 수포자인 나로써는 해당 문제를 발견하고 해결하는데 꼬박 하루가 걸렸다.)
이렇게 작성해두면 구매 개수가 만약 100개 일 경우 프로모션 상품은 추가 증정품에 대해서 사용자에게 물어봐야 되는지 혹은 묻지 않고 몇개의 프로모션 혜택을 받을 수 있는지 알아서 적용할 수 있었다.
두번째 문제
첫번째 문제를 해결하고 나서 바로 맞딱드린 문제는 프로모션 재품의 제고가 다 떨어질 경우이다. 해당 경우에는 똑같은 상품이지만 프로모션이 적용되지 않은 물건을 찾아서 재고를 감소시켜야 하고, 사용자에게 프로모션 혜택이 적용된 상품이지만 재고가 없으니 일반 정가로 추가 구매해야 한다 라는 식의 안내메세지가 출력되어야 한다.
현재 코드를 사진으로 찍어서 파라미터로 사용자 입력값이 어떤식으로 들어오는지 어떤 코드 조각에서 데이터 어떤 형식인지 먼저 정리할 필요가 있었다.(아이패드가 없었다면 못했을 뻔....그냥 A4 용지로 했을려나??)
첫번째 문제와 두번째 문제 모두 복잡한 요구사항을 잘 분석하면 풀 수 있었던 부분이었다. 하지만 이러한 부분을 간과하고 1~3주차 부터 해왔던 습관대로 "코드 먼저 작성 후 생기는 문제에 대해서 해결 및 리팩토링" 이 사이클로 가다보니 코드가 매우 지저분한 상태이다.
여러 분기점이 존재하니, 이는 예상치 못한 사이드 이펙트가 발생할 확률이 크고 변수에 대해서 서로 강하게 엮여있다보니 메서드를 분리하기도 힘들었었다.
느낀점
첫번째 문제와 두번째 문제를 해결해나가는 과정에 있어서 많은 시간을 소비했다. 애초에 처음부터 요구 사항을 정확히 분석할 수 있는 습관을 길렀다면 좀 더 수월하게 해당 문제를 풀 수 있었을 텐데 라는 아쉬움이 많이 남는다.
현재 우테코 프리코스가 끝난 시점에서 해당 문제를 다시 풀어보았지만 끊임없는 if문에서 빠져나오기가 힘들었다. 이는 기본기에 대한 부족이 크다 라는 생각이 든다.
현재 스터디원들과 우테코 프리코스에 대한 문제를 다시 살펴보고있고, 서로 코드리뷰를 진행하며 1~4주차를 다른 방식으로 재작성 및 더 나은 방식으로 "서로가 이러한 패턴 혹은 이러한 기술을 적용해보았다면..." 하는 아쉬움이 남았던 코드들을 고쳐보는 시간을 가지고 있다.
나는 4주차를 다시 풀어보았지만 처음으로 작성했던 코드 패턴에 묶여있어서 새로운 방식을 떠올리긴 쉽지 않았다. 더 나은 방법도 사실 떠오르진 않긴 하지만...ㅎㅎ
쨌든 기본기 부족 -> 더 나은 방식이 존재한다는 건 인지하지만 구현을 하지 못함(생각대로 되지 않음) -> 코드 구현에 있어서 가독성을 해치는 안티 패턴 및 습관(StreamAPI,Optional, null 리턴, 유틸 클래스 설계(생성자를 호출하지 못하도록 완벽히 막지 못함), 객체 사용시 사용되는 디자인 패턴의 사용 고려 등등) 이러한 문제점과 부족한 점들을 인지했고, 이번주 까지 1~3 주차에 대한 문제를 스터디원들과 서로 의논한 이후에 사이드 프로젝트를 각자 도맡으면서 Effective Java 책을 사서 코드를 구현해보고 서로 의논할 예정이다.
우테코 프리코스가 끝나면서 사실 처음에는 코테만 불러줘도 경험할 수 있어서 너무 좋을거같지만 이렇게 눈에 띄는 문제점들을 아직 해결하지 못한 채로써는 자신감이 붙지 않는 것도 사실이다.
프리코스를 진행하면서 배운게 너무 많고 단점도 확인할 수 있어서 앞으로의 과제는 위에 문제점들을 해결해나가는데 집중하도록 하겠다.
혹시 우테코 프리코스를 참여안해본 개발자 지망생 혹은 현직 개발자가 있다면 내년 11월달에 있을 우테코 프리코스에 필히 참여하여 퀄리티 좋은 과제들을 맛보고 본인의 문제점을 파악하여 꾸준히 성장해나갔으면 한다. 현직 개발자들 또한 배울점이 무조건 있으리라 생각한다.
'회고록' 카테고리의 다른 글
[인프런 워밍업 클럽 스터디 - 테스트 코드를 대하는 자세 2주차 회고] 어떤 것이 더 적절한 단위 테스트인가? (0) | 2025.03.17 |
---|---|
[우테코 7기 백엔드 회고]3주차 로또 (0) | 2024.11.12 |
[우테코 7기 백엔드 회고] 2주차 레이싱 게임 (2) | 2024.11.05 |
[우테코 7기 백엔드 회고] 1주차 미션 문자열 계산기 (0) | 2024.10.28 |