개발노트/우아한테크코스

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

flinter 2024. 10. 27. 19:32
728x90

 

이번에 우아한테크코스를 지원하면서 참가하게 된 프리코스 1주차 과제 진행 사항을 다시 되돌아 보고자 한다.

프리코스 1주차 과제

학습 목표

  • Git, GitHub, IDE 등 실제 개발을 위한 환경에 익숙해진다.
  • 교육 분야에 맞는 프로그래밍 언어를 사용하여 간단한 문제를 해결한다.

프리코스 진행 방식

진행 방식

  • 미션은 과제 진행 요구 사항, 기능 요구 사항, 프로그래밍 요구 사항 세 가지로 구성되어 있다.
  • 세 개의 요구 사항을 만족하기 위해 노력한다.
  • 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다.
  • 기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다.
  • 매주 진행할 미션은 화요일 오후 3시부터 확인할 수 있으며, 다음 주 월요일까지 구현을 완료하여 제출해야 한다.
  • 제출은 일요일 오후 3시부터 가능하다.
  • 정해진 시간을 지키지 않을 경우 미션을 제출하지 않은 것으로 간주한다.
  • 종료 일시 이후에는 추가 푸시를 허용하지 않는다.

미션 제출 방법

  • 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다.
  • GitHub을 활용한 제출 방법은 프리코스 과제 제출 문서를 참고해 제출한다.
  • GitHub에 미션을 제출한 후 우아한테크코스 지원 플랫폼에 PR 링크를 포함하여 최종 제출한다.
  • 자세한 안내는 제출 가이드를 참고한다.
  • 과제를 수행하면서 느낀 점, 배운 점, 많은 시간을 투자한 부분 등 자유롭게 작성한다.

과제 제출 전 체크 리스트

  • 기능을 올바르게 구현했더라도 요구 사항에 명시된 출력 형식을 따르지 않으면 0점을 받게 된다.
  • 기능 구현을 완료한 후 아래 가이드에 따라 모든 테스트가 성공적으로 실행되는지 확인한다.
  • 테스트가 실패하면 점수가 0점이 되므로 제출하기 전에 반드시 확인한다.
  • 테스트 실행 가이드 IntelliJ IDEA와 같은 IDE에서 Java21로 실행되는지 확인한다.
  • 터미널에서 Mac 또는 Linux 사용자의 경우 ./gradlew clean test 명령을 실행하고, Windows 사용자의 경우 gradlew.bat clean test 또는 ./gradlew.bat clean test 명령을 실행할 때 모든 테스트가 아래와 같이 통과하는지 확인한다.

BUILD SUCCESSFUL in 0s


문자열 덧셈 계산기

과제 진행 요구 사항

  • 미션은 문자열 덧셈 계산기 저장소를 포크하고 클론하는 것으로 시작한다.
  • 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가한다.
  • Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가한다.
  • AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성한다.
  • 자세한 과제 진행 방법은 프리코스 진행 가이드 문서를 참고한다.

기능 요구 사항

  • 입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다.
  • 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.
    • 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다.
  • 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다.
    • 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

입출력 요구 사항

입력

  • 구분자와 양수로 구성된 문자열

출력

  • 덧셈 결과

결과 : 6

실행 결과 예시

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

프로그래밍 요구 사항

  • Java21에서 실행 가능해야 한다.
  • 프로그램 실행의 시작점은 Application의 main()이다.
  • build.gradle 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.
  • 프로그램 종료 시 System.exit() 또는 exitProcess()를 호출하지 않는다.
  • 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다.
  • 자바 코드 컨벤션을 지키면서 프로그래밍한다.

라이브러리

  • camp.nextstep.edu.missionutils에서 제공하는 Console API를 사용하여 구현해야 한다.
  • 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.ConsolereadLine()을 활용한다.

요구기능 정의하기

문자열 덧셈 프로그램을 구현하기 위해 필요한 기능과 과제에서 제시하지 않은 상황에 대한 제약조건을 정의하였다.

입력 기능

  • 문자열 덧셈 대상 문자열을 입력받아야 한다.
  • 입력을 받기 전에 덧셈할 문자열을 입력해 주세요.를 먼저 출력한 뒤, 개행하여 입력을 받아야 한다.
  • 사용자가 입력하는 값의 처리는 camp.nextstep.edu.missionutils.ConsolereadLine()을 활용한다.
  • 사용자가 프로그램에서 요구하는 사항이 아닌, 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

구분자 판정 기능

  • 기본 구분자(콤마, 세미콜론)외에 커스컴 구분자("//""\n" 사이에 위치하는 문자)의 사용 여부를 확인해야 한다.
  • 구분자 문자열을 return 한다.

문자열 분리 기능

  • 구분자를 이용하여 입력받은 문자열에서 숫자를 분리한다.
  • 정수 또는 실수를 요소로 가지는 List를 return한다.

자료형 판정 기능

  • 일관된 연산을 진행하기 위해 자료형을 판정한다.
  • 정수 또는 실수 여부를 판정하여 자료형에 맞는 요소를 제공한다.

덧셈 연산 기능

  • input은 정수 또는 실수를 요소로 가지는 List로 한정한다.
  • List의 요소를 모두 더한 값을 return 한다.

출력 기능

  • 덧셈 연산 기능에서 return한 값을 출력한다.
  • 출력 형태는 결과 : <덧셈 연산 기능 return 값>로 해야 한다.

종합 실행 기능

  • 위에서 구성한 기능들을 종합하여 실행한다.

제약 조건

  • 숫자의 범위는 java에서 처리할 수 있는 양수의 최대 범위로 설정한다.
    (숫자의 범위를 가장 넓게 지원하는 java의 자료형 또는 기본 라이브러리를 사용한다.)
  • "잘못된 값"은 아래의 형태 중 하나 이상 만족할 경우로 정의한다.
    • 판정된 구분자 또는 숫자가 아닌 다른 문자가 존재하는 경우 (ex: "//!\n1!2/3!4", "1;2;3;a")
    • 커스텀 구분자를 판정하는 문자의 형태가 잘못된 경우 (ex: "/?\b1?2?3?4")
    • 빈 문자열일 경우
  • 결과 출력에 성공하였을 때, 애플리케이션은 종료되도록 한다.

클래스 구조 설계

이번에 MVC 패턴을 적용해보는 것을 목표로 설정하였다. 지금까지 수행했던 과정은 패턴 상관 없이 기능 작동에만 집중해서 진행하는 것이었으나, 이번 기회를 통해 설계 작업을 연습해보자는 생각으로 진행하였다.

  • Service
    • 입력 기능(UserInput 클래스)
    • 자료형 판정 기능(NumTypeResolver 클래스)
    • 덧셈 기능(정수, 실수)
      • 숫자 변환 기능(NumConverter 인터페이스 - IntConverter, DecConverter 클래스)
      • 덧셈 연산 기능(NumAdder 인터페이스 - IntAdder, DecAdder 클래스)
    • 구분자 판정 기능(Splitter 클래스)
    • 문자열 분리 기능(Seperator 클래스)
    • 출력 기능(UserOutput 클래스)
  • model
    • 데이터 저장 클래스(Global)
  • controller
    • 계산기 controller 클래스(Calculator)

주로 고민한 사항

  1. 덧셈을 할 수 있는 숫자의 범위는 어떻게 할까?

과제에서는 정수 case 로만 구성되어있어서 정수로만 해도 되는지 생각이 들었다. 숫자는 정수뿐만이 아닌 실수로도 이루어져있을 때에도 처리할 수 있으면 좋을 것이라고 생각이 들었고 이를 효과적으로 반영하기 위한 방법을 고민하였다.

그리고 int나 long의 범위로 커버가 안될정도의 큰 수를 입력하는 경우도 고려를 하기 위해 Java에서 제공하는 BigInteger, BigDecimal API를 활용하여 구현하기로 하였다.

  1. 어플리케이션에서 사용하는 데이터들은 어떻게 관리해야 할까?

실제로 구현을 진행하면서 각 기능에서 사용해야 할 데이터가 중복이 되는 부분이 있는 것을 확인하였다. 해당 데이터들을 어떻게 관리하는 것이 좋을지 생각해보았고, 이에 대한 해결 방안으로 클래스를 생성하여 내부에서 저장 및 제공을 하도록 구성을 하였다.

  1. 여러 기능과 관련된 사항에 대한 Commit 단위는 어떻게 해야 할까?

이번 과제의 목표인 Git, GitHub, IDE 등 실제 개발을 위한 환경에 익숙해진다.와 관련된 사항이다. commit을 할 때, 여러 기능들이 복합적으로 연관되어있을 때에는 어떻게 처리해야 할 지에 대해서 고민을 하였다.

문제 해결 요소

구현하면서 발생한 문제와 해결 방안을 생각해 보았다.

  1. 덧셈 기능(정수, 실수)
    정수들을 더하는 문자열인지, 실수들을 더하는 문자열인지에 따라 사용하는 Class가 다르다는 문제점이 있었다.(정수: BigInteger, 실수: BigDecimal) 이를 해결하기 위해, NumConverter, NumAdder 인터페이스를 정의하여 필요한 메서드를 정의하였고, 각 자료형에 맞는 형태로 클래스를 구현하였다. 마지막으로 NumTypeResolver에서 문자열의 요소를 확인하여 이에 맞는 Converter, Adder를 지정하도록 하였다. 이를 통해 다른 자료형 따른 연산 차이 문제를 해결하였다.
  2. 구분자 판정 기능
    구분자를 판정하는 로직에서, String의 split() 메서드의 특성에 주의를 해야했다. split에 제공할 수 있는 String 문자열로는 정규식 형태의 문자열을 제공해야 한다는 점이였다. 여기서 정규식에서 사용하는 메타 문자들에 대한 처리 방법을 생각해야 했고, 메타 문자들도 구분자로 사용 가능하게 하기로 결정하였다. 이를 처리하기 위해, 메타 문자 리스트를 만들어 해당 리스트에 존재하는 문자일 경우, \를 문자 앞에 추가하여 커스텀 구분자로 추가하도록 하는 로직을 구성하였다.

아쉬웠던 사항

  1. 작명 규칙
    이번 코드리뷰를 진행하면서 받은 피드백 중, 클래스 작명에 대한 피드백이 많았다.
    코드 리뷰를 진행하면서 받은 피드백 중 하나이다. 효과적인 작명 방법을 찾아봐야겠다는 계기가 되었다.

    풀 네임을 다 작성하면 너무 길어질 것 같다는 생각으로 어느정도 축약을 하는 식으로 작명을 해야겠다는 생각을 했었는데, 오히려 다른 사람이 보고 이해하는 데에는 풀 네임으로 작성하여 이해도를 높이는 방향이 있을 수 있겠다는 생각이 들었다.

이번에 구현한 클래스를 예시로, NumConverter는 NumberConverter와 같이 풀네임을 이용한 직관적인 이름으로 짓는 것과 Global은 DataManager와 같은 데이터를 처리한다는 역할을 충실히 표현할 수 있는 이름으로 짓는 것이 좋다는 점을 배울 수 있었다.

  1. 불완전한 MVC 패턴 이해 및 적용
    MVC 패턴이 무엇인지는 알고는 있었고, 이전에 Spring 프로젝트를 진행할 때에는 어느정도 적용 방법을 체득했다고 생각을 했었다. 하지만 순수 JAVA를 이용하여 MVC 패턴을 적용하려 하니 각 요소가 해당 위치에 있는 것이 맞는지 혼동이 많이 있었다. 이번 주차에는 어떻게 구현은 완료했지만 개인적으로는 아쉬웠던 점으로 남았다.

개선하기 위해 할 수 있는 것은?

  1. MVC 패턴의 정의 및 적용 사례 더 찾아보기
    spring을 공부하면서 가장 익숙한 패턴이라고 생각했지만 아직 체득하지는 못했다고 느끼게 해준 과제였다. 이를 해결하기 위해 다른 사람들은 어떻게 MVC 패턴을 적용하였는지 찾아보면서 각 요소의 역할을 명확하게 이해할 필요성을 느꼈다.
  2. 효과적인 변수명 작명 규칙 고안해보기
    이번에 코드리뷰를 진행해보면서 변수명이나 클래스명을 효과적으로 작성하는 방법을 찾을 필요성을 느꼈다. 이번에 커뮤니티에서 올라온 JAVA 변수 네이밍 방법에 대한 좋은 글(JAVA 변수 네이밍)을 찾을 수 있었고 추가적으로 탐색을 진행해볼 예정이다.

마무리하며...

아직 프로그래밍에 대한 길은 멀다는 것을 느낀 과제였다. 앞으로 부족한 점을 찾아가면서 보완해가는 개발자가 될 수 있는 초석이 될 수 있으면 좋겠다.

728x90