
워밍업 클럽 4기 - 백엔드 Day 4
수정내역
썸네일 추가
과제
1. 읽기 좋은 코드로 리팩토링해 보기
AS-IS
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;
}
TO-BE
Early Return 적용
if else 문에 대한 조건에 대하여 if문 별 return이 존재하다는걸 파악하였고 조건에 맞게 Early Return적용
order가 null일 경우 추가 적용
공백 라인 적용
if문에 대한 공백 라인을 적용함으로서 코드의 분기점을 명확하게 구분
부정연산자를 메서드안에 포함하여 메서드명으로 확인할 수 있도록 변경
!(order.getTotalPrice() > 0)
,!order.hasCustomerInfo()
의 가독성 향상을 위한 메서드화
예외 처리
return false;
에 대해서 각 메서드에서IllegalArgumentException
예외를 던지도록 수정하였고예외처리를 통해 log를 try-catch문으로 한번에 처리하도록 수정(1번버전)
1. 예외처리 버전 ( 다소 엄격 )
public boolean validateOrder(Order order) {
if (order == null) {
log.info("Order 객체가 null입니다.");
return false;
}
try{
validateOrderItemsExist(order);
validateTotalPrice(order);
validateCustomerInfoPresent(order);
return true;
}catch(IllegalArgumentException e) {
log.info(e.getMessage());
return false;
}
}
public void validateOrderItemsExist(Order order) {
if (order.getItems().size() == 0) { //order.getItems().isEmpty()도 고려
throw new IllegalArgumentException("주문 항목이 없습니다.");
}
}
public void validateTotalPrice(Order order){
if((order.getTotalPrice() <= 0)){
throw new IllegalArgumentException("올바르지 않은 총 가격입니다.");
}
}
public void validateCustomerInfoPresent(Order order) {
if (!order.hasCustomerInfo()) {
throw new IllegalArgumentException("주문에 사용자 정보가 필요합니다.");
}
}
2. 예외처리 미적용
public boolean validateOrder(Order order) {
if (isOrderNull(order)) return false;
if (isOrderItemsEmpty(order)) return false;
if (isTotalPriceInvalid(order)) return false;
if (isCustomerInfoMissing(order)) return false;
return true;
}
public boolean isOrderNull(Order order) {
if (order == null) {
log.info("Order 객체가 null입니다.");
return true;
}
return false;
}
public boolean isOrderItemsEmpty(Order order) {
if (order.getItems().size() == 0) { //order.getItems().isEmpty()도 고려
log.info("주문 항목이 없습니다.");
return true;
}
return false;
}
public boolean isTotalPriceInvalid(Order order) {
if((order.getTotalPrice() <= 0)){
log.info("올바르지 않은 총 가격입니다.");
return true;
}
return false;
}
public boolean isCustomerInfoMissing(Order order) {
if (!order.hasCustomerInfo()) {
log.info("사용자 정보가 없습니다.");
return true;
}
return false;
}
2. SOLID에 대하여 자기만의 언어로 정리해 봅시다.
1. SRP - Single Responsibility Principle(단일 책임 원칙)
한 클래스는 딱 하나의 역할만 하자.
하나의 클래스가 너무 많은 일을 하려고 하지 말자.
2. OCP- Open/Closed Principle(개방/폐쇄 원칙)
기존 코드를 고치지 않고, 기능을 확장할 수 있어야 한다.
수정에는 닫혀 있고, 확장에는 열려 있어야 한다.
조건문을 늘리기보다는 새로운 클래스를 추가해 기능을 확장하자.
3. LSP - Liskov Substitution Principle(리스코프 치환 원칙)
부모 타입을 사용하는 곳에 자식 타입을 써도 제대로 작동해야 한다.
부모 클래스의 역할을 자식이 완전히 대체할 수 있어야 한다.
자식 클래스가 부모의 약속을 깨면 안 된다.
4. ISP - Interface Segregation Principle(인터페이스 분리 원칙)
쓸데없는 인터페이스는 나눠서 큰 종합세트를 주지말고 작은 인터페이스 여러개가 좋다
클라이언트가 사용하지 않는 메서드에 의존하게 하지 말자.
하나의 거대한 인터페이스보다는, 작은 인터페이스 여러 개가 좋다.
5. DIP - Dependency Inversion Principle(의존 역전 원칙)
고수준 모듈은 저수준 모듈에 의존하지 말고, 추상(인터페이스)에 의존하자.
핵심 로직(고수준)이 세부 구현(저수준)에 끌려다니면 유연성이 떨어진다.
인터페이스를 사이에 두고 서로 느슨하게 연결하자.
강의
댓글을 작성해보세요.