❓ Mission 1.
코드와 설명을 보고, [섹션 3. 논리 의 사고 흐름]에서 이야기 하는 내용을 중심으로 읽기좋은 코드로 리팩토링 해보기
✔️ 사용자가 생성한 '주문'이 유효한지를 검증하는 메서드.
✔️ Order는 주문 객체이고, 필요하다면 Order에 추가적인 메서드를 만들어도 된다. (Order 내부의 구현을 구체적으로 할 필요는 없다.)
✔️ 필요하다면 메서드를 추출할 수 있다.
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️⃣ 로직 말로 풀어보기
말로 위 코드 정리해보면
주문 아이템의 사이즈가 0 이면 바로 false 리턴 0 이 아니고 주문 가격이 0이상이 아니면 false 리턴
주문 총 가격이 0보다 큰데 주문 정보가 없다면 false 리턴 있다면 true 리턴
궁금해지는것: 가격이 0이면 아무것도 사지 않았다는 것인데 주문 항목이 비었으면 아무것도 사지 않았다는 뜻이라고 의문이 들었다
하지만 로직을 짜는 것이 아니기 때문에 size가 0이면 아무것도 getTotalPrice=0 이란 개념도 동일하다고 가정
-> 4️⃣ 에서 <= 로 변경하여 궁금증 해결
2️⃣ 부정 연산자 제거
부정 연산자가 있어 긍정으로 변경 시켜보기
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
} else {
if (order.getTotalPrice() > 0) {
if (order.doesNotHaveCustomerInfo()) { // 부정 연산자 제거
log.info("사용자 정보가 없습니다.");
return false;
} else {
return true;
}
} else if (order.getTotalPrice() < 0) { // 부정 연산자 제거
log.info("올바르지 않은 총 가격입니다.");
return false;
}
}
return true;
}
/**
* order 객체의 hasCustomerInfo() 메소드가 구현되어 있다는 걸 가정 하고 이걸 또 부정한다(=긍정)로 만들기
* 또한 이름의 맞게 doesNotCustomerInfo()로 변경
*/
3️⃣ 불필요한 else문 제거
public boolean validateOrder(Order order) {
if (order.getItems().size() == 0) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.getTotalPrice() > 0) {
if (order.doesNotHaveCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
}
if (order.getTotalPrice() < 0) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
return true;
}
4️⃣ 객체의 요청해보기
order.getItems를 처럼 getter를 사용하는 것이 아니라 객체가 비교 로직을 수행하도록 요청해보자
public class Order {
private final List<Item> items;
private final long totalPrice;
// 생성자 생략
/**
* public isSizeEqualsZero() {
* return item;
* }
* Size 가 0 이것보다 비었니로 물어보자
*/
public boolean isEmptyItems() {
return !this.items.isEmpty();
}
public boolean isInvalidTotalPrice(){
return this.totalPrice <=0;
}
}
public boolean validateOrder(Order order) {
if (order.isEmptyItems()) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.getTotalPrice() > 0) {
if (order.doesNotHaveCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
}
if (order.isInvalidTotalPrice) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
return true;
}
5️⃣ 먼저 리턴 시킬수 있는것 리턴
public boolean validateOrder(Order order) {
if (order.isEmptyItems()) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.isInvalidTotalPrice) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (order.doesNotHaveCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
return true;
}
/**
* 만약 총 주문 금액의 유효성 검사를 해버리고 리턴 할 시 (order.getTotalPrice() > 0)를 할 필요가 없다.
*/
6️⃣ 이름 맞추기 (is , does)
public boolean validateOrder(Order order) {
if (order.isEmptyItems()) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.isInvalidTotalPrice()) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (order.isEmptyCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
} //doesNotHaveCustomerInfo() -> 부정인데 없다는 의미로 단어를 찾아 대체
return true;
}
✅ 정리
public boolean validateOrder(Order order) {
if (order.isEmptyItems()) {
log.info("주문 항목이 없습니다.");
return false;
}
if (order.isInvalidTotalPrice()) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (order.isEmptyCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
return true;
}
❓ Mission 2.
SOLID에 대하여 자기만의 언어로 정리해 봅시다.
✅ 정리
1️⃣ SRP 단일 책임 원칙
하나의 클래스는 단 하나의 책임을 가져야한다. = 욕심 부리지 않기
2️⃣ OCP 개방 폐쇄 원칙
확장에는 OPEN, 수정에는 CLOSE 해야한다. = 기존 코드 건드리지말기
3️⃣ LSP 리스코프 치환 원칙
자식 클래스는 부모 클래스는 대체 가능해야한다. = 자식은 부모가 가진 기능을 다 할수 있기
4️⃣ ISP 인터페이스 분리 원칙
하나의 인터페이스는 단 하나의 책임을 가져야한다. SRP 와 비슷하다고 생각하기(근데 Interface 버전)
5️⃣ DIP 의존석 역전 원칙
구체적인 것보다 추상적인 것에 의존하라 = 추상화 레벨이 높은 인터페이스에 의존하기
출처
[박우빈 강사님] Readable Code: 읽기 좋은 코드를 작성하는 사고법
https://www.inflearn.com/course/readable-code-%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%82%AC%EA%B3%A0%EB%B2%95/dashboard
[인프런 워밍업 클럽 3기] 과제
'인프런 워밍업 클럽 3기' 카테고리의 다른 글
인프런 워밍업 스터디 클럽 3기 백엔드 Day 18미션 (0) | 2025.03.27 |
---|---|
인프런 워밍업 스터디 클럽 3기 백엔드 Day 16미션 (0) | 2025.03.25 |