[인프런 워밍업 0기 Day2] 한 걸음 더! 메서드로 코드 재사용해보기!
!! 해당 글은 독자가 인프런 워밍업 0기를 수강하고 있다는 전제 하에 작성되었습니다 !!
과제 수행에 있어 스프링부트 3.2.2 버전을 사용하고 있다는 점을 미리 알려드립니다!
안녕하세요🙌! 인프런 워밍업 2일차 과제입니다!
2일차에는 API를 작성하는 방법에 대해서 배우고 그에 대한 과제를 받았습니다😎
과제를 자세히 살펴보는 도중, 문제 1번과 3번 모두 덧셈을 수행하는 공통로직이 있다는 사실을 발견했습니다!
따라서! 오늘은 제가 한 걸음 더 성장하기 위해 메서드를 통해 공통로직을 처리한 과정을 공유할 예정입니다~
⚙️메서드 설계하기
메서드를 만들 때, 제가 중요하다고 생각하는 것은 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
를 활용하여 객체 내부에서 값을 변환하여 반환하자!
댓글을 작성해보세요.