[우아한테크코스 6기 BE] 1주차 회고 (지난 시간을 돌이켜보며)

반응형

지난 시간을 돌이켜보며

필자는 작년 5기에 지원했었지만 떨어진 경험이 있다.

작년 5기 지원 때를 돌이켜보면,

비전공자였기 때문에 경험이 정말 없어 프리코스 지원이 열리자 말자 백엔드에서 사용하는 언어인 "자바"를 학습하기 위해

부리나케 "자바의 정석"책을 사서 프리코스 시작전 한달동안 공부했었다.

하지만 한달이라는 시간은 자바에 대해 제대로 알기에는 턱 없이 부족한 느낌이 있었다.

글로는 배웠지만 실제로 써먹는 법을 잘 몰랐기 때문이다...

그 때는 5주간 미션을 진행했는데 5주동안 모든 시간을 프리코스에 몰입하여 투자했기 때문에 비록 실력이 부족했을지라도 살짝의 기대는 있었다.

그렇기 때문에 탈락이라는 결과를 받았을 때 큰 허탈함이 있었다.

무엇보다 아무것도 모르는 상황에서 앞으로 혼자 어떻게 공부를 해야할지 정말 감이 잡히지 않았다.

일다는 기초 지식도 부족했기 때문에 기초 지식부터 학습하는 방법으로 나아갔고

이후에는 각종 커뮤니티에 가입해 질문해보고, 검색을 통해 자바와 관련된 지식들을 찾아보며 무엇을 학습해야할지 알아보았다.

그렇게 1년이라는 시간동안 쉬지 않고 CS, Spring, JPA, DB, 오픈소스 등등 정말 많은 것을 학습했고

개인 프로젝트를 진행해보며 학습내용들을 체화 시킬 수 있도록 하였다.

프로젝트를 완성하고 난 후에는 우테코 6기 모집과 시기가 딱 맞아 떨어지게 되었고

그 동안 몰입했던 경험들을 5일 동안 자소서를 여러번 수정해가며 솔직하게 전달하려고 작성하려 했다.

확실히 느낀건 그 간의 노력들로 나의 이야기가 많이 생겨 정말 하고 싶은 말이 많았다.

하지만 1000자 제한이라서 이 글자 수 안에 전하고자 하는 내용을 다 담기는 어렵더라 😥

자소서 제출 마감 이후 2023년 10월 19일 (목) 드디어 기다리던 우테코 프리코스가 시작되었다 !


1주차 미션

1주차 미션은 숫자 야구 게임을 받았다.

이 미션은 작년에도 나왔던 문제여서 이해하는데 어렵진 않았다.

우테코 프리코스 미션은 객체 지향 프로그래밍이 핵심이라 생각했기 때문에 "이펙티브 자바"책을 사서

객체 지향적으로 잘 설계하여 작성하려 욕심을 좀 내보았다.

 

제출 코드
 

GitHub - Hyeon0208/java-baseball-6

Contribute to Hyeon0208/java-baseball-6 development by creating an account on GitHub.

github.com

 

시작하기 앞서 미션의 README.md에 나와있는 요구사항들을 꼼꼼히 검토하였다.

그리고 추가적으로 다음과 같은 부분들을 나 자신에게 미션으로 주었다. 

  1. 요구사항을 잘 지켰는가?
  2. 예외 처리를 꼼꼼히 했는가?
  3. 코딩 컨벤션 규칙을 잘 준수했는가?
  4. 단위 테스트를 꼼꼼히 작성하여 기능 검토하기
  5. 요구사항에 작성한 기능 별로 커밋하기
  6. 우테코 문서에 있는 PR 체크리스트에 있는 객체지향 생활체조 원칙을 잘 지켰는지?
    https://github.com/woowacourse/woowacourse-docs/blob/main/cleancode/pr_checklist.md

무엇을 배웠나?

스프링 프레임워크를 사용하다보니 순수 자바를 이용해서 객체지향적으로 설계하는 것은 좀 어색했고 어려움이 있었다.

그래서 일단 구현을 완성한 다음 위 규칙들을 검토해가며 리팩토링을 통해 하나씩 개선하는 방향으로 나아갔다.

객체 지향적으로 설계하는 것은 정말 쉽지 않았다..

고민끝에 완성한 코드들도 계속 아쉬움이 있어서 다시 설계 해보며 다른 사람이 코드를 보고도 쉽게 이해할 수 있도록 구현하려고 노렸했다.

그렇게 정말 수많은 리팩토링 과정이 있었고 이 과정을 통해 객체지향 설계에 대해 조금 더 친숙해질 수 있게 된것 같다.

 

객체가 할 수 있는 일은 객체에게

스프링을 통해 애플리케이션을 구현하면 Controller - Service - Repository 구조를 사용할 것이다.

그래서 이번 미션에서도 처음에 service 레이어를 두고 비즈니스 로직을 담았었다.

객체가 할 수 있는 일을 service에 위임하고 있던 것이다.

객체 지향에서는 객체가 할 수 있는 일은 객체가 담당해야 한다.

그런데 service가 들고 있는건 조금 어색했다.

결국 service에 있는 로직을 각 객체가 할 수 있는 일은 자신이 하도록 옮겨보았다.

이렇게 수정하니 코드가 정말 깔끔해졌고, 객체가 객체다워짐을 느낄 수 있었다.

 

그렇다면 service 레이어를 두는 것은 객체지향적이지 못한건가??

객체가 할수있는 일을 service에 위임하여 중앙화시킨다면 OOP 원칙에 어긋날 수 있다.

하지만 여러 도메인 모델을 조합하여 복잡한 비즈니스 로직을 수행해야 한다면 Service 레이어를 두는 것이 효과적일 수 있다.

 

getter 없이 구현하기

특히 스프링을 이용해 애플리케이션을 구현할 때 도메인 객체에 Setter는 사용하지 않는 것은 익숙했지만 Getter는 자주사용해

객체지향 생활체조 원칙 중 "getter/setter 없이 구현했는가?"가 발목을 많이 잡았다.

List<> 컬렉션 타입 필드만을 가진 Number라는 객체를 일급 컬렉션으로 만들고, Computer 객체와 Player 객체는 이 Number를 필드로 갖게 했는데

두 객체가 갖고 있는 Number 필드의 값을 비교해서 스트라이크 수와 볼 수를 구하는 부분에서 익숙했던 getter를 사용하지 않고 서로 통신하려니 생각보다 쉽지 않았다..

수 많은 고민 끝에 현실에 반영하여 생각했던 Computer와 Player가 서로 통신하는 그림에 맞게

객체가 할 수 있는 작업은 객체가 담당하게 하고, 객체에 메시지를 보내 로직을 수행하도록 하여 캡슐화를 유지하면서 객체를 객체 답게 사용할 수 있었다.

 

getter를 무조건 사용하지 않는 것 어려울 것이다.

하지만 getter 사용을 지양할 수 있다면 객체에 메세지를 보내 내부 로직을 통해 값을 반환 받는 것이 좋다고 생각한다.

만약 getter 사용을 피할 수 없다면 불변의 값을 반환하도록 하자.

getter를 허용하다는 것 자체가 객체 내부 구조를 알리는 것이기 때문에 캡슐화의 원칙을 깨지만

분명 모든 원칙을 다 지키면서 프로그래밍하기 어려운 상황도 있을 것이다.

그러니 잘 판단해서 적절히 사용하는 것이 바람직한 방법이라 생각한다.

 

디미터 법칙에 대한 오해

디미터 법칙에 대해 단순히 점(.)을 두번 사용하면 안된다고 오해하고 있었다.

이 문제에 대해서는 아래 포스팅에 정리해두었다.

 

[OOP] 디미터 법칙에 대한 오해와 디미티 법칙에 대해

객체지향 프로그래밍을 잘 하기 위한 9가지 원칙을 준수해가며 코드를 리팩토링 하는 과정에서 디미터 법칙에 대한 오해가 한 가지 생겼습니다. Enum 클래스의 경우 열거형 상수 값을 가져 올 때

hstory0208.tistory.com


아쉬웠던 점

이번에 제출한 코드에 대해 지원자분들과 리뷰하는 과정에서 많은 점들을 배울 수 있었고 칭찬도 있어 기분이 좋았다.

특히 내 코드에 대해 한 부분이 아리까리 했었는데 한분이 그 부분에 대해 피드백을 주셔서 인상 깊었다.

아래 사진은 해당 피드백을 주신 분이 작성한 글에 대한 필자의 답변이다.

getter 사용을 피하고 Computer와 Player 객체가 소통하려했지만 현재 내 코드 설계는 Player 객체의 존재가 의문인 상황이다.

Player 객체를 없애고 플레이어의 번호를 Number 타입으로 Number playerNumber 사용 했으면 좀 더 깔끔할 수 있었을 텐데 너무 Player 객체를 고집했나 싶다..

다음 미션 부터는 클래스의 역할에 대해 신중하게 고민해볼 필요가 있을 것 같다.