티스토리 뷰

experiences/refactoring

2. 목표 설명

lingi04 2021. 12. 22. 22:36

앞서 intro에서 refactoring 시 달성할 목표를 몇가지 적어보았다.

  1. 한 메서드는 인덴트를 하나만
  2. else 예약어 사용을 자제하자
  3. 한 가지 메소드는 한 가지 일만
  4. 지역변수를 없애보자

말로만 하면 이해하기 어려우니 예시를 들어 알아보자. 예시는 유튜브에 박재성님의 우아한테크세미나 190425 TDD 리팩토링을 참고했다.

아래와 같은 코드를 가지고 목표를 어떻게 달성할지 알아보겠다.

public class StringCalculator{
    public static int splitAndSum(String text){
        int result = 0;
        if(text == null || text.isEmpty()){
            result == 0;
        }else{
            String[] values == text.split(",|:");
            for(String value : values){
                result += Integer.parseInt(value);
            }
        }

        return result;
    }
}

1. 한 메서드는 인덴트를 하나만

첫번째 목표는 인덴트를 하나만 사용하는 것이다. 인덴트는 iffor를 사용할 때 생성이 된다. 프로그래밍을 할때 iffor는 빼놓을 수 없는 중요한 요소이다. 하지만 너무 많이 사용하면 코드를 이해 하기 힘들게 만들기도 한다. 로직을 적절히 수정해서 인덴트를 줄여보자.

예로 들었던 코드는 아래와 같이 수정할 수 있다.

public class StringCalculator{
    public static int splitAndSum(String text){
        int result = 0;
        if(text == null || text.isEmpty()){
            return 0;
        }

        String[] values == text.split(",|:");

        return sum(values);
    }

    private static int sum(string[] values){
        int result = 0;
        for(String value : values){
            result += Integer.parseInt(value);
        }
        return result;
    }
}

우선 예외 조건이 명확해 졌다. 그리고 조건문 안에 있던 반복문을 꺼내 함수로 만들어 전체 인덴트를 줄임과 동시에 함수의 재사용성이 올라갔다. 코드가 조금 길어지긴 했지만 좀 더 이해하기가 쉬워졌다(고 생각한다).

2. else 예약어 사용을 자제하자

사실 if의 조건에 걸리지 않으면 else는 무조건 실행되는 부분 이기 때문에 꼭 필요한 상황이 아니면 안쓰는 것이 조금 더 깔끔한 코드를 만들어 준다고 생각한다. 앞선 1번 처럼 종료조건을 정의하고 그때 그때 return을 해 주면 뒷부분에선 진짜 필요한 로직에만 집중하면 되기때문에 프로그래밍 하기 쉽고 읽고 이해하는 것도 수월해진다고 생각한다.

3. 한 가지 메소드는 한 가지 일만

클래스도 마찬가지 이지만 메서드도 한가지 일만 해야 한다고 생각한다. 두 가지 이상 일을 하면 변경하기도 힘들고 변경으로 인한 사이드이펙트가 발생할 확률이 굉장히 높아진다. 그러므로 한 메서드가 두 가지 이상의 일을 한다면 하는 일에 따라 분리하여 응집도를 높여주는게 좋다고 생각한다. 이렇게 하면 (앞선 경우와 마찬가지로) 이해하기 쉬워지고 변경에 유연하게 대처할 수 있으며 메서드의 재사용성이 올라간다.

public class StringCalculator{
    public static int splitAndSum(String text){
        int result = 0;
        if(text == null || text.isEmpty()){
            return 0;
        }
        String[] values = text.split(",|:");
        int[] numbers = toInts(values);
        result = sum(numbers);

        return result;
    }

    private static int[] toInts(String[] values){
        int[] numbers = new int[values.length];
        for(int i = 0; i < values.length; i++>){
            numbers[i] = Integer.parseInt(values[i]);
        }

        return numbers;
    }

    private static int sum(int[] numbers){
        int result = 0;
        for(int number: numbers){
            result += number;
        }

        return result;
    }


}

4. 지역변수를 없애보자

마지막은 '단순히 잠시동안 값을 저장하기 위해 사용하는 지역변수를 제거해보자.' 인데 살짝 고개가 갸우뚱해진다. 앞선 세 가지 목표는 적용했을 때 개선되는 점이 확 와닿았지만 마지막 목표는 그렇지 않았다. 너무 사용을 안하면 오히려 코드를 읽기 힘들어 지지 않을까... 하는 생각이 든다.

그래도 뭐 지역변수를 남발하는 것 역시 좋지 않아 보이니 궂이 필요 없어 보이는 변수들은 코드 가독성을 헤치지 않는 선에서 없애보자.

public class StringCalculator{
    public static int splitAndSum(String text){
        int result = 0;
        if(text == null || text.isEmpty()){
            return 0;
        }

        return sum(toInts(text.split(",|:")));;
    }
    ...

'experiences > refactoring' 카테고리의 다른 글

4. 적용 사례2  (0) 2021.12.22
3. 적용 사례  (0) 2021.12.22
1. intro  (0) 2021.12.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday