[인프런 워밍업 0기 Day2] 한 걸음 더! 메서드로 코드 재사용해보기!

[인프런 워밍업 0기 Day2] 한 걸음 더! 메서드로 코드 재사용해보기!

!! 해당 글은 독자가 인프런 워밍업 0기를 수강하고 있다는 전제 하에 작성되었습니다 !!

과제 수행에 있어 스프링부트 3.2.2 버전을 사용하고 있다는 점을 미리 알려드립니다!

 

안녕하세요🙌! 인프런 워밍업 2일차 과제입니다!

2일차에는 API를 작성하는 방법에 대해서 배우고 그에 대한 과제를 받았습니다😎

과제를 자세히 살펴보는 도중, 문제 1번과 3번 모두 덧셈을 수행하는 공통로직이 있다는 사실을 발견했습니다!

따라서! 오늘은 제가 한 걸음 더 성장하기 위해 메서드를 통해 공통로직을 처리한 과정을 공유할 예정입니다~

 

️메서드 설계하기

메서드를 만들 때, 제가 중요하다고 생각하는 것은 3가지입니다!

  1. 메서드가 무엇을 할 것인가 (메서드 명)

  2. 메서드가 무엇을 반환할 것인가 (리턴 타입)

  3. 메서드가 무엇을 필요로 하는가 (파라미터)

여기서, 중요한 점은 어떻게는 생각하지 않는다는 것입니다! 🙅‍♂

위의 3가지만 만족한다면 공통로직으로 볼 수 있기 때문에 메소드의 내부 로직은 추후에 생각해도 무방합니다!

 

자, 그렇다면 지금부터 문제 1번과 3번에서 각 절차를 수행해보겠습니다.

첫째, 무엇을 할 것인가?

문제 1번과 3번 모두 2개 이상의 숫자를 더해야 하는 상황입니다! 따라서, 저는 메서드 명을 addNumbers로 정했습니다.

둘째, 무엇을 반환할 것인가?

우리는 두 수를 더 한 값을 반환 받아야 합니다! int와 Inteager 등 다양한 숫자가 가능하겠지만, 저는 Inteager를 택했습니다!

셋째, 무엇을 필요로 하는가?

우리는 숫자를 더하기 위해, 2개 이상의 숫자를 필요로 합니다! 또한, 문제 3번의 경우 몇 개의 숫자가 입력될 지 알 수가 없습니다! 따라서 저는 List<Integer> numbers로 파라미터 값을 설정했습니다.

이제 위의 세 부분을 합치면 제가 만들 메서드는 아래와 같은 형식이 될 것입니다!

public Integer addNumbers(List<Integer> numbers);

💡 int 타입의 경우 List로 받을 수가 없어 Integer를 반환 값으로 설정하였습니다!

 

메서드 구현하기

이제 설계가 끝났으니, 메서드를 구현할 시간입니다! for each문으로 List에 담긴 값을 하나씩 꺼내 더하여 값을 반환만 해주면 구현은 어렵지 않게 끝이 납니다!😎

    public Integer addNumbers(List<Integer> numbers) {
        Integer result = 0;
        for (Integer number : numbers) {
            result += number;
        }
        return result;
    }

자~ 이제 구현이 끝났으니 메서드를 적용해봐야겠죠?

 

메서드 적용하기

문제 3번

먼저, 문제 3번입니다! 3번부터 풀이하는 이유는 1번 문제를 풀며 발생하는 문제 때문입니다!

DTO (데이터를 전송 받고 보내는 객체)

@Getter @Setter
public class NumbersRequest {
    private List<Integer> numbers;
}

Controller

    @PostMapping("/api/v1/calc")
    public Integer addNumbers(@RequestBody NumbersRequest numbersRequest) {
        return addNumbers(numbersRequest.getNumbers());
    }

List<Integer>를 필드 값으로 갖는 NumberRequest를 입력받아 addNumbers()에 필드값을 전달했습니다!

입력받은 숫자가 몇 개던지 메서드 내부에서 값이 잘 합산되어 반환될 것입니다!

 

문제 1번

이번엔, 문제 1번을 해결해보죠! 😎

DTO

@Getter @Setter
public class CalcResponse {
    private int add;
    private int minus;
    private int multiply;
}

Controller

    @GetMapping("/api/v1/calc")
    public CalcResponse calc(Integer num1, Integer num2) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(num1);
        numbers.add(num2);

        CalcResponse response = new CalcResponse();

        response.setAdd(addNumbers(numbers));
        // minus와 multiply도 메서드로 구현해주었습니다!
        response.setMinus(minusNumbers(numbers));
        response.setMultiply(multiplyNumbers(numbers));

        return response;
    }

값을 Integer num1과 Integer num2를 입력받기 때문에 입력 값들을 List로 변환해줘야 합니다.

이렇게 하여도 문제는 없겠지만, 코드가 지저분한 게 영 마음에 들지 않습니다!

그래서, 다음과 같이 코드를 변경해보았습니다!

DTO (Request) 추가

@Getter @Setter
public class CalcRequest {
    private Integer num1;
    private Integer num2;

    public List<Integer> getNumbers() {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(this.num1);
        numbers.add(this.num2);
        return numbers;
    }
}

입력 값을 각각의 값이 아닌 하나의 객체로 변환하여 받고, 내부에 getNumbers()를 구현하여 입력받은 값을 바로 List<Integer>로 변환하여 받도록 하였습니다!

DTO를 적용하면 Controller의 코드가 다음과 같이 바뀌게 됩니다!

    @GetMapping("/api/v1/calc")
    public CalcResponse calc(@ModelAttribute CalcRequest calcRequest) {
        CalcResponse response = new CalcResponse();

        response.setAdd(addNumbers(calcRequest.getNumbers()));
        response.setMinus(minusNumbers(calcRequest.getNumbers()));
        response.setMultiply(multiplyNumbers(calcRequest.getNumbers()));

        return response;
    }

훨씬 간결해졌죠? 참고로 @ModelAttribute쿼리 스트링으로 입력받은 값들을 확인하여 파라미터 타입으로 지정한 타입의 필드 값과 일치하면 자동으로 객체로 변환해주는 Annotation입니다!

이렇게, 메서드를 사용하면 공통로직을 단일 메서드 내부에서 관리할 수 있게 되고, 코드의 반복을 줄일 수 있게 됩니다! 여러분도 코드의 중복이 보인다면 메서드로 한 번 만들어보는 것은 어떨까요? 지금 까지의 내용을 정리하면서 2일차 포스팅을 마치도록 하겠습니다!

 

💡정리 💡

메서드를 설계할 때 중요한 것!

메서드를 설계할 때는 어떻게는 생각하지 말자!

무엇을 하고, 반환하고, 필요한 지 3가지만 충족된다면 공통로직으로 만들 수 있다!

객체 내부에서 변환로직 만들기!

여러 개의 Integer를 Controller에서 List로 직접 변환할 시 코드가 지저분해진다! @ModelAttribute를 활용하여 객체 내부에서 값을 변환하여 반환하자!

댓글을 작성해보세요.