과제 진행 소감에는 미션을 진행하면서 느끼고 배운 점, 많은 시간을 투자한 부분 등도 포함하면 더 좋을 것 같습니다. 🙂
그리고 과제를 제출할 때 'git’과 '과정별 언어’를 학습하면서 느낀 점을 소감문으로 작성해 주세요. 이때 학습한 '과정’을 잘 드러내 주세요.
이번 우아한 테크 코스 5기는 이전 기수들과 달리 1차 코딩 테스트가 없어지고, 기존의 프리코스 3주 차에서 4주 차로 바뀌면서 1주 차에 온보딩 주차가 추가되었다.
온보딩에 대한 자세한 내용은 해당 우테코 깃허브를 통해 공개해놓고 있기 때문에 들어가서 확인하면 된다.
우테코 깃허브:
내 깃허브:
온보딩 과제는 미션 제목처럼 온보딩이여서 그런지 엄청 어려운 요구사항은 없었다. 그냥 기존의 코딩 테스트를 보는 대신 코딩 테스트 문제들을 온보딩 주차에 미션으로 추가한 것 같다.
나는 프로그래밍을 독학하면서 NextStep의 JavaPlayground를 통해서 우테코 프리코스와 비슷한 과정을 의식적인 연습을 통해 학습한 경험이 있다. JavaPlayground도 우테코 캡틴인 박재성님이 하는 교육이기에 과정이 비슷하다. 물론 JavaPlayground를 진행했다고 해서 프리코스에서 얻는 게 없고, 배움이 없는 건 아니다. 그 당시의 나와 지금의 나는 다르기 때문이다.
프리코스를 하면서 github pull request 하는 것도 처음이었고, Java언어와 Git에 대해서 배우고 얻는 것도 많았지만, 이번 프리코스 4주차를 통해 새로운 인사이트를 얻고 싶었다. 바로 TDD(Test Driven Development)이다.
테스트 코드를 공부하다가 TDD에 대해서 알게 되었고, 테스트 코드의 중요성을 느꼈기에 관심이 생겨서 '테스트 주도 개발'이라는 책을 사서 읽었다. 앞의 화폐 예제는 볼만해서 보고, 뒤로 갈수록 내용이 추상적이라 보는 것을 멈췄지만, TDD를 이해하기에는 충분했다.(TDD에 대해선 설명하지 않는다.)
책을 보고 다음과 같은 생각이 들었다.
이후 나는 Spring 프로젝트에서 TDD를 시도해보았지만, 당연히 포기했다. TDD가 연습되어 있지 않을뿐더러, 많은 프레임워크와 라이브러리가 의존되어 있을수록, 해당 문법에 익숙지 않을수록, 테스트 코드를 먼저 작성하는 일은 쉽지 않았다. 이후 TDD의 장단점에 대해서 구글링을 해보았지만, 다양한 상황에서 장단점이 있었고, 사람들마다 의견이 다양했다.
JavaPlayground 피드백 강의에서 박재성님이 하신 말이 떠올랐다. "TDD 한번 해보고 좋은 거 같으면 계속하고, 아니면 하지 마세요." 맞다. 나는 제대로 해보지도 않고 TDD의 장단점이 뭔지에 대해서만 꽂혀있었다. 프로그래밍은 잘못된 것은 있지만, 정답은 없다고 생각한다. 나에게 맞을 수도 안 맞을 수도 있다.
따라서 이번 프리코스를 통해 TDD에 대한 인사이트를 얻고자, 모든 미션부터 최종 코딩 테스트 까지(1차가 붙는다면ㅠ) TDD로 개발하기로 도전했다. 프리코스 과정이 우테코 합격에 영향을 미치기에 쉽지 않은 결정이었지만, 그만큼 많은 성장이 있을 것으로 기대하고 있다.
내가 지금까지 개발을 진행해왔던 방법이다.
하지만 TDD로 도전하면서 다음과 같은 싸이클로 개발을 진행했다.
첫 번째로 메소드의 접근제어자 의문이 들었다. 기존에 개발 방식은 주요 기능에 대한 메소드를 public으로 열어주고 해당 메소드에서 파생되는 메소드는 private으로 클래스 내에서만 접근 가능하게끔 했다. 테스트 코드를 짤 때에도 public 메소드만 테스트하여 private 메소드는 public 메소드를 통한 간접 테스트를 진행했다. 물론 private 메소드들도 테스트를 위해 public으로 열어줘도 된다고 생각하지만(테스트는 그만큼 중요하다.), 나는 private 메소드가 엄청 복잡한 로직이여서 내가 불안한 경우를 제외하고는 굳이 테스트 하지 않는다. 왜냐하면 서비스 규모가 커지면 커질수록 해당 클래스 내에서만 사용하는 메소드들은 private으로 두어서 주는 이점이 더 많다고 생각하기 때문이다.
즉 (현재 상황이 메소드가 하나의 기능을 담당한다고 가정했을 때) 정리해보자면, 하나의 기능을 구현하기 위해 methodA를 public으로 열어두고 구현하였고, 그 과정에서 methodB, methodC가 파생되었으며 methodA만 테스트 코드를 작성했다.
public methodA(...){
methodB(...);
methodC(...);
...
}
private methodB(...){};
private methodC(...){};
이 생각은 변함이 없고, 이 생각으로 TDD를 진행하는데 어려움이 있었다. TDD는 더 작은 기능 단위로 접근을 하게 되었고, 위의 예에서 methodB, methodC를 먼저 TDD로 개발하다 보니 테스트 코드 작성을 위해 public으로 열어둬야 했다. 따라서 결국 public으로 열어두지 않아도 될 메소드들이 테스트를 위해 public인 상태로 개발을 진행하게 되었다.
이에 대한 나의 생각은 다음과 같다. methodB, methodC를 위한 테스트 코드를 작성하기 위해 public으로 열어두지만, 진행을 하다 보면 결국 methodB, methodC가 methodA 내부에서만 쓰이기 때문에 이 점을 인지했을 때, private으로 수정하고 기존의 methodB, methodC의 테스트 코드를 삭제하면 TDD개발의 장점을 가져가면서 public을 남발하지 않을 수 있다고 생각한다. 결과만 놓고 보자면 의미 있는 기능의 methodA의 단위 테스트만 존재하는 것이다.
하지만 작성한 테스트 코드 삭제에 대해서 의문이 들었고, 이에 대한 생각을 정리하고, 다른 사람들의 생각이 궁금하여 구글링과 책을 통해서 찾아봤다.
다양한 사람들의 의견이 존재했다.
다양한 사람들의 의견에 대한 내 생각은 이렇다,
다양한 상황에서 다양한 의견들이 존재하고, 정답은 없다고 생각한다. 같이 개발하는 팀원들과 토론을 통해 규칙을 정하는 게 맞다고 생각한다.
하지만 private 메소드의 유닛 테스트 여부에 대한 답변은 많은데, 나의 궁금증인 TDD로 개발하면서 이전의 public 메소드가 어느 한 메소드에서만 포함되고 해당 클래스 내에서만 쓰일 때, private으로 바꾸고 해당 테스트 코드를 삭제해도 되는지에 대한 의견은 찾을 수 없었다. 따라서 '테스트 주도 개발' 책에서 테스트 삭제 관련 내용을 찾아보았다.
책에는 다음과 같은 질문과 답이 있었다.
테스트를 지워야 할 때는 언제인가?
테스트 코드를 지워야 할 때의 조언을 찾을 수 있었다. 온보딩을 진행할 때는 public으로 열어두지 않아도 될 메소드들을 열어두 었지만, 앞으로는 이럴 경우 테스트 코드를 지우고 해당 메소드를 private으로 리팩토링하는식으로 진행하고, private 메소드 테스트는 해당 메소드를 호출하는 public 메소드를 통한 간접 테스트만을 진행하려고 한다.
결과적으로 1주 차를 TDD로 개발을 진행해본 결과 느낀 점은 다음과 같다.
1주 차를 통해 얻은 인사이트로 나머지 프리코스도 TDD로 계속 도전하려고 한다.
이 생각은 기존의 내가 개발을 진행해왔던 방법과, 프리코스에서 TDD를 진행하면서 클래스 내에 메소드 위치가 다르게 구성되어 의문이 생겨서 구글링을 해보았다. 클래스 변수 -> 인스턴스 변수 -> 생성자 -> 메소드 이러한 컨벤션은 이미 알고 있었고, 클래스 내 여러 메소드들 사이의 배치 순서에 대한 내용을 찾아보았다.
나는 메소드들을 접근 제어자 기준으로 작성하는 것보단 기능 및 역할별로 분류하여 다른 사람이 봤을 때 책을 위에서 아래로 읽는 것처럼 자연스럽게 읽히는 순서가 가장 이상적이라고 생각했다. 구글링을 해보니 내 생각과 동일했다.
전체 플로우를 정리해보자면,
7번이 나의 궁금증이었는데 해결이 되었다.
8번의 경우는 몰랐기 때문에 이번 온보딩에서는 신경 쓰지 못했는데, 다음 프리코스부터는 신경 써서 고려해봐야 할 부분이었고, 9번 경우 나는 개발할 때 setter를 아예 쓰지 않으며 getter 또한 dto에서만 사용하기 때문에 큰 연관은 없는듯하다.
https://stackoverflow.com/questions/4668218/are-there-any-java-method-ordering-conventions
프리코스 1주 차를 진행하면서 람다와 스트림을 적극 사용하기로 했다. 하지만 나는 모든 경우를 스트림으로 해결하기로 노력했고, 가독성에 장점이 있는 스트림이 오히려 가독성을 해치는 경우가 종종 발생했다. 무조건 스트림이 좋다고 생각한 내 생각에 의구심이 들어서 구글링을 통해 자료를 찾아보았다.
정리해보자면 아래와 같다.
이펙티브 자바 아이템 46
에 따르면,
forEach 연산은 최종 연산 중 기능이 가장 적고 가장 ‘덜’ 스트림답기 때문에, forEach 연산은 스트림 계산 결과를 보고할 때(주로 print 기능)만 사용하고 계산하는 데는 쓰지 말자...
이와 같이 내 생각이 틀렸음을 깨달았다. 온보딩 과정에서 어떠한 상황인지를 고려하지 않고, 무조건 스트림으로 해결하려고 해서 가독성을 해치는 경우가 있었다. 다음 프리코스부터는 무조건 스트림을 사용하기보다는 각 상황을 이해하여 스트림을 사용해야겠다.
https://stalker5217.netlify.app/java/stream-deeping/
https://tecoble.techcourse.co.kr/post/2020-05-14-foreach-vs-forloop/
기존에는 커밋을 할 때 클래스, 메소드 단위로 커밋을 주로 해왔다. 하지만 우테코 프리코스에서는 의미 있는 기능별 커밋에 대해 요구사항을 주고 있다. 하나의 기능을 구현하는데 3개의 메소드가 구현되었다고 하면, 기존에 했던 방법은 3번의 커밋이 발생했을 것이다. 또한 클래스 단위로 커밋을 했다면 여러 기능(메소드)들이 한 번에 커밋이 발생했을 것이다.
온보딩 과정을 통해 의미 있는 기능별로 커밋을 구성하다 보니깐 나중에 커밋 내역을 확인할 때 좀 더 직관적인 장점이 있었고, 버전을 되돌리기에도 더 유연했다. 그리고 프리코스 과정을 통해 Pull Request를 처음 경험하게 되었다. 우테코에 합격해서 백엔드 협업 과정을 겪는다면, 깃허브를 활용한 협업에 대한 경험을 더 할 수 있을 것으로 기대하고 있다.
프로그래밍을 독학해오며 혼자 무엇을 공부해야 하는지 공부하는 것 조차 힘들었는데, 프리코스 미션을 진행하면서 자연스럽게 느낌 점과 궁금한 점, 부족한 점을 통해서 무엇을 공부해야하는지 깨닫게 되고, 이것들을 하나씩 채워갈 때마다 성장하고 있음을 느꼈으며 앞으로의 프리코스 과정도 기대가 된다.😊
[우아한 테크 코스 5기] 가장 강력한 예외 처리 방법은 무엇이 있을까요? (1) | 2022.12.11 |
---|---|
[우아한 테크 코스 5기] 여러분은 MVC에 대해서 얼마나 알고 계신가요? (0) | 2022.11.28 |
[우아한 테크 코스 5기] 프리코스 4주차 - 다리 건너기 회고 (0) | 2022.11.22 |
[우아한 테크 코스 5기] 프리코스 3주차 - 로또 회고 (0) | 2022.11.15 |
[우아한 테크 코스 5기] 프리코스 2주차 - 숫자 야구 게임 회고 (0) | 2022.11.08 |