![[워밍업 클럽 4기 - BE 클린 코드 & 테스트 코드] Day 4 미션](https://cdn.inflearn.com/public/files/blogs/2447dfae-73ab-4f4e-8364-dbf22d143976/인프런 워밍업 클럽 4기썸네일_직사각형.png)
[워밍업 클럽 4기 - BE 클린 코드 & 테스트 코드] Day 4 미션
🎯 Day 4 미션
1⃣번 미션
Step 0) 분석 및 이해하기 & 리팩토링 대상/범위 확인
키워드 :
논리, 사고의 흐름
,읽기 좋은 코드
,리팩토링
코드와 설명을 통해, 해당 도메인에 대해서 이해합니다.
⇒ 주문에 대한 비즈니스 측면의 유효성 검사가 아닌 사용자가 생성한 주문 객체에 대한 유효성 검사는 Order 객체에서 진행한다고 가정하겠습니다.
// 사용자가 생성한 '주문'이 유효한지를 검증하는 메서드
public boolean validateOrder(Order order) {
// a. 주문 항목이 있는지 확인
if (order.getItems().size() == 0) { // a-1. 주문 항목이 없음
log.info("주문 항목이 없습니다.");
return false;
} else { // a-2. 주문 항목이 있음
// b. 주문 총액이 올바른지 확인 (0원 초과)
if (order.getTotalPrice() > 0) { // b-1. 주문 총액이 0원 초과
// c. 주문한 사용자 정보가 있는지 확인
if (!order.hasCustomerInfo()) { // c-1. 사용자 정보가 없음
log.info("사용자 정보가 없습니다.");
return false;
} else { // c-2. 사용자 정보가 있음
return true;
}
} else if (!(order.getTotalPrice() > 0)) { // b-2. 주문 총액이 0원 이하
log.info("올바르지 않은 총 가격입니다.");
return false;
}
}
// 모든 조건을 통과하여 유효한 주문인 경우
return true;
}
Step 1) 리팩토링
1. 주문 항목이 있는지 확인 (a)
if (order.getItems().size() == 0)
if
조건에서 주문 항목이 없으면false
를 반환하고, 주문 항목이 있다면 그 이후의else
로 자연스럽게 넘어가게 됩니다. 따라서, 주문 항목이 없는 경우에만false
를 반환하고, 그 외의 주문 항목이 존재하는 경우에는 계속해서 다음 조건을 검사하게 되므로else
를 제거해도 문제가 없습니다.
⇒ 뇌 메모리 적게 쓰기 (인지적 경제성)
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
}
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;
}
2. 주문 총액이 올바른지 확인 (b)
(b-2)의
!(order.getTotalPrice() > 0)
를 부정의 의미를 담지 않은order.getTotalPrice() <= 0
로 표현할 수 있습니다.
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
}
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;
}
주문 총액이 0원 이하(b-2)인 경우를 먼저 확인하게 하면 이 조건을 만족하면 바로
false
를 반환합니다. 이후, 주문 총액이 0원을 초과(b-1)하는 경우에만 사용자 정보를 확인하는 로직으로 넘어가게 됩니다. 이렇게 조건문의 순서 변경을 통해, 불필요한else if
를 제거할 수 있습니다.
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.getTotalPrice() <= 0) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (!order.hasCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
} else {
return true;
}
return true;
}
3. 주문한 사용자 정보가 있는지 확인 (c)
(c-2)의 경우는 모든 조건을 통과한 경우로,
else
를 제거해도 됩니다.공백 라인으로 모든 조건을 만족한 경우를 다른 조건과 분리해줍니다.
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.getTotalPrice() <= 0) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (!order.hasCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
return true;
}
2⃣번 미션
SRP (Single Responsibility Principle; 단일 책임의 원칙)
하나의 클래스는 하나의 책임/관심사를 가진다.
→ 변경하는 이유는 하나여야 한다.
→ 높은 응집도 & 낮은 결합도
OCP (Open-Closed Principle; 개방-폐쇄의 원칙)
확장에는 열려 있고, 수정에는 닫혀 있어야 한다.
→ 기존 코드 변경 없이 기능 확장 가능해야 한다.
LSP (Liskov substitution Priciple; 리스코프 치환 원칙)
부모 클래스의 인스턴스는 자식 클래스의 인스턴스로 치환할 수 있어야 한다.
→ 자식 클래스는 부모 클래스를 변경시키지 않아야 한다.
ISP (Interface Segregation Principle; 인터페이스 분리 원칙)
인터페이스에는 필요한 기능만 선언한다.
DIP (Dependecy Inversion Principle; 의존성 역전의 법칙)
구체화된 것보다 추상화된 스펙에 의존해야 한다.
👨🏻💻 강의 출처
댓글을 작성해보세요.