[워밍업 클럽 스터디 2기::백엔드] 1주차 발자국
일주일간의 학습 내용
추상 (抽象)
코드 단위에서의 추상 레벨을 지키는 법
메서드를 추출하는 기준과 이름 짓기등
도메인의 책임 분리에 대해서만 추상화를 생각하고 있었는데
코드안에서 추상 레벨을 일관되게 유지하고 제가 제일 어려워하던 이름짓는법을
매우 쉽게 설명해주셔서 큰 도움이 되었습니다.
논리, 사고의 흐름
읽기 쉬운 코드를 작성하고 싶었으나 그동안은 메서드의 구조, 이름만 신경을 쓰고 있었습니다.
잊고 있던 early return을 상기했고 부정문을 메소드로 대체했을때 인지부하를 줄여
읽는이로 하여금 더 이해하기 쉬운 코드를 작성할 수 있다는게 신선했습니다.
객체 지향 패러다임
SOLID 원칙을 코드에 적용하시는 것을 보고 많이 배웠습니다.
늘 SOLID한 코드인가를 고민했는데 강사님의 강의를 듣고 좀 더 시야가 트인 느낌입니다.
학습 회고
칭찬하고 싶은 점
프로젝트 진행중에도 시간을 쪼개어 강의를 듣고 과제를 수행했다
진행중인 프로젝트에도 적용을 시키려 노력했다.
아쉬웠던 점
부트캠프에 참여중이라 시간 제약이 있어 강의를 완전 깊게 이해하지 못한 느낌이라 아쉽다.
여러번 강의를 듣고 싶은데 시간이 없었다...
보완하고 싶은 점
강의 내용을 글로 정리하려했으나 글쓰기가 아직은 많이 어렵게 느껴진다.
글을 정리하는법을 공부해야할 것 같다.
미션
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
} else {
if (order.getTotalPrice() > 0) {
if (!order.hasCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
} else {
return true;
}
} else if (!(order.getTotalPrice() > 0)) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
}
return true;
}
내가 생각한 문제점들
1. 추상화 부족
이 메서드는 주문 항목을 확인하고, 사용자 정보를 확인하고, 총 가격을 확인하고 있다.
주문 검증이라는 책임을 지키는 듯 보이지만 내부를 살펴보면 3가지 일을 직접하고 있기에 확장이 어렵고
단일 책임을 지키지 못한다는 판단을 하였다 이런 문제들은 추상화를 제대로 하지 않았기에 생긴 문제라 판단하여
이 문제를 추상화 부족이라는 문제로 추상화하였다.
2. 중첩된 조건문
else문을 보면 else문에서 끝나는 것이 아니라 다시 조건문을 이용하고 그 안에서 다시 조건문을 이용하는 복잡한 형태인데
이런 형태가 가독성을 해치고 로직을 복잡하게 만들고 있다는 생각이 들었다.
3. 중복된 조건
order.getTotalPrice() > 0 를 else if에서도 사용중인데 0보다 크거나, 아니거나의 조건 판별을 위해서라면 두번씩이나
조건을 붙이는건 효율적이지 못하다는 결론을 내렸다
4. 부정 연산자에 의한 사고의 흐름 방해
order.getTotalPrice() > 0 와 order.hasCustomerInfo에 ! 부정 연산자를 붙인 형태로 보는이로 하여금 한번더 어떤 코드인가를
생각하게 만드는 좋지 않은 조건문이라는 생각이 들었다.
내가 생각한 해결방법들
1. 추상화 부족
먼저 주문 검증이라는 책임을 어떻게 분산을 시킬것인가를 정했는데
각각의 조건문에서 원하는 검증들을 각각의 메서드들로 분할을 시켜주기로 했다.
리팩토링후에는 validateOrder 내부를 주문 항목 확인, 사용자 정보 확인, 총 가격 확인이라는
각각의 책임을 가진 메서드들로 나누고 validateOrder는 주문 검증이라는 명확한 책임을 가지게 만들어야 겠다고 생각했다.
2. 중첩된 조건문
1번에서의 메서드 분할에 따라 각각의 메서드를 조건문에 넣어주기로 했고
6개의 if 또는 else를 3개의 if문으로 줄여보기로 했다
3. 중복된 조건
조건문의 순서와 early return을 이용해 order.getTotalPrice()의 조건을 한번만 이용하기로 했다
총가격이 0보다 작거나 같다면 사용자 정보 확인전에 return을 해주어 불필요한 중복 조건을 제거했다.
4. 부정 연산자에 의한 사고의 흐름 방해
더 직관적인 코드를 만들기 위해 부정 연산자를 메서드 내부로 숨기고
메서드의 이름을 isCustomerInfoNotFound라는 문장으로 만들어 validateOrder 메서드만 확인해도 해당 조건문에서
무엇을 확인하는지 알 수 있게끔 수정했다.
결과 코드
public boolean validateOrder(Order order) {
if (isOrderItemsEmpty(order)) {
log.info("주문 항목이 없습니다.");
return false;
}
if (isTotalPriceInvalid(order)) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (isCustomerInfoNotFound(order)) {
log.info("사용자 정보가 없습니다.");
return false;
}
return true;
}
private boolean isOrderItemsEmpty(Order order) {
return order.getItems().isEmpty();
}
private boolean isTotalPriceInvalid(Order order) {
return order.getTotalPrice() < 0;
}
private boolean isCustomerInfoNotFound(Order order) {
return !order.hasCustomerInfo();
}
회고
재미있는 미션이었다.
실제 프로젝트에서는 리팩토링이 부담스럽게 느껴졌는데
부담없이 내 맘대로 리팩토링을 진행했기에 마음편히 진행하고
다른 분들의 코드와 비교도 해볼수 있는게 아주 좋다.
댓글을 작성해보세요.