0. 다시 한 번 스스로에게 채찍질하기

2022년 11월 2일 15시. 14시에 있던 코수타의 종료와 함께 2주차 미션이 시작됐다. 미션이 시작되면서 프리코스를 밟는 동기들끼리 서로 피어리뷰나 토론 등을 할 수 있는 프리코스 커뮤니티도 활성화됐고, 공통 피드백들이 주어졌다. 

 

원래는 바로 2주차 미션을 수행하려 했으나, 14시에 들었던 코수타와 이후 다른 사람들과 진행한 상호 코드 리뷰(피어 리뷰)에서 얻은 게 많았다.

 

일단 제일 인상 깊었던 것은, 포비님이 했던 말이다. 기능 목록을 정의하는 것이나 메서드 분리 등은 정해진 답이 없기 때문에, 어떻게 해야 할까요? 라기 보다는 스스로 고민해서 자신의 기준을 만들어가야 한다는 것. 사실 나도 돌이켜보면 1주차 미션을 진행하는 중에 이게 좋을까 저게 좋을까를 많이 고민하는 과정에서 "보편적으로 답이 될 수 있는 무언가가 있다!"라는 걸 무의식적으로 가정하고 있던 것 같다. 그 과정에서 다른 사람들에게 물어가면서 어떻게 하는게 정답에 가까운지를 알아내야 한다고 생각했었다. 정해진 답을 찾아내야 하는 학생의 함정에 빠져 이건 답이 없는 현실의 문제임을 망각했던 거다..앞으로 개발자의 삶을 살아가는데 있어서 답이 없는 문제들을 많이 마주칠 것이다. 그리고 내가 프로그래머가 되고 싶은 이유는 내가 그렇게 마주치는 문제들, 즉 정해진 답이 없는 현실의 문제들을 코딩이란 도구를 통해 해결하는 사람이 되고 싶어서이다. 그러나 부끄럽게도 무의식적으로 정답을 찾으려고 했다니..일종의 고정관념이 머릿속에 있던 것 같아 망치로 탕 맞은 느낌이었다.

 

그리고 프론트를 공부하던 시절 강의에서 잠깐 봤던 임동준 코치님(준 님이라고 부르는 듯 하다)이 나와 피드백을 주는데, 요구사항을 의도적으로 명확하게 주지 않았음을 강조해주셨다. 이 이유 역시 포비님이 했던 말과 마찬가지로, 현실에서 우리가 개발자로써 풀어가야 할 문제들은 정답이 없을 뿐더러 명확한 요구사항이 주어지는 문제들이 아니기 때문! 즉 스스로 생각하고 스스로 고민하고 스스로 판단해서 기능 목록, 요구사항 목록들을 정의해가야 한다고 해주셨다. 이런 과정을 통해 학교 과제에서나 요구하는 정답 코드가 아닌, 현실 문제를 풀 수 있는 코드를 짤 수 있게 될 거라고 말씀해주셨다. 역시나 감명을 크게 느꼈다..

 

그리고 저녁에는, 부족한 실력임을 알고 있지만 용기를 내어 프리코스 커뮤니티를 통해 다른 사람들과 1주차 미션에 대한 피어리뷰를 진행했다. 다른 사람들이 짠 코드를 보면서 "이렇게 하면 확실히 다른 사람이 봤을 때 이 사람이 뭘 하고자 하는지 잘 알 수 있겠구나", "와 이걸 이렇게도 할 수 있구나", "이 부분은 이렇게 하면 좀 더 깔끔할 것 같다"  등등을 느끼면서 많은 배움을 얻을 수 있었다. 동시에 내 코드를 다른 사람이 리뷰해주는 과정을 통해 내가 짠 코드가 어떻게 읽히는지, 어떤 문제가 있는지, 어떤 부분을 개선해야 하는지도 여실히 느낄 수 있었다. 남이 나에게 해주는 코드리뷰와 내가 남에게 해주는 코드리뷰는 처음인데 이거 정말 맛있다..그리고 우테코는 사실상 읽기 좋은 코드를 쓰고 싶은, 어떻게 보면 나랑 같은 목표를 가진 사람들끼리 서로 모여서 피어리뷰를 해주는 거다보니까 신나기도 했다. 열정있는 사람들과 함께이니 더 끓어오르는 느낌. 

 

코수타와 피어리뷰를 통해, 정말 느끼고 얻은 게 많다. 정리하면 다음과 같다.

 

  1. 기능목록, 메서드 분리? 스스로 고민하고 스스로 쥐어짜서 해라. 정답 없다. 나만의 기준을 세워가면서 해라.
  2. 리터럴 값 (1, -1같은 거) 그대로 쓰지 말고 변수에 담아서 해보자. 그게 다른 사람 입장에서 이 수가 뭐하는 용도인지 잘 드러난다.
  3. 메서드 선언 순서도 아무 생각 없이 막 하지 마라. 코드의 흐름과 메서드 선언을 하는 순서를 맞춰두면 다른 사람 입장에서 그 메서드가 뭘 하는지 찾아가는 길이 편하다
  4. 한 메서드가 하나의 기능을 하게 해라. 한 메서드가 너무 많은 책임을 가지면 안 된다

 

그럼 내가 생각하는 가장 좋은 기능목록이란 뭘까. 1주차에서 느꼈던 것은, "의미있는 기능 단위로 작성된 목록"이 가장 좋은 기능목록이라는 것이고 내가 생각하는 의미있는 기능 단위란 각 기능들이 메서드 하나 또는 특정 코드에 대응하는 구조를 말한다. 물론 이건 저번 1주차 미션에서 "아 좀 깔끔하게 떨어지지 않는 구조로 세밀하게 기능목록 만들고 그거에 맞춰서 구현했더니 리팩토링할 때 메소드 단위로 뽑아내기 힘들더라.." 라는 걸 느꼈기 때문에, 내가 현재로써 생각하는 가장 좋은 기능목록에 불과할 수도 있다. 그러나 어떠랴. 이렇게 생각해보고 시도해보고, 그 다음엔 저렇게 해보고 시도해보는 과정에서 나만의 기준이 생길 것이고 이게 내 개발자 인생에 큰 도움이 될 거다. 계속해서 고민해보고 생각해봐야 할 사항일 것이다.

 

이번 2주차 미션에서는, 함수/메서드들을 역할에 따라 분리하는 것과 테스트 도구에 익숙해지는 것을 목표로 한다고 메일로 말씀해주셨다. 테스트 코드..사실 1주차 미션에서 휙하고 처음 마주쳤지만, 이 녀석과도 이제 안면을 트고 인사할 때가 된 거다. 계속해서 성장하고, 앞으로 나아가자. 바쁜 하루들이 계속되지만, 이 길이 내리막길이 아닌 오르막길임을 알고 있다. 


1. 구현 전 준비운동

우선 기능 목록을 정의하는 것부터 시작했다. 코치님들이 일부러 요구사항을 명확히 주지 않는다고 말해주신 만큼, 주어진 룰을 바탕으로 내가 어떤 제한과 기능을 추가해야 할 지 생각했다. 주로 제한사항들에 대한 것들을 생각해야 했는데, 내가 생각한 제한사항들은 다음과 같았다.

 

  1. 사용자 입력이 3글자면 안 된다
  2. 사용자 입력이 숫자가 아니면 안 된다
  3. 사용자 입력에 0이 있으면 안 된다(맞춰야 하는 3개의 수는 1 ~ 9 사이임)
  4. 사용자 입력에 중복된 수가 있으면 안 된다(사실상 반칙임)

 

이를 토대로 최대한 의미있는 기능목록(각 기능들이 하나의 메서드 혹은 코드에 대응하는)을 다음과 같이 만들었다.

처음부터 이 모습은 아니었고, 중간중간 수정을 거쳐 만들어진 최종 기능 목록이다

 

구현에 앞서 조금 생각을 했던 것은, 클래스를 분리해서 만들어보자는 것이었다. 이번 2주차 미션의 목표가 함수/메서드들을 역할에 따라 분리하는 걸 연습하는 것이기도 했고, 근본적으로 한 클래스가 하나의 책임만 갖게 하고 싶었다. 물론 기본적으로 실행되는 Application.java에 모든 코드를 작성해서 만들 수도 있다. 그러나 내 목표는 "읽기 좋고 재사용성이 좋은 코드를 짜는 개발자가 되는 것"이고 이를 위해선 객체지향적인 프로그래밍을 할 줄 알아야 하기 때문에, 최대한 클래스를 분리해서 각각의 코드를 짜는 걸 추가적으로 연습해보고 싶었다. 숫자야구게임기가 있다고 하면 

 

  1. 각종 메시지들이 출력되는 디스플레이장치
  2. 키보드처럼 입력을 받는 장치
  3. 게임 로직

 

이렇게 3개의 요소가 필요하다고 생각했다. 각각에 대응하는 GameMessageDisplay, Inputter, BaseBallGame이란 클래스를 만들고 Application에서 BaseBallGame객체를 만든 다음 runGame메서드를 통해 게임을 실행하는 방식으로 코드를 짜면 깔끔할 것 같다는 생각이 들었고, 그렇게 만들기로 했다.

 

그러나..

 

얼마되지 않아 사실상 입력장치의 필요성에 대한 의문이 들었다. 사실 입력받는 동작 자체는 우테코에서 제공하는 api를 사용하면 끝나는 부분이었고, 입력장치보다는 입력된 내용에 대한 검증(validate)를 필요하는 객체의 필요성이 더 높다고 느껴졌기 때문이다. 입력장치 객체 안에 검증메서드들을 넣는 식으로 만들까 했지만, 차라리 검증기 객체(Validator)를 따로 만드는 게 내가 처음에 원했던 "한 클래스가 하나의 책임만 갖게 하기"에 더 부합하다는 생각이 들었다. 그래서 입력을 받는 동작을 BaseBallGame으로 옮기기로 하고, Validator를 만들어 이 객체가 검증기능을 담당하도록 생각을 끝난 다음 구현에 들어갔다.


2. 학습 과정 -  한 메서드가 하나의 기능만 가지게 한다..그럼 그 기능의 범위는?

본격적인 구현에 들어가면서는 한 함수가 하나의 기능만 하도록 함수를 만드는 점에서 많은 고민을 하게 됐다. 함수 이름을 어떻게 지을 것인가! 부터 시작했는데, 이를 위해 메소드 이름 짓는 팁 등을 알아보다가 "동사로 시작하도록 이름 짓기"를 알게 돼서 일단 모두 동사로 시작하게끔 지어줬다. 원래는 gamePrepare라는 식으로 짓던 것도 prepareGame으로 다 바꿔줬는데, 확실히 동사로 시작하도록 통일하고 나니 이 메서드가 어떤 걸 하는지 그 의도가 조금은 더 잘 보이는 느낌이었다. 또한 검증메서드(isNumeric)등을 모두 긍정문으로 통일시켜줬는데, 이것 역시 그 의도가 좀 더 잘 보이는 것 같은 느낌이 들었다.

 

가장 많은 고민을 했던 건, "한 기능의 범위"를 어디까지로 봐야 하는가? 였다. 예를 들어서 내가 만들었던 getGameResult는 사용자가 입력한 수를 토대로 ball의 개수와 strike의 개수를 얻는 메서드였는데, 내부적으론 ball과 strike의 개수를 센 다음 그 개수들을 map에 저장하여 리턴하는 구조였다. 큰 틀에서 본다면 getGameResult는 "게임결과를 얻는다"라는 하나의 기능을 수행한다고 볼 수 있지만, 좀 더 파고들어 본다면 getGameResult는 "ball과 strke의 개수를 센다"와 "센 개수를 map에 저장한다"라는 두 기능을 수행한다고 볼 수 있다. 

바로 이게 고민이었던 거다. 사실 1주차 온보딩 미션에서도 이 부분을 많이 고민했었다. 도대체 어떤 관점에서 기능의 범위를 바라봐야 할까.. 목표 자체를 다시 상기해보면, "하나의 함수가 하나의 기능만 하게 한다"이다. 만약 세부적인 관점에서 본다면 getGameResult는 두 개의 기능을 하므로 잘못된 함수가 아닐까라는 생각이 들어서 많이 헷갈렸다.

결국은 큰 관점에서 "게임결과를 얻는다"라는 하나의 기능을 한다고 보고 일단 구현을 해나갔다.

 

그러나..

 

나중에 리팩터링을 하게 되면서 내 생각이 잘못됐음을 느낄 수 있었다.

우선, 돌이켜보니 함수의 덩치가 너무 크다. "결국은 큰 틀에선 ~~라는 기능을 하는 함수니까!"라고 생각하고 만들어서 그런지 내부적으론 여러 기능을 하는 구조였고, 결과적으로 함수 하나하나가 많이 뚱뚱했다.

또한, 함수 내에서 일어나는 세부적인 기능들이 어떤 걸 하는건지 눈에 쉽게 들어오지 않는다! 이게 가장 큰 문제였다.

 

 

이게 바로 당시의 getGameResult다. 큰 틀에선 "게임결과를 얻는다"라는 한 가지 기능을 하지만, 내부 코드들은 ball과 strike의 개수를 세는 기능과 센 개수를 map에 저장하는 기능을 한다. 그러나, 코드만 보면 뭘 하는 건지 한 눈에 파악하기 쉽지 않다.

 

따라서 읽기 좋은 코드를 만들기 위해, 이 부분들도 메소드로 추출하여 만들어야 할 필요성을 느꼈다. 그러면 다음과 같이 만들어질 수 있다.

 

 

getGameResult안의 코드들이 어떤 걸 하는지 한결 알아보기 편해졌다. 지금 글을 쓰며 다시 생각해보니 성공여부를 true로 바꿔주는 부분도 메서드화하고 이를 countBallAndStrike로 옮겼다면(예를 들면 judgeSuccess란 이름으로..) 더 좋았을 거라는 생각이 든다. 

 

회고를 쓰며 돌이켜보니, 역시나 아직도 부족한 면이 많다. 그러나 기능의 범위를 어디까지 해야 하는지에 대해 좀 더 감을 잡게 된 것 같다. "하나의 함수가 한 기능만 하게 한다"라는 것은, 기능별로 테스트를 할 때 그 기능에 맞는 함수를 사용할 수 있게 한다는 편리함을 위해서이기도 하고 다른 이유들도 있겠지만, 읽기 좋은 코드를 지향하기 위해서인 것 같다. 내가 헷갈렸던 것은 "내부적으로 파고들면 여러 기능이지만 큰 틀에선 하나의 기능으로 볼 수 있으니 더 이상 쪼갤 필요가 없지 않을까? "였다. 그러나 이번 과제를 통해 이에 대한 스스로의 답을 찾을 수 있었다. 그건 바로 "큰 틀에선 하나의 기능으로 볼 수 있지만, 읽기 좋은 코드를 위해 메서드 내부의 세부적인 각 기능들을 메서드화해야 한다!"이다. getGameResult의 예로 가보자. 물론 "게임결과를 얻는다"라는 궁극적인 기능을 하는 거지만  세부적으론 "ball & strike의 개수를 센다"와 "센 갯수를 저장한다"라는 2개의 기능을 통해 "게임결과를 얻는다"라는 기능을 하는 것이므로, 내부 기능들도 함수로 만들 필요가 있는 것이다! 하나의 기능(게임 결과를 얻는다)이 다른 기능들(개수를 센다, 센 갯수를 저장한다)을 통해 수행된다면, 그 다른 기능들에 해당하는 애들도 함수로 만들어줘야 한다는 것. (물론 필수는 아니겠지만 이렇게 하는게 읽기 좋은 코드가 된다) 이번 2주차 함수 분리하기 연습을 통해 얻은 나만의 작은 깨달음인 것 같다. 다만, 이 때 과하게 기능이 세분화되지 않도록 중간에 적절히 cut하는 것도 내 몫인 것 같다.


3. 학습 과정 - 테스트 코드 먹어본 후기

이번 2주차 미션의 또 다른 목표는 "테스트 도구에 익숙해지는 것!". 테스트 코드라는 걸 말로만 들었지 실제로 접한 건 사실 저번 1주차 미션이 처음이었다. 당시엔 "아니 뭐야 자바는 main이 있어야 실행할 수 있다는데 main이 없어도 된다고?"라는 것에 조금의 충격을 받았었는데, 이번 기회에 테스트 코드를 제대로 찍먹해보자는 생각이 들었다. 우선 구글링을 통해 테스트 코드가 어떤 걸 말하는 거고 왜 쓰는 건지, 내가 기존에 쓰던 나만의 테스트 방법인 "직접 프로그램을 수행하며 중간중간 print(js면 console.log)로 찍어보면서 확인하기"와 어떤 차별점이 있는지를 먼저 공부했다. 그러고나선 실제로 gradle로 자바 프로젝트를 만들어 assertj를 설치한 다음, 2가 1 + 1과 같은지 등을 확인하는 간단한 테스트 코드를 만들어가며 공부했다.

 

https://jofestudio.tistory.com/70

 

테스트 코드 찍먹해보기(feat. Junit, Assertj)

테스트 코드? : 내가 작성한 메서드가 실제로 잘 동작하는지 확인하는 용도로 작성하는 코드를 일컫는다. 이걸 왜 쓰는가? : 궁극적으론 기능이 정상적으로 동작하는지 확인하기 위함. 기존에 내

jofestudio.tistory.com

프론트에서 공부하다 백엔드로 전향해서 자바가 처음과 마찬가지였던 내 입장에선, 이 공부과정에서 gradle이 뭔지, 외부 라이브러리는 어떻게 설치하는지, annotation이 뭘 말하는 건지 하나도 몰랐다. 그래서 하나하나 구글링해보면서 gradle이 이런 거군..외부 라이브러리는 이렇게 설치하는군..등등을 공부했는데, 시간은 오래 걸렸지만 덕분에 자바를 조금이라도 더 알게 돼서 좋았다.

 

테스트 코드에 대해 공부를 하던 중 TDD라는 걸 알게 됐다. 테스트 코드를 먼저 짜고 그 테스트가 통과할 수 있는 프로덕션 코드를 짜는 방식이었는데, 이왕 테스트코드 찍먹할 거 TDD방식을 조금 적용해보면 어떨까란 생각이 들었다. 테스트를 먼저 짜면서 "어떻게 해아 프로덕션 코드를 테스트하기 쉽게 짜지?"를 고민하는 과정에서 "음 이런 기능을 하는 ~~라는 메소드를 만드는데, 리턴값을 어떤 걸 주게 하면 되겠다!"등을 생각할 수 있었고, 덕분에 하나의 함수가 한 기능만 하도록 하는 것에 나름대로의 도움을 얻을 수 있었다. 물론 처음이라 그런지 TDD방식 자체는 익숙하지 않고 상당히 불편하다는 느낌이다...

 

컴퓨터 숫자들을 세팅하고 그 숫자들이 서로 다른 수들이 세팅되는지, 3개가 세팅되는지 테스트하는 과정에서는 "이 테스트들은 컴퓨터 숫자들을 미리 세팅하고 테스트해야 하는데, 컴퓨터 숫자들을 세팅하는 걸 따로 뺄 순 없을까?"를 고민하다가 BeforeEach라는 어노테이션으로 각 테스트들의 수행 전에 실행될 함수들을 지정할 수 있는 걸 알게 됐다. 내 생각 이상으로 테스트 툴들은 여러 가지 기능을 제공해주던 거였다..또한 단순히 isEqualTo만 쓸 수 있는게 아니라 isFalse같은 여러 가지 메서드(assertion이라 부르는 듯하다)들이 있었고, 이것들을 체이닝 형식으로 이어서 여러 가지 조건을 만족하는지에 대한 테스트도 할 수 있는 걸 알게 되면서 엄청난 편리함을 느낄 수 있었다.

 

가장 놀랐던 건 따로 있다. 사실 야구 게임 프로그램 자체는 사용자 입력을 기반으로 하기 때문에, 사용자가 터미널에 입력하는 걸 받아서 테스트하는 방식은 힘들다고 생각했다. 실제 사용자 입력을 테스트하려면 프로그램 자체를 수행해야 한다고만 생각했었다. 따라서, 입력값에 대한 예외처리는 내가 직접 변수를 만들어 잘못된 입력을 할당한 다음, 다음과 같이 validate메서드 자체를 호출해서 잘못된 입력에 대한 처리를 테스트해야 한다고 생각했다.

 

 

근데 이건 내 착각이었다! ApplicationTest파일에 기본적으로 작성된 두 개의 test가 있었는데, 각각을 ctrl + b를 누르며 코드를 따라가며 분석하는 과정에서 프로그램을 실행시킨 다음 내가 직접 입력할 필요 없이 임의의 입력을 넣으며 테스트할 수 있는 걸 알게 됐기 때문이다!!

 

 

이게 우테코에서 기본적으로 ApplicationTest파일에 넣어줬던 테스트인데, 야구게임 프로그램을 실행하고 원래는 사용자가 터미널 창에 입력해야 하는 값을 "1234"라는 값으로 자기들이 대신 넣어줘서 테스트를 돌리는 코드다! 

 

 

이것 역시 우테코에서 기본적으러 넣어줬던 테스트로, 역시나 프로그램을 실행시킨 다음 사용자가 직접 입력할 필요 없이 "246", "135"등의 입력값을 자기들이 대신 넣어주는 테스트이다. 

이걸 알게 되고는 "와 그럼 내가 테스트할 수 있는 영역들이 그럼 엄청 넓어지는데? 사용자가 온갖 수들을 입력하는 과정 자체를 하나의 테스트로 만들 수도 있겠는데? ” 라는 생각이 들었고 테스트 코드의 미칠 듯한 강력함을 피부로 느낄 수 있었다. 기존에 내가 테스트했던 방식으로 한다면 게임 코드를 수정한 뒤 직접 야구 게임을 실행한 다음 컴퓨터를 숫자를 내가 하나하나 맞춰야 하는 번거로운 작업이 진행됐을 텐데, 수들을 입력하는 과정 자체를 하나의 테스트로 만들게 된다면 코드를 수정한 뒤엔 테스트 실행 버튼만 딸깍하고 누르면 된다. 테스트에 걸리는 시간 자체가 대폭 감소하게 되는 것..이게 사실 2주차 미션에서 얻은 가장 큰 수확이 아닌가 싶다. 테스트 코드라는 걸 찍어먹어보고 싶었던 건데, 잠깐 찍먹한 것으로도 그 풍미를 온몸으로 느낄 수 있었다. 정말 강력한 도구라는 생각이 들고, 앞으로 내가 어떤 개발로 가든 테스트는 꼭 데리고 가야겠다.

 

테스트의 장점을 느낀 건 이뿐만이 아니다. 코드 수정 후 테스트를 하는 것을 통해 문제가 나는 부분을 파악할 수 있었다. 그 상황은 다음과 같았다.

 

 

어느 테스트가 실패했는지, 어느 부분에 문제가 생겼었는지를 파악하기 쉬웠다. 즉 코드를 수정한 후 테스트를 돌려봄으로써 어떤 부분이 잘못 돌아가는지를 쉽게 파악할 수 있었다! 코드를 수정하는 과정에서 기존 기능들이 잘 동작하는지 파악하게 하는 데에도 테스트가 큰 도움을 주는 것을 느낄 수 있었다. 


4. 그 외의 고민 - 어떤 흐름으로 짜야 다른 사람이 읽기 편할까

학습 목표 이외에 2주차 미션을 수행하며 고민했던 것 중 하나만 꼽자면, "어떤 흐름으로 짜야 다른 사람이 읽기 편할까?"가 아니었나 싶다. 동일한 동작을 하게 된다고 해도, 그 흐름을 짜는 방식은 천차만별이다. 예를 들면 예외처리가 그런 종류일 것이다. 사용자 입력을 검증하면서 문제가 있으면 에러를 일으키는데, 어디서 일으킬지는 내가 정해야 한다! 처음엔 다음과 같이 validate메서드 자체에서 문제가 있으면 에러를 일으키도록 코드를 짰었다.

 

 

그러나 이 경우, 다음과 같은 문제가 있었다. 다음 코드에서 isValidInput은 내부적으로 위에  있는 validateInput메서드를 호출한다.

 

 

즉 이 코드는 사용자에게 입력을 받고, 유효성 검사를 통과해야 게임결과를 출력하는 코드다. 나야 이 게임을 만들었고, 다른 우테코 참가자들이야 사용자 입력이 유효하지 않다면 에러가 난다는 것은 암묵적으로 알고 있을 것이다. 그러나 아예 다른 사람이 보기엔 어떤가. "음 사용자한테 입력받네. 그 입력이 유효할 때만 게임결과 출력하고, 입력이 유효하지 않으면 아무 일도 없네"라고 오해할 수 있는 코드라고 생각됐다. 왜냐하면 그 사람들은 입력이 유효하지 않으면 에러를 내야 한다는 걸 모르니까. 즉 메서드 이름을 나름 잘 지었다고 생각했지만, 다른 사람이 보기에 맥락상 오해할 여지가 있는 코드인 것이다!

따라서 validate메서드를 유효하지 않으면 오류가 나는 코드에서 유효하지 않으면 VALIDATE_FAIL(=false)를 리턴하도록 바꿔주고, 다음과 같이 코드를 수정했다.

 

 

유효성 검사가 실패한 경우, raiseError 메서드를 통해 에러를 일으키는 것을 파악할 수 있게끔 바꿨다. 이제 다른 사람이 봤을 때도 "음 유효성 검사를 실패하면 오류가 나고, 성공했을 때만 게임결과를 출력하는군!"이란 생각을 할 수 있을 거라고 생각했다. 이를 통해 코드의 흐름을 어떻게 짜야 할지, 같은 동작이라도 어느 메서드에서 하게 할지에 따라 읽기 좋은 코드가 될 수도 있고 안 될 수도 있다는 걸 느꼈다.


5. 2주차가 끝나고..

저번 1주차가 끝나고 2주차로 접어들며 세웠던 목표였던 "의미있는 기능 목록 세우기"를 돌아봤다. 과연 목록의 각 기능이 하나의 메서드에 대응되도록 기능 목록을 만들었는가!

결과는 다음과 같다.

 

게임 종료와 재시작의 경우, while문의 로직으로 대체되어 별도로 메서드화하진 않았다. 나름 기능 목록을 의미있게, 즉 각 기능들이  더 이상 세분화하지 않아도 되면서 하나의 메서드에 대응하게끔 잘 만든 것 같아 뿌듯하다.

 

전반적으로 이번 2주차 미션을 통해서 내가 궁극적으로 지향하는 목표인 “읽기 좋고 재사용성이 좋은 코드를 짜는 개발자 되기”의 방법 중 하나가 “함수를 최대한으로 분리하기”임을 느낄 수 있었고 덕분에 이전보다 스스로가 조금은 성장한 것 같아 기분이 좋다. 또한 테스트 코드라는 신문물을 알게 됐고, 앞으로 개발 속도 자체를 대폭 줄이면서 유지보수에 좋은 코드를 짜는 것에도 도움이 될 수 있을 것 같아 더욱 더 좋다. 테스트 코드라는 정신건강에도 좋고 맛도 좋은 S급 별미를 왜 이제야 맛을 보게 됐는지 억울하기도 하다... 우테코를 통해 조금씩 성장하고 있는 내 모습을 조금씩 보게 되는 것 같아 너무나도 감사하다. 앞으로도 우테코를 통해 더욱 더 성장하고 싶다.

 

+ Recent posts