(TIL) 20221027/ 책임에 따른 분리

2022. 10. 27. 03:13TIL(Today I learned)

반응형

🏴󠁩󠁤󠁪󠁷󠁿Facts(한 것) & Findings(배운 것)


가장 최근 TIL이 테스트하기 좋은 코드였다.

그리고 나는 책임 분리가 잘 되어 있는 코드가 테스트하기 좋은 코드라는 말을 했다.

 

 

그렇다면 어떤 코드가 책임 분리가 잘 된 코드일까?

 

 

우선 아래 코드를 보자.

 

public class Calc {
    public String calc(List<Integer> list) {
        int sum = 0;
        for(int i = 0; i < list.size(); i++) {
            sum += list.get(i);
        }
        int product = 1;
        for(int i = 0; i < list.size(); i++) {
            product *= list.get(i);
        }
        
        int result = sum + product;
        
       	if(result > 50) {
            return "Yes";
        else {
            return "No";
        }
    }
}

 

(아무 의미 없는 코드다.)

 

코드를 위에서부터 읽어보자.

 

가장 첫 번째 for문을 보아하니, 모든 값을 더하는 역할을 하는 for문인 것 같다.

그리고 그다음 for문을 보니, 모든 값을 곱하는 역할을 하는 for 문인 것 같다.

마지막 if문에서는 50 초과 여부를 판별한다.

 

어떤가?

책임이 잘 분리가 되어 있는가?

 

책임이 잘 분리 되어 있는지 쉽게 확이 하는 방법은 한눈에 봤을 때,

무엇을 하는 코드인지 확인할 수 있냐 없냐로 어느 정도 구분이 가능하다.

 

 

이 코드가 한눈에 들어올 수도 있다. 코드가 짧기에.

하지만 코드가 이것보다 훨씬 길어진다면, for문마다 주석을 달지 않는 이상,

if문마다 주석을 달지 않는 이상,

 

우리는 어떤 역할, 즉 어떤 책임을 다하고 있는지를 이해하기 위해서 소스코드를 열심히 읽어야 할 것이다.

 

 

다시 아래코드를 보자.

 

import java.util.List;

public class Calc {
    public int getSum(List<Integer> list) {
        return list.stream().mapToInt(i -> i).sum();
    }

    public int getProductNumber(List<Integer> list) {
        return list.stream().reduce(1, (a,b) -> a*b);
    }

    public String checkOver(int offset, int num) {
        if(num > offset) {
            return "Yes";
        } else {
            return "No";
        }
    }

    public String calc(List<Integer> list) {
        int sum = getSum(list);
        int product = getProductNumber(list);
        int result = sum + product;
        return checkOver(50, result); 
    }
}

 

어떤가?

 

메인 로직은 calc 메서드를 보자.

 

 

첫 번째 줄에, 뭔진 몰라도 getSum이란 메서드는 합을 반환하는 함수인 것 같다.

그렇기 때문에 우리는 합을 반환한다고 잠정적으로 생각하고 계속 다음 코드를 읽어 내려갈 수 있다.

 

그 다음, 뭔진 몰라도 getProductNumber 메서드는 곱을 반환하는 함수인 것 같다.

 

그리고 이 둘을 합한 후 

 

마지막으로 check한다.

 

 

다시 좀 더 예쁘게 주석을 달아서 완성하자면,

import java.util.List;

public class Calc {
    /**
     * 주어진 list의 전체 합을 리턴합니다.
     * @param list
     * @return 전체 합
     */
    public int getSum(List<Integer> list) {
        return list.stream().mapToInt(i -> i).sum();
    }

    /**
     * 주어진 list의 전체 곱을 리턴합니다.
     * @param list
     * @return 전체 곱
     */
    public int getProductNumber(List<Integer> list) {
        return list.stream().reduce(1, (a,b) -> a*b);
    }

    /**
     * 주어진 숫자 num이 기준인 offset을 넘는다면 Yes, 아니라면 No를 반환합니다.
     * @param offset 기준 값
     * @param num 비교대상
     * @return offset을 넘는다면 Yes, 아니라면 No
     */
    public String checkOver(int offset, int num) {
        if(num > offset) {
            return "Yes";
        } else {
            return "No";
        }
    }

   
    public String calc(List<Integer> list) {
        int sum = getSum(list);
        int product = getProductNumber(list);
        int result = sum + product;
        return checkOver(50, result); 
    }
}

 

이런 식으로 완성할 수 있다.

 

사실 저 calc메서드가 아무 의미가 없기 때문에 이 코드도 어딘가 좀 이상하긴하다.

 

 

하지만 책임 분리의 예제를 설명할 수 있음에는 틀림없다.

 

 

이렇게 책임 분리를 잘 한 덕분에, 우리는 테스트코드를 작성할 때,

각각의 메서드에 대해서도 테스트를 할 수 있다.

 

 

🏴󠁩󠁤󠁪󠁷󠁿Affirmation(자기 선언)


  • 코틀린 || 스프링 || 리액트 강의 듣기 -> 실패
  • Goole k8s 강의 듣기 -> 실패
  • 알고리즘 문제 풀기 -> 성공
 
 
반응형