인프런 워밍업 클럽 3기 BE 클린코드 & 테스트

[인프런 워밍업 클럽 BE 3기 클린코드 & 테스트] Day4 미션

taey 2025. 3. 7. 21:36

Day4 미션

1. 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.
2. 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. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.

import java.util.List;
import java.util.logging.Logger;

// 주문 도메인
public class Order {

    private final OutputHandler outputHandler = new OutputHandler();

    private Customer customer;
    private List<Item> items;
    private final int totalPrice;

    public Order(Customer customer, List<Item> items) {
        this.customer = customer;
        this.items = items;
        this.totalPrice = items.stream().mapToInt(Item::getPrice).sum();
    }

    public boolean validateOrder(Order order) {
        if (order.hasNoItems()) {
            outputHandler.printErrorMessage("주문 항목이 없습니다.");
            return false;
        }

        if (order.hasNoCustomerInfo()) {
            outputHandler.printErrorMessage("사용자 정보가 없습니다.");
            return false;
        }

        if (order.isNotTotalPricePositive()){
            outputHandler.printErrorMessage("올바르지 않은 총 가격입니다.");
            return false;
        }

        return true;
    }

    // 구매 물품이 존재하지 않는지 확인
    private boolean hasNoItems() {
        return this.items.isEmpty();
    }

    // 사용자 정보가 존재하지 않는지 확인
    private boolean hasNoCustomerInfo() {
        if(customer == null){
            return true;
        }
        return customer.isNullName();
    }

    // 구매 가격이 0보다 큰지 (정상 구매)인지 확인
    private boolean isNotTotalPricePositive() {
        return !(this.totalPrice > 0);
    }
}

// 상품 도메인
class Item {
    private String name;
    private int price;

    public int getPrice() {
        return price;
    }
}

// 사용자 도메인
class Customer {
    private String name;

    public Customer(String name) {
        this.name = name;
    }

    public boolean isNullName() {
        return name == null;
    }
}

// 출력 핸들러
class OutputHandler {

    private final Logger log = Logger.getLogger(OutputHandler.class.getName());

    public void printErrorMessage(String message) {
        log.info(message);
    }
}

 


2. SOLID에 대하여 자기만의 언어로 정리해 봅시다.

  • SRP (Single Responsibility Principle) : 단일 책임 원칙
    • 하나의 클래스에는 하나의 책임만 가져야 한다. (하나의 역할)
    • 높은 응집도, 낮은 결합도를 추구한다.
  • OCP (Open-Closed Principle) : 개방 폐쇄 원칙
    • 확장은 열리고, 수정에는 닫힌다.
    • 기능 수정 시에 코드 변경이 필요하면 안된다.
  • LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
    • 인터페이스 또는 추상 클래스를 활용한다.
    • 부모 클래스 자리에 자식 클래스가 들어가도 실행되어야 한다.
    • 자식 클래스에 특화된 기능을 만들면 리스코프 치환 원칙을 지키기 어렵다.
  • ISP (Interface Segregation Principle) : 인터페이스 분리 원칙
    • 하나의 인터페이스에서는 하나의 기능만 하도록 한다.
    • ex) 초기화 기능, 실행 기능을 분리하자
  • DIP (Dependency Inversion Principle) : 의존성 역전 원칙
    • 고수준 모듈과 저수준 모듈 구체화 모듈이 아닌 추상화에 의존
    • 저수준 모듈을 쓸 때, 직접 사용하지 말고, 인터페이스를 활용해야 한다.

 

 

출처 : 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  [섹션4]