[우아한테크코스 7기] 1주차 프리코스 회고

dev_yuni·2024년 10월 22일
8

우아한테크코스

목록 보기
1/4
post-thumbnail

들어가기 전에!

3시에 미션이 나오고 기대 반 걱정 반으로 문제를 읽었습니다. 처음에는 '읭..? 생각보다 간단한 것 같은데 ?' 라고 생각했는데 그러다가 눈물 펑펑 흘렸습니다.
이번 1주차 회고에서는 어떤 목표를 가지고 어떻게 접근했는지, 목표를 달성했다고 생각하는지 적어보려 합니다.

제 목표는요!

  1. 객체 지향을 준수해서 각 클래스와 메서드가 한 가지의 역할을 하게 하자.
  2. 다른 사람들이 봤을 때 '아 이런 역할을 하는 메서드구나'하고 이해할 수 있게 메서드명을 명확히 하자.
  3. 코드 한 줄 한 줄 이유를 생각하고 구현하자.
  4. 완성하자.

문제는요!

[문자열 덧셈 계산기]

기능 요구사항

입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다.

쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.
◦ 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6

앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다.
◦ 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.

사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

입출력 요구 사항

입력 : 구분자와 양수로 구성된 문자열

1,2,3

출력 : 덧셈 결과

결과 : 6

실행 결과 예시

덧셈할 문자열을 입력해 주세요.
1,2:3
결과 : 6

이렇게 진행했어요!

문제 파악

노션에 문제를 읽으면서 생각했던 것들을 다 적었습니다. 처음엔 구분자의 정확한 정의가 무엇인지 궁금해서 찾아봤습니다.

구분자는 데이터를 구분하거나 분리하는 데 사용하는 문자 또는 기호이다.

기본 구분자는 이미 정해져 있기 때문에 문자열을 나누는데에 어려움이 없었고, 커스텀 구분자는 정해져 있지 않기에 어떤 기준으로 사용할 수 없는 구분자를 정해야 할지 생각했습니다.
그래서 정해진 저의 규칙은 아래와 같습니다. 아래 규칙 이외 문자열은 사용이 가능하게 하였습니다.

커스텀 구분자 규칙

  1. //와 \n는 커스텀 구분자를 정하기 위한 형식이므로 혼동을 줄 수 있기 때문에 사용할 수 없다.
  2. 공백 : 공백으로 이루어진 구분자는 사용할 수 없다.
  3. 숫자 : 숫자를 계산해야 하기 때문에 구분자로 사용할 수 없다.

역할 분리

한 가지 역할의 목표를 위해 어떤 역할이 필요한 지 먼저 나누었습니다.

  • 문자열을 입력받고 결과를 출력하는 역할
  • 입력받은 문자열을 검증하는 역할
  • 문자열에서 구분자를 찾는 역할
  • 구분자로 나눈 후 숫자를 찾는 역할
  • 덧셈 연산하는 역할

테스트 예제

여러 예제를 고민하며 생각날 때마다 테스트 예제를 추가해서 정리했습니다.
이렇게 고민하니 추가적으로 어디서 예외 처리를 하면 좋을 지 알 수 있었던 것 같습니다.

입력값기댓값
“”0
1,2,36
1,2:36
//;\n1;2:3,410
//;\n11
//;\n1;2;3
:1:2:36
//\n12*36
1::2,36
//;\n1;;2;36
//;\n//&\n1;2&3;410
//\n123사용할 수 없는 커스텀 구분자 사용 예외 발생
\n1;2;3커스텀 구분자 형식 예외 발생
-1,2,3구분자로 나누었을 때 음수 예외 발생
//\n1a*3구분자로 나누었을 때 문자열 예외 발생

구현

구현한 내용은 깃허브 PR 링크를 걸어두겠습니다!
만약.. 누가 본다면 리뷰도 환영입니다 :)

코드 구경 하러 가기 👀

제가 배운 건요!

정규식

숫자와 구분자를 많이 다뤄야하는 문제이다보니 정규식은 빠질 수 없다고 생각했습니다. 저는 숫자나 정해진 문자열만 정규식을 사용하려 하였습니다. 이유는 정규식은 정말 다양하고, 형식이 정해져 있는 것도 있어 편리하지만 저 조차도 이게 어떤 걸 표현하는 정규식인지 한 눈에 알아보기 어려웠기 때문입니다. 아직 정규식에 대해서 잘 모르는 다른 사람이 봤을 때도 어떤 정규식인지 알아볼 수 있는 것만 사용했습니다. 아래는 제가 정규식을 공부할 때 도움을 받았던 블로그입니다!

정규 표현식 이해하기

여러 상황 고려

처음에는 기본 구분자와 커스텀 구분자를 추출하고 그걸로 정규식을 만들어서 구분하면 될 것이라고 생각했습니다. 하지만 '나중에 기본 구분자가 추가된다면? 커스텀 구분자로 사용할 수 없는 게 추가된다면? 커스텀 구분자를 나누는 형식을 바꾸고 싶으면 어떻게 하지?' 라는 생각을 하게 되었습니다.
이렇게 다양한 상황을 생각하는 것이 코드를 유지보수할 때 불편한 상황을 빠르게 파악할 수 있다는 것을 깨닫게 해주었습니다.

Enum을 효율적으로

열거된 상수를 사용해서 이름을 명확하게 나타낼 수 있다는 장점을 이용하여 기본 구분자와 사용할 수 없는 커스텀 구분자를 Enum 클래스로 만들었습니다. 하지만 선언한 상수를 확인하기 위해서 조건문과 반복문이 필요했고 '뭔가 더 좋게 활용할 수 있을 것 같은데..' 라는 생각이 들었습니다. 그래서 Enum 클래스에 대해서 알아보고 메서드를 사용하니 더 깔끔한 코드를 짤 수 있었습니다. (엄청난 효과를 봤습니다!!!)

// 수정 전 코드
...
private boolean containsValidDelimiter(String input) {
    for (Delimiter delimiter : Delimiter.values()) {
        if (delimiter == Delimiter.COMMA || delimiter == Delimiter.COLON) {
            if (input.contains(delimiter.getDelimiter())) {
                return true;
            }
        }
    }
    return false;
}
...

// 수정 후 코드
...
private boolean containsValidDelimiter(String input) {
    return Delimiter.getBasicDelimiters()
    				.stream()
            		.anyMatch(input::contains);
}
...

Java Enum 활용기 - 우아한기술블로그

Util과 Service

여러 PR을 구경하니 MVC를 사용하신 분들이 많았습니다. 저는 MVC를 쓰지 않아서 패키지 구조에 대한 고민을 하게 되었습니다.
처음에는 controller를 제외한 모든 클래스를 service에 포함해야 한다고 생각했지만, 구분자와 숫자를 추출하는 기능이 상태를 가지거나 의존성을 필요로 하지 않는다는 점에서 빈 등록이 불필요하다고 판단했습니다.
이렇게 분리한 덕분에 필요에 따라 재사용이 가능해졌습니다.
하지만 단순히 공통 기능을 util로 묶는 것보다, 책임과 역할에 맞게 적절히 분리하는 것이 중요하다는 점을 깨달았고 너무 광범위하게 사용할 경우 단일 책임 원칙에 어긋날 수 있기 때문에, util의 활용은 신중하게 결정해야 한다는 것을 배울 수 있었습니다.

공부하면서 참고했던 블로그입니다!
Util 클래스

저의 느낀 점은요!

앞서 적었던 목표를 달성했는지 생각해보면 아쉬웠던 부분이 많은 것 같습니다.
역할을 분리해놨음에도 계속 해서 중복되는 역할을 가지거나 여러 역할을 가지고 있는 것들도 있는 것 같습니다.
객체 지향에 대해서 완벽히 이해하지 않고 역할에만 초점을 두니 이런 일이 일어나지 않았나 생각합니다..🥺
메서드명은 하는 역할을 명확하게 명시하기 위해서 노력했습니다.
생각보다 메서드명 짓기가 어렵다는 걸 알게되었습니다.(제가 영어에 약한걸지도..)
만약 코드를 보다가 '얘가 무슨 역할을 하는 거지..?' 하는 생각이 든다면 바로 혼내주시면 감사하겠습니다!
이번 미션을 하면서 다양한 지원자분들의 PR도 구경을 많이 했습니다. 보면서 대단하다고 생각하신 분들이 많았습니다.
그런 분들과 모여서 소통하며 많이 배워갈 수 있을 거라고 생각하니 정말 기대가 됩니다!

다음엔 이렇게 할게요!

객체 지향에 대해서 요즘 많이 알아보고 관련 서적도 읽어보고 있습니다. 추천해주셔도 좋습니다!!
이번 2주차 미션에서는 1주차 때 아쉬웠던 부분을 보완해서 객체 지향적이고 더 나은 코드를 위해 최선을 다하겠습니다! 화이팅👊🏻

profile
꾸준히 성장하는 백엔드 개발자

0개의 댓글