클린코드 적용하기 - 5. 형식 맞추기

Jaden Kim·2021년 10월 3일
0

이번에 적용할 규칙은 아래와 같다

친화도가 높을수록 코드를 가까이 배치한다.
함수 호출 종속성은 아래 방향으로 유지한다.

아래의 코드는

["number" : CardNumber.TWO, "type" : CardType.CLOVER]

와 같이 카드 정보가 Map으로 주어질 경우,
해당 정보에 맞게 Card를 생성하는 로직이다.
(CardNumber, CardType은 CardDetail 인터페이스의 구현체이다.)

public class CardFactory {


    public static Card generateCard(final CardDetailGenerator generator) throws NoTypeKeyException, NoNumberKeyException {
        Map<String, CardDetail> cardDetailMap = generator.generate();
        CardNumber number = getCardNumberFrom(cardDetailMap);
        CardType type = getCardTypeFrom(cardDetailMap);

        return Card.of(number, type);
    }
    

    private static CardNumber getCardNumberFrom(Map<String, CardDetail> cardDetailMap) throws NoNumberKeyException {
        CardDetail cardNumber = cardDetailMap.get("number");
        validateCardNumberNull(cardNumber);
        validateInstanceOfCardNumber(cardNumber);

        return (CardNumber) cardNumber;
    }
   
    private static CardType getCardTypeFrom(Map<String, CardDetail> cardDetailMap) throws NoTypeKeyException {
        CardDetail cardType = cardDetailMap.get("type");
        validateCardTypeNull(cardType);
        validateInstanceOfCardType(cardType);

        return (CardType) cardType;
    }
    
    
    private static void validateCardNumberNull(CardDetail cardNumber) throws NoNumberKeyException {
        if(cardNumber == null) {
            throw new NoNumberKeyException();
        }
    }
    
    private static void validateInstanceOfCardNumber(CardDetail cardNumber) {
        if(!cardNumber.getClass().equals(CardNumber.class)) {
            throw new IllegalValueOfNumberKeyException();
        }
    }

    private static void validateCardTypeNull(CardDetail cardType) throws NoTypeKeyException {
        if(cardType == null) {
            throw new NoTypeKeyException();
        }
    }

    private static void validateInstanceOfCardType(CardDetail cardType) {
        if(!cardType.getClass().equals(CardType.class)) {
            throw new IllegalValueOfTypeKeyException();
        }
    }
}

초기에는 위와 같이 추상화 수준에 따라 메서드의 순서를 정렬해서 작성했다.
구조적으로는 직관적이긴 하나, 읽기는 불편한 코드이다.
호출한 메서드의 코드를 읽기 위해서는 해당 추상화 수준의 메서드들을 흝으면서 찾아야 한다.

호출한 메서드와 호출 대상 메서드는 친화도가 매우 높은 관계이다.
해당 메서드들을 세로 방향으로 가까이 붙이는 것이 적절하다.

public class CardFactory {
    public static Card generateCard(final CardDetailGenerator generator) throws NoTypeKeyException, NoNumberKeyException {
        Map<String, CardDetail> cardDetailMap = generator.generate();
        CardNumber number = getCardNumberFrom(cardDetailMap);
        CardType type = getCardTypeFrom(cardDetailMap);

        return Card.of(number, type);
    }

    private static CardNumber getCardNumberFrom(Map<String, CardDetail> cardDetailMap) throws NoNumberKeyException {
        CardDetail cardNumber = cardDetailMap.get("number");
        validateCardNumberNull(cardNumber);
        validateInstanceOfCardNumber(cardNumber);

        return (CardNumber) cardNumber;
    }

    private static void validateCardNumberNull(CardDetail cardNumber) throws NoNumberKeyException {
        if(cardNumber == null) {
            throw new NoNumberKeyException();
        }
    }

    private static void validateInstanceOfCardNumber(CardDetail cardNumber) {
        if(!cardNumber.getClass().equals(CardNumber.class)) {
            throw new IllegalValueOfNumberKeyException();
        }
    }

    private static CardType getCardTypeFrom(Map<String, CardDetail> cardDetailMap) throws NoTypeKeyException {
        CardDetail cardType = cardDetailMap.get("type");
        validateCardTypeNull(cardType);
        validateInstanceOfCardType(cardType);

        return (CardType) cardType;
    }

    private static void validateCardTypeNull(CardDetail cardType) throws NoTypeKeyException {
        if(cardType == null) {
            throw new NoTypeKeyException();
        }
    }

    private static void validateInstanceOfCardType(CardDetail cardType) {
        if(!cardType.getClass().equals(CardType.class)) {
            throw new IllegalValueOfTypeKeyException();
        }
    }
}

순서를 적절히 변경했을 때, 코드를 읽기가 훨씬 수월해진다.

0개의 댓글