Study/우아한 테크 코스 / / 2023. 11. 10. 20:37

[우아한 테크 코스] 프리코스 - 3주차, 로또 회고

 


❤️ 서로 PR하기를 원하시는분은 https://github.com/woowacourse-precourse/java-lotto-6/pull/818 여기에 남겨주세요!


👍3주차 목표

3주차는 2주차에서 계획했던 목표인

  1. mvc 패턴에 맞게 유효성 검사하기
  2. public 메소드만 테스트하기


이 두가지에 중점을 뒀다.

이번주에 적용하기 위해서 해당 내용을 정리하여 블로그에 포스팅했는데, 덕분에 이번주차 미션을 해결하는데 도움이 많이 됐다. 특히 private 메소드를 테스트해야 하는 경우라면, 해당 클래스가 너무 많은 책임을 가진것이 아닌지 확인하라는 말에 많은것을 깨달았다.

[해리&션 발표 중, 많이 실수하는 부분]
https://mntdev.tistory.com/90#%ED%95%B4%EB%A6%AC%26%EC%85%98%20%EB%B0%9C%ED%91%9C%20%EB%82%B4%EC%9A%A9%20%EC%A0%95%EB%A6%AC-1

[private 메서드를 테스트해야할까?]
https://mntdev.tistory.com/91

🔍 추가 요구사항

그리고 추가 요구사항들에서 많은 도움을 얻을 수 있었는데 "기능 목록을 재검토한다"를 지켜 클래스를 설계하지 않고 진행하였다. 그렇게 했더니 자연스럽게 설계 과정에서 달라지는 파라미터들을 수정하지 않아도 되어 리펙토링을 하는데 문제가 발생하지 않았고, 더 빠른 시간안에 좋은 코드를 작성할 수 있었다.

함수가 한가지 역할을 하게 하라는 기준에 맞춰 15줄이 넘어가는 경우 함수를 분리해 조금 더 객체지향적인 코드를 작성할 수 있는 쉬운 기준을 가질 수 있었다. 또 나만의 함수가 한가지 기능을 하는지 확인하는 기준을 세울 수 있었는데, 함수명에 and가 들어가야 하는 경우에 해당 함수를 분리하는 기준을 세워 보기도 했다. 나만의 기준으로 인해 함수명을 짓는데에 고민을 많이 했던 것 같다.(메소드가 어떤 역할을 하는지 알기 쉬운건 덤)

🎈 테스트코드의 중요성

테스트를 작성하는 이유는 2주차에 들어가며 약간 알게됐고 이번 주차에 확신을 한 부분이 있다. 바로 SOLID와 연관되어 있는데 OCP를 위반하게 되는 경우 테스트하기 어려운 코드가 발생한다는 것 이었다. 그 이유는 랜덤넘버를 가져와야 하는데, 이와 연관된 테스트하기가 정말 어려웠고, 자연스럽게 OCP를 지켜 개발을 하게 됐다. 그리고 단위 테스트를 통한 빠른 피드백을 통해 해당 클래스에 대한 실패원자성을 보장하는것도 내가 생각한 테스트를 작성하는 이유다.

[테스트와 관련된 나의 생각 정리]
https://mntdev.tistory.com/95

🛠️ 함수형 프로그래밍과 람다

이번 주차에는 저번 미션에서 코드리뷰를 하면서 감명깊게 본 함수형 프로그래밍과 람다를 적절하게 활용해 봐야겠다. 라고 생각했었다. 그 이유는 함수가 하는 일이 명확하기 때문에 가독성이 좋아보였고, 불변이기 때문에 side effect가 발생하지 않는다는 점을 찾아봐서 알게 돼서 활용을 결심했다. 그리고 stream은 종종 IDE가 람다식으로 변환해주기 때문에 사용을 해봤는데 눈에 익어서인지 도입에 큰 어려움은 없었다. 또 java.util.function에 대부분의 경우에 처리할 수 있는 유틸리티를 제공해주었기 때문에 따로 함수형 인터페이스를 직접 구현할 필요는 없었다. 다만, 어떤 경우에 Consumer를 사용하고 Function을 사용하는지만 알면 되어서 그 부분만 숙지하고 리펙토링 하였는데, 사용자의 입력이 잘못된 경우, 계속 반복해서 입력을 받아야 하는데 이때 활용해서 너무 아름다운 코드가 완성돼서 너무 기뻤다. (코딩은 예술인가?)

public void run() {
    ...
    int purchaseAmount = getInputSafely(this::tryInputPurchaseAmount); //람다식을 활용
    ...
}


private <T> T getInputSafely(Supplier<Optional<T>> inputSupplier) { //함수형 인터페이스 활용
    Optional<T> result;
    do {
        result = inputSupplier.get(); // 특정 함수를 실행한다.
    } while (result.isEmpty()); // 만약 결과가 비어있으면 반복
    return result.get(); // 해당 함수 결과 반환
}


private Optional<Integer> tryInputPurchaseAmount() {
    try {
        return Optional.of(inputView.inputPurchaseAmount()); //사용자 입력을 받음
    } catch (IllegalArgumentException e) {
        outputView.displayErrorMessage(e.getMessage()); //오류 발생시 메시지 출력
        return Optional.empty(); //빈 결과 출력
    }
}



[java.util.function 학습자료]
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유