221208 TIL
오늘 배운 것 & 한 일
항해 4주차 과제 코드 리뷰
오늘 항해 4주차가 끝났다. 하지만 과제는 결국 완성하지 못했다.
이번 주에 과제를 하면서 정말 많이 헤맸다. 혼자 계속 헤매다가 길을 잃지 않기 위해 매니저님께 1:1로 과제 코드 리뷰를 부탁드렸다. 그리고 코드 리뷰를 통해 정말 많은 걸 얻을 수 있었다.
이 코드 리뷰 덕분에 내가 헤매왔던 길, 시간이 모두 유의미하게 바뀌었다.
코드 리뷰를 통해 알게 된 내용들이 상당히 많아서 깔끔하게 정리하진 못하지만, 일단 오늘 알게 된 내용들을 모두 나열해보려 한다.
참고로 이건 이번 과제의 깃허브 링크이다.
https://github.com/minokim1080/hanghae4th
1. Cascade 쓰지 마라
요점만 말하자면 '내가 통제할 수 없는 코드는 지양하자' 였다.
Cascade도 어찌 보면 @Getter, @NoArgsConstructer 등의 어노테이션과 비슷하다고 볼 수 있지만 결이 많이 다르다.
@Getter, @NoArgsConstructer 등 우리가 자주 사용하는 롬복의 어노테이션들은 우리가 완전히 통제할 수 있는 것들이다. 왜냐하면 저 어노테이션들은 해당 클래스 안에 '한번' 작성될 코드들을 대신 작성해주는 것 뿐이기 때문이다. 그래서 우린 저 어노테이션의 결과를 온전히 이해할 수 있고, 통제할 수 있다.
하지만 Cascade는 아니다. Cascade는 '한번' 작성되고 끝이 아니라 조건이 맞을 경우 매번 대신 코드를 작성하고 진행해준다. 이런 경우 우리가 Cascade의 작동 원리를 온전하게 이해하고 있다 하더라도, 예기치 못한 상황이 발생할 수 있다.
그런데 심지어 Cascade는 SQL을 다루는 기능이다. SQL 자체가 서버 부하에 영향을 많이 끼칠 뿐 아니라, 데이터베이스를 다루기 때문에 DB에도 예상치 못한 영향이 갈 수도 있다. 그렇기에 Cascade의 사용을 지양하라고 하셨다.
특히나 Cascade의 delete 옵션은 절대 사용하지 말자. DB 내용 잘못 삭제됐다간 진짜로 회사를 날려먹을 수도 있다...
2. 클래스 이름에 복수형 쓰지 말자
3. 계층 구조는 제대로 나누자
계층 구조를 왜 그렇게 나누려고 하는지 원래 이해가 안갔었는데, 실무 얘기를 듣고 바로 이해가 갔다.
실무에서는 서로 다른 계층에서 작업을 맡아서 할 때, 같은 프로젝트인데도 다른 계층에 있는 패키지나 클래스에 접근 자체가 불가능한 경우가 있다고 한다!!
즉, 내가 맡은 영역 밖에 있는 정보들을 열람조차 하지 못할 수도 있다. 그래서 계층 분리와 역할 분리가 강조되었던 것이다.
그러니 지금부터라도 영역 분리를 잘 하도록 하자
내 과제의 영역 분리를 다시 하면 대략 이런 식으로 된다.
Response와 관련된 내용들은 Web 패키지에 Response 패키지로, Controller는 Controller 패키지로 넣자.
Domain에는 User, Post, Comment 패키지가 있고, 각 패키지 안에 Dto 패키지, Model 패키지, Repository 인터페이스가 있다.
Service에는 그냥 서비스 들어가면 된다. 과하게 분리하려 하지 말자. 자기가 맡아야 하는 비즈니스 로직은 자기가 구현한다.
Exception은 없어서 못 여쭤봤는데, 이건 나중에 여쭤보자. 아마 Service에 들어가는게 적절하지 않을까 싶다.
4. 서비스에서 ResponseEntity 반환하지 마라
저건 서비스에서 반환할 애가 아니다. 저건 Controller의 영역이다. 영역 분리를 확실하게 하자. 서비스에서는 그냥 Dto를 반환하자.
5. ~~RequestDto를 그대로 서비스에 넘겨주지 마라
RequestDto는 컨트롤러가 받는 가공이 안된 정보라고 볼 수 있다. 서비스 계층에 넘겨줄 때는 그걸 가공해서 필요한 곳에 넘겨주자. 그렇게 해야 코드들의 결합성이 낮아지고 재사용성이 높아진다.
예를 들어 PostRequestDto 가 있다고 해보자.
이걸 서비스에 넘겨주기 전에 파싱해서 PostDto로 만든 후 Service의 savePost 메소드에 전달한다.
savePost는 받아온 PostDto를 파싱해서 작업을 진행한다.
왜 이렇게 작업을 할까?? 이렇게 해두면 savePost에 들어오는 값이 다양해질 수 있기 때문에 보다 다양한 상황에 대처가 가능해진다. PostRequestDto를 거치지 않고 내부에서 save를 사용하는 것도 가능해진다.
웬만하면 뭔가를 받아서 그대로 넘겨주는 짓은 하지 말도록 하자.
6. Enum 이름 뒤에 Enum 붙이지 말자
7. 무의미하게 분리하려 하지 마라
한 클래스가 책임져야 할 일은 제대로 책임지게 하자.
이유없이 코드를 깔끔하게 하려다간 괜히 무의미한 분리를 하게 된다.
대표적인 예로 내 코드에서 PostService 클래스가 있었다.
자기 스스로 처리해야 할 로직들도 자꾸 밖에서 구현하려 하다 보니 일이 엄청 꼬였었다. 책임질 일은 스스로 책임지게 하자. 그로 인해 코드가 조금 길어지는 건 어쩔 수 없다.
8. 메소드의 재사용성은 최대한 높여라
한 클래스 안에 이런 메소드들이 있었다.
respondOK, respondCreated ...
이러한 메소드들은 모두 respond() 하나로 줄일 수 있었다.
만약 줄이는 과정에서 문제가 생긴다면, 다른 메소드들을 전부 private으로 만들고 respond() 안에서 if문을 써서 각 상황들에 맞게 응답이 나갈 수 있도록 짜보자.
잘한 점
매니저님께 1:1로 코드 리뷰를 신청했다. 상급자에게 코드 리뷰를 받을 기회가 있다면 최대한 그 기회를 이용하자. 내 코드가 부끄러울수록 더 좋다. 실력을 빠르게 늘릴 수 있는 가장 좋은 방법이라 생각한다.