인프런 워밍업 클럽 4기 BE - 미션 Day 4

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

Readable Code: 읽기 좋은 코드를 작성하는 사고법

미션 Day 4


1. [섹션 3. 논리, 사고의 흐름] 내용을 중심으로 읽기 좋은 코드로 리팩토링

사용자가 생성한 '주문'이 유효한지를 검증하는 메서드.
Order는 주문 객체이고, 필요하다면 Order에 추가적인 메서드를 만들어도 된다. (Order 내부의 구현을 구체적으로 할 필요는 없다.)
필요하다면 메서드를 추출할 수 있다.

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

public boolean validateOrder(Order order) {
    if (hasNoItems(order)) return false;
    if (hasInvalidTotalPrice(order)) return false;
    if (hasNoCustomerInfo(order)) return false;

    return true;
}

private boolean hasNoItems(Order order) {
    if (order.getItems().isEmpty()) {
        log.info("주문 항목이 없습니다.");
        return true;
    }
    return false;
}

private boolean hasInvalidTotalPrice(Order order) {
    if (order.getTotalPrice() <= 0) {
        log.info("올바르지 않은 총 가격입니다.");
        return true;
    }
    return false;
}

private boolean hasNoCustomerInfo(Order order) {
    if ((order.hasNoCustomerInfo()) {
        log.info("사용자 정보가 없습니다.");
        return true;
    }
    return false;
}
public class Order {
    public boolean hasCustomerInfo() {
        // 로직
    }

    //추가
    public boolean hasNoCustomerInfo() {
        return !hasCustomerInfo();
    }
}

Early return, 메서드 추출해 validateOrder 추상화 레벨 일관화, 공백 사용으로 가독성 향상, ! 피하기


2. SOLID 정리

S - SRP 단일 책임 원칙 (Single Responsibility Principle)

하나의 클래스는 하나의 책임(관심사, 역할)만 가져야 한다.

이 객체는 딱 하나의 이유로만 바뀌는가?

예) Order 클래스

  • 주문 목록 저장, 총 금액 계산, 주문 상태 변경만 존재 -> OK

  • 결제, 이메일 전송 로직 포함 -> NOT GOOD


O- OCP 개방-폐쇄 원칙 (Open-Closed Principle)

기능은 확장 가능하게 열어두되(open) - 기존 코드는 수정 없이 닫아둔다(closed)

다형성, 추상화 등을 활용, 기존 코드의 수정 없이 새로운 요구사항을 반영할 수 있어야 한다.

  • 대표적 위반 패턴) if else~


L- LSP 리스코프 치환 원칙 (Liskov Substitution Principle)

부모 클래스를 사용하는 곳에 자식 클래스를 넣어도 문제가 없어야 한다.

자식 클래스가 부모 클래스의 책임을 준수하고, 부모처럼 행동해야 한다.

  • 부모의 기능을 자식이 무시하거나 예외를 던질 시 LSP 위반

    (기능을 추가하더라도 기존 부모의 기능을 제대로 지켜야 함)


I - ISP 인터페이스 분리 원칙 (Interface Segregation Principle)

인터페이스는 클라이언트가 필요한 기능만 가지도록 나눠야 한다.

여러 기능이 섞인 인터페이스에 의존하면 필요하지 않는 메서드까지 강제로 구현하게 된다.


D- DIP 의존성 역전 원칙 (Dependency Inversion Principle)

구현체에 직접 의존하지 말고 추상화에 의존해야 한다.

저수준 모듈에 에 직접적으로 의존하면 변경 시 고수준 모듈에 영향을 미친다.

  • 인터페이스나 추상 클래스를 통해 의존성 연결

댓글을 작성해보세요.

채널톡 아이콘