인프런 스터디 미션 4

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

사용자가 생성한 '주문'이 유효한지를 검증하는 메서드.

Order는 주문 객체이고, 필요하다면 Order에 추가적인 메서드를 만들어도 된다. (Order 내부의 구현을 구체적으로 할 필요는 없다.)

필요하다면 메서드를 추출할 수 있다.

변경 전

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. 주문항목이 존재하는지 판단하는 부분이다.

getter를 사용하는 부분을 hasNoItems() 메서드로 변경하고 항목이 존재하지 않는다면 false를 리턴하도록 리팩토링한다.

그 뒤 else 부분은 필요 없으므로 else는 제거한다.

2. 총 가격이 유효한지 판단하는 부분이다.

사용자 정보 유효성을 판단하는 if문까지 같이 있기 때문에 우선 이 부분을 분리하고

getter를 사용하는 부분을 wrongTotalPrice() 메서드로 변경한다. 

그 뒤의 else if와 else 또한 필요 없으므로 제거한다.

3. 사용자 정보가 유효한지 판단하는 부분이다.

두 번째에서 분리한 if문을 !가 사용되고 있는데 이것을 부정의 의미를 가진 hasNotCoustomerInfo() 메서드로 변경한다.

마지막으로 이 3개의 if문들을 의미 단위로 공백을 준 뒤, 마지막에 if문에 걸리는 것이 없는 경우 true를 리턴 할 수 있도록 return true를 한다.

변경 후

public boolean validateOrder(Order order) {
        if (order.hasNoItems()) {
            log.info("주문 항목이 없습니다.");
            return false;
        }
        
        if (order.wrongTotalPrice()) {
            log.info("올바르지 않은 총 가격입니다.");
            return false;
        }
        
        if (order.hasNotCustomerInfo()) {
                log.info("사용자 정보가 없습니다.");
                return false;
            }
        return true;
    }

 

 

 

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

SRP : Single Responsiblity Principle

단일 책임 원칙 말 그대로 책임을 하나만 갖는다는 것이다. 하나의 책임은 하나의 역할을 갖는다는 의미와 같다.

ex) 옛날 레노버 키보드를 보면 빨콩이라고 키보드에서 마우스 역할을 하는 트랙 포인터가 달려 있다. 현재는 키보드와 마우스를 따로 분리한 것이 더 효율적이다.

OCP : Open-Closed-Principle

개방-폐쇄 원칙으로 확장에는 열려 있고 변경에는 닫혀 있다.

ex) 기능의 확장은 한 클래스 내의 메서드 추가로 가능하지만 기능의 변경은 클래스 내에 존재하는 메서드의 내용을 변경하는 일이기 때문에 기존의 코드가 변경된다.

LSP : Liskov Substitution Principle

리스코프 교체 원칙으로 상속 구조에서 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있다.

ex) 부모 클래스 내에 잡기, 때리기, 뛰기 3개의 기능을 하는 메서드가 있을 때 어떤 한 자식 클래스에서 잡기, 때리기, 눕기라는 부모 클래스와는 다른 메서드가 존재할 경우 예외가 발생할 수 있다.

ISP : Interface Segregation Principle

인터페이스 분리원칙으로 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.

ex) 어떤 인터페이스를 구현한 구현체가 2개가 있다. 그런데 한 구현체에서는 인터페이스 내의 기능들을 모두 사용하지만, 나머지 한 구현체는 인터페이스 내의 기능 중 단 한 가지 기능만을 사용한다. 이를 해결하기 위해 인터페이스를 필요한 기능 단위로 분리한 뒤 구현체에 필요한 인터페이스들을 상속시켜주면 된다.

DIP : Dependency Inversion Principle

의존성 역전 원칙으로 상위 모듈은 하위 모듈에 의존하면 안 되며, 둘 다 추상화에만 의존해야 한다.

하위 모듈이 변경되어도 상위 모듈에는 영향이 가지 않는다.

ex) 스마트폰이라는 상위 모듈이 존재할 때 스마트폰은 어플이라는 인터페이스를 통해 다양한 기능의 어플들을 사용할 수 있다.

지도 어플, 금융 어플, 게임 어플 등의 하위 모듈은 어플이라는 인터페이스를 통해 구체화된다.

 

 

 

 

댓글을 작성해보세요.

채널톡 아이콘