[워밍업 클럽 4기 백엔드] Day 4 미션
1. 읽기 좋은 코드로 리팩토링 해봅시다.
😫 Before
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;
}😄 After
public boolean validateOrder(Order order) {
if(order.isEmptyItems()) {
log.info("주문 항목이 없습니다.");
return false;
}
if(order.isInvalidTotalPrice()) {
log.info("올바르지 않은 총 가격입니다.");
return false;
}
if (order.hasNotCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return false;
}
return true;
}✅ 불필요한 중첩 분기문 제거 & early return
사고의 흐름을 복잡하게 하는 중첩 분기문을 제거하여 사고의 depth를 줄임
early return을 활용하여 각 분기문에 대한 맥락만 파악할 수 있도록 함
✅ 부정 연산자보단 부정어구 사용
!order.hasCustomerInfo()같이 가독성이 떨어지는 부정 연산자 보단,order.hasNotCustomerInfo()처럼 문장 자체에 부정의 의미를 담는 방식을 채택하여 이해를 도움
✅ getter를 통한 검증보단 해당 객체에 검증 위임
order객체가 가진 값을 직접 꺼내와서 검증하는 것보다, 객체에게 메시지를 보내어 검증을 요구기존 getter를 통해 값을 가져와서 하는 검증보다, 메서드명에서 무엇을 검증하려고 하는지 보여줄 수 있어 기능에 대한 이해를 빠르게 할 수 있음
2. SOLID에 대하여 자신만의 언어로 정리해 봅시다.
📌Single Responsibility Principle(단일 책임 원칙)
하나의 클래스가 하나의 책임만 가지도록 설계하자!
객체간의 책임을 명확하게 나누어 설계해야 한다.
객체의 관심사를 분리하여 하나의 관심사만 가지도록 하여 명확한 책임을 부여한다.
우리가 설계한 객체가 하나의 책임만을 가지고 있는지 점검하며 개발한다.
책임을 제대로 나누지 못하면 리팩토링 과정에서 엉뚱한 클래스를 수정 해야하는 상황이 발생한다.
📌Open-Closed Principle(개방-폐쇄 원칙)
확장에는 열려 있고, 수정에는 닫혀 있어야 한다!
요구 사항이 생겨도 기존 코드를 과도하게 변경하지 않고 확장할 수 있어야 한다.
인터페이스를 활용하여 확장 가능성이 있는 기능은 추상화를 잘해야 한다.
📌Liskov Substitution Principle(리스코프 치환 원칙)
자식 클래스는 부모 클래스의 책임을 준수하며, 부모 클래스의 행동을 변경하지 않아야 한다.
상속 구조로 객체를 설계할 때, 자식은
@Override를 통해 부모의 기능을 훼손해서는 안된다.항상 부모의 자리에 자식이 위치했을 때도 생각하며 자식을 설계해야 한다.
만약 자식 클래스의 기능을 사용할 때 타입 체크를 해야 하는 상황이라면 설계를 다시 하자.
📌Interface Segregation Principle(인터페이스 분리 원칙)
클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다!
인테페이스를 잘게 쪼개어 꼭 필요한 기능만 구현할 수 있도록 설계한다.
모든 기능을 추상화한 인터페이스로 인해, 구현 클래스에서 구현을 하기 힘들거나 예외 던지기 같은 상황을 유발하면 안된다.
📌Dependency Inversion Principle(의존성 역전 원칙)
상위 수준의 모듈은 하위 수준의 모듈에의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다!
저수준 모듈 : 구체에 가까운 모듈
고수준 모듈 : 추상화 레벨이 높은 모듈
추상화에만 의존하여 런타임 시점에 어떤 구현체가 들어와도 추상화된 기능에만 의존할 수 있도록 한다.
댓글을 작성해보세요.