워밍업 클럽 2기 BE 클린코드&테스트 day4 과제

워밍업 클럽 2기 BE 클린코드&테스트 day4 과제

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

아래 내용은 위의 인프런 강의를 들으면서 과제 및 내용을 정리해봤습니다.

 

  1. 아래 코드 리팩토링 하기

public boolean validateOrder(Order order){
    if(order.getItems().size() == 0){
        log.info("주문 항목이 없습니다");
    }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. if, else if, else 그리고 중접 if 등으로 인하여 주문의 유효성 조건이 한 눈에 들어오지 않는다

=> early return을 사용해보자

 

  1. 무분별한 getter의 사용(if(order.getItems().size() == 0))

=> 주문에 담긴 상품이 있는지 확인하는 내용인데 굳이 getter를 써야할까?

=> 오히려 order에 item 항목이 있다고 세부 내용을 노출해버리고 있다

=> 의미있는 이름의 메소드를 order에서 그 역할을 책임하도록 해보자

 

  1. 부정어의 사용 if(order.hasCustomerInfo()) / !(order.getTotalPrice() > 0)

=> 부정어를 사용하면 코드의 가독성을 해친다 

=> 1순위 긍정어를 사용하여 메소드 만들 수 있는지 확인

=> 2순위 긍정어를 사용할 수 없다면 메소드명으로 부정을 나타내서 만들어보자

 

위의 내용을 고려한 최종 코드는 아래와 같다

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

    if(order.isLessThanOrEqualToZero()){
        log.info("올바르지 않은 총 가격입니다");
        return false;
    }

    if(order.isEmptyCustomerInfo()){
        log.info("사용자 정보가 없습니다");
        return false;
    }
    return true;
}
public class Order{
    private List<Item> items;

    public boolean isEmptyOrderItem(){
        return order.getItems().size() == 0;
    }
    public boolean isLessThanOrEqualToZero(){
        return order.getTotalPrice() <= 0
    };
    public boolean isEmptyCustomerInfo(){
        return !hasCustomerInfo();
    }

    public double getTotalPrice(){...}
    public boolean hasCustomerInfo(){...}
}

  1. SOLID에 대하여 자기만의 언어로 정리

  • SRP

클래스가 변경될 이유는 단 하나다!!

클래스 설계 시, 하나의 관심사로 응집하여 구현하도록 하자

  • OCP

기존 코드의 변경 없이, 기능 추가하도록 설계가 되어야 한다

 다형성을 이용하여 클라이언트 코드의 변경 없이 구현체를 쉽게 변경이 가능하다

  • LSP

부모 클래스에서 정의한 스펙을 자식 클래스에서도 지켜야 한다

instance of로 타입 체크하여 특정 타입에 대해서만 처리가 필요하다는 건 LSP를 위반한 사례이다!!

  • ISP

SRP와 비슷하게 인터페이스 또한 한 가지 책임을 가지도록 분리를 잘해야 한다

  • DIP

클래스 참조 시, 추상화 레벨이 높은 인터페이스, 추상클래스, 상위 클래스를 참조하도록 하자

코드에 구현체가 드러나게 되면 기능 변경시, 클라이언트 코드의 변경이 생기므로

추상화 레벨이 높은 인터페이스 등을 메소드 파라메터, 필드, 리턴타입으로 활용하도록 하자

댓글을 작성해보세요.

채널톡 아이콘