본문 바로가기
우아한테크캠프pro

[우아한테크캠프pro] 6주차 미션 : 레거시 코드 리팩터링 후기, 코드리뷰 (자바 백엔드, NextStep, 우아한형제들, 우테캠pro, 우테캠프로)

by 개발하는 지토 2021. 1. 24.

6주 차 미션 : 레거시 코드 리팩터링

 

저장소: github.com/next-step/jwp-refactoring/tree/jhhj424

1차 리뷰: github.com/next-step/jwp-refactoring/pull/15

2차 리뷰: github.com/next-step/jwp-refactoring/pull/24

3차 리뷰: github.com/next-step/jwp-refactoring/pull/40

4차 리뷰: github.com/next-step/jwp-refactoring/pull/58

 

 

참고자료: 조영호 님의 `우아한 객체지향` 발표 , 이동욱 님의 `우아한 객체지향` 정리 , 권용근 님의 `멀티모듈` 정리 , gradle 에서 compile과 implementation의 차이 , gradle에서 api 추가 플러그인 설정

 


후기

  • 레거시 프로젝트를 분석하고 요구 사항을 작성할 수 있다.
  • 기존 요구 사항을 만족하는 테스트 코드를 먼저 작성하여 안정적인 리팩터링을 할 수 있다.
  • 테스트 코드를 기반으로 하여 리팩터링 할 수 있다.
  • 도메인들의 의존관계를 분리하고, 나아가 패키지들 사이의 의존관계를 분석 및 분리할 수 있다.
  • 의미 있는 단위로 Gradle 멀티 모듈 구성을 할 수 있다.

이번 과정의 목표

많은 기업들이 "서비스를 안정적으로 운영하면서 레거시 코드를 리팩터링 할 수 있는 역량을 갖춘 개발자"를 요구한다.
  • 레거시 프로젝트를 리팩터링 하는 경험을 통해 서비스를 안정적으로 운영하면서 레거시 코드를 리팩터링 할 수 있는 역량을 키운다.
  • 프로젝트를 만드는 단계에서 끝나는 것이 아니라 프로젝트를 완료한 후 일정 기간 유지보수를 함으로써 레거시 코드를 리팩터링 하는 경험을 쌓는다.

주요 내용

  • 리팩터링 프로세스와 일반 원칙 이해하기
  • 프로그램을 더 쉽게 이해하고 변경하는 유용한 리팩터링 빠르게 적용하기
  • 리팩터링 가능성이 있는 코드에서 풍기는 악취 인식하기
  • 각 리팩터링 기법의 개념, 동기부여, 역학 및 간단한 사례 살펴보기
  • 리팩터링을 수행하는 견고한 테스트 구축하기
  • 리팩터링의 장단점과 장애물 인식하기

내 코드 피드백

공통적으로 사용되는 `테스트 픽스쳐` 는 중복을 제거해서, 가독성 그리고 추 후에 작성될 테스트 코드에서 편리하게 사용할 수 있겠다👍

 

Mock 테스트를 작성하게 되면, 테스트하기 어려운 요소를 분리해 원하는 데이터와 상태로 만들어 빠르게 테스트할 수 있는 장점이 있다.

 

하지만 이러한 Mock 테스트의 경우는 메서드 로직이 변경됐을 때 테스트 코드까지 영향을 줄 수 있어 코드 변경을 어렵고 번거롭게 만들어 유지 보수성을 떨어트릴 수 있고, 실제 내부 로직이 정확히 동작하는지 검증할 수 없다.

 

통제가 가능한 선에서는 Mock 테스트보단 @SpringBootTest를 사용한 통합 테스트를 고려해보는 것도 좋을 듯하다.

 

컨트롤러에 대한 테스트만 작성할 때는 @WebMvcTest 어노테이션을 사용할 수 있겠다!!

 

정답이 있는 가이드는 없지만, 다른 인스턴스 여도 같은 클래스 객체일 경우에는 필드 접근을 활용할 수 있겠다!😁

 

이것도 정답이 있다고는 생각하지 않는다, 그룹에서의 규칙이 있을 수도 있고, 개발자들 간의 생각이 다를 수도 있겠다고 생각한다.

 

이번에는 리뷰어님의 의견을 수용하여 변경을 하였고, 사실 본인보단 비교적 많은 걸 보고 배우신 분이기 때문에 앞으로는 해당 의견을 생각하고 작성하게 될 것 같다.

 

이 부분은 먼저 질문을 드렸었던 내용이었는데, 질문의 내용(좌)에 대한 답변을 명쾌하게 해 주셨다고 생각한다.💡

 

프로그래밍은 정답이 없는 부분이 굉장히 많기 때문에 더 재밌다고 생각한다, 물론 가이드라던가 이렇게 하는 편이 좋겠다. 하는 건 있을 수 있지만!!!

 

앞으로는 DTO에서 toMenu와 같은 형식의 도메인 생성을 자주 사용하게 되지 않을까 싶다.

 

물론 이 부분도 어떤 개발 그룹에서 어떤 규칙이 있는가에 따라 변경될 수 있겠다.😊

 

Stream 활용의 문제😂 reduce를 잘 사용하지 않았어서 해당 방법을 생각하지 못했다.

 

익숙한 방법이 있다고 할지라도 좀 더 좋은 방법이나 구성은 어떤 게 있을까 항상 생각하는 개발자가 될 수 있으면 좋겠다👍👍

 

(핑계) 매일 퇴근 후에 미션을 진행하면서 새벽 3~4시까지 진행하는 날들이 많았기에 마지막엔 정신없이 제출하게 되는 경우도 많았던 것 같다.

 

그렇지만! 항상 코드를 점검하고 PR을 보냈어야 됐는데 아쉬운 부분이다😢😢

 

좀 더 꼼꼼해질 필요가 있겠다👊

 

이전에 클래스에 대한 단위 테스트를 작성할 때 자주 사용했던 @Parameterized 어노테이션을 사용하여 가독성 좋은 코드를 작성할 수 있겠다.

 

@EnumSource라는 어노테이션을 활용할 수 있다는 것도 이번에 알게 되었다.👍👍

 

이번 미션을 진행하면서 가장 큰 실수가 아니었나 생각한다.

양방향 관계를 끊어내면서 이전에 영속성 전이를 통해서 저장되던 엔티티를 따로 영속화하지 않아서 저장되지 않는 문제점이 있었다.

 

그리고 양방향 관계를 모두 끊어내는 것도 좋은 방법이 될 수 있겠지만, 충분한 고려 사항을 확인하고 양방향 관계를 유지해도 좋을 때도 있을 것 같다.

 

그리고 도메인과 패키지의 관계들에 대해 고민이 있을 때는 다시 한번 `조영호 님의 발표를 참고하면 좋을 듯하다`

 

해당 발표 내용을 정리한 `이동욱 님의 블로그` 도 참고할 수 있겠다.

 

주기적으로 이에 대한 내용을 학습해서 확실하게 내 것으로 만들도록 해야겠다.

 

이번 미션에서 인수 테스트 작성에 대한 요구는 따로 없었지만 작성을 했었다.

 

작성하다 보니 목록 조회에 대한 검증에서 상태 코드 체크만 했었는데, 로직상 오류로 잘못된 응답이 올 수도 있기 때문에 실제 값 검증도 진행하면 좋겠다는 피드백을 받았다.

 

이에 따라 실제 반환되는 값에 대한 검증을 하도록 변경했다.

 

이번 미션을 진행하면서 직접 그려본 관계도였는데, Order와 Menu에 대한 의존성을 끊어서 Aggregate 경계를 나눌 수 있겠다는 의견이 있었다.

 

이에 따라 OrderLineItem에서 가지고 있는 Menu 객체 참조는 끊어냈고, id를 통해서 접근하여 검증 로직을 수행하도록 진행했다.

 

이 부분은 진행하면서 잘하고 있는지에 대한 의문이 있긴 했는데,

리뷰어분이 의도하신 대로 잘 작성한 것 같아서 기분이 좋았다 😊

 

 

 

 

마지막 Step에서 진행했던 멀티 모듈 적용 미션이었다.

 

공통적으로 사용하고 있다고 생각했던 공통 예외 처리에 대한 부분이나, 공통 도메인(값 객체) 클래스를 Common 패키지로 분리를 시도했었는데, 생각해보니 이렇게 작성하면 경계가 애매모호해질 수 있겠다고 생각이 들었고, 최종적으로는 Common 패키지를 없애버렸다.. ㅎㅎ 

 

이후에 정말 Commom이 필요할 때 고려해보는 것이 좋겠다.

 

멀티 모듈에 대해서는 `권용근 님이 작성하신 좋은 글` 이 있어서 참고하면 좋겠다👍

 

이에 대한 내용도 이전에 링크해둔 글을 읽으면 이해할 수 있다고 생각한다.

 

현재 프로젝트에서는 `애플리케이션 모듈 계층` 에서 하위 계층을 조립하여 `web application` 만 가지고 있다고 생각해서 `app-web`이란 이름의 모듈로 구성했다.

 

gradle 버전이 올라가면서 compile은 `implementation`, `api` 로 대체할 수 있다.

 

해당 글(build.gradle 에서 compile과 implementation의 차이 , api 추가 플러그인 설정)들을 참고할 수 있겠다.

 


끝으로...

이번 미션을 끝으로 약 2달간의 우아한 테크 캠프 pro 리뷰 미션은 모두 끝이 났다.

 

아무래도 회사를 다니면서 진행을 하다 보니 시간 제약이 있었고, 우테캠pro 과정을 하는 동안, 그리고 지금도 여기에만 집중하려고 했으며 다른 약속이나, 일정들은 되도록 차단했다.

 

평일에는 매일같이 회사 업무를 끝내고 칼퇴근을 했으며, 집에 와서 저녁을 먹고 미션을 진행했다.

 

같이 과정을 참여하시는 분들보다 경력도 적고 아직 모르는 게 많았다고 생각이 들었으며, 이를 채우기 위해서 많은 시간을 투자하여 학습을 진행함과 동시에 미션을 해나가야 한다고 생각을 했기 때문이었다.

 

미션을 진행하다 보면 새벽 두세 시는 기본이 되었고 어떤 날은 오기로 미션을 끝내려다가 해가 뜬 적도 있었다.

 

하지만 이 경험들 모두 소중하고 값진 경험이었고, 제일 중요한 건 미션을 진행하는 동안 너무 재밌었다는 점이었다. 미션 구성이나 리뷰어들과의 호흡이 더해져서 학습에 대한 재미, 미션에 대한 재미가 있었던 게 아닐까 하는 생각이다.

 

좋은 경험을 통해 많은 성장을 했다고 생각하고, 그럼에도 아직 많이 부족하기에 이 과정을 진행했던 동안의 마음가짐을 앞으로도 쭉 가지고 파이팅해야겠다!!!👊👊


컴퓨터가 이해할 수 있는 코드는 어느 바보나 다 짤 수 있다.

좋은 프로그래머는 사람이 이해할 수 있는 코드를 짠다. - 마틴 파울러

 

 

좋은 프로그래머가 될 수 있도록🙏

 

2021. 01. 24

댓글