안녕하세요. 카카오 테크 캠퍼스 4주차 코드 리뷰 결과를 들고 왔습니다. 이번 주 코드 리뷰는 3주차에 비해 쪼금 많았는데요 ㅎㅎ 그만큼 코드가 더 깔끔해진 것 같습니다.
아래 pr에서 코드 리뷰 받은 것을 볼 수 있습니다.
https://github.com/kakao-tech-campus-2nd-step2/spring-gift-enhancement/pull/130#event-13547149495
충남대 BE_이은경 4주차 과제 (1단계) by pkyung · Pull Request #130 · kakao-tech-campus-2nd-step2/spring-gift-enhanc
과제 진행 사항 상품 카테고리 카테고리 도메인 설계 상품과 관계 설정 카테고리 ru 구현 화면 반영 - 상품과 함께 추가 구현에 대한 부가 설명 카테고리는 상품 생성 이전에 데이터베이스에 미
github.com
충남대 BE_이은경 4주차 과제 (2단계) by pkyung · Pull Request #247 · kakao-tech-campus-2nd-step2/spring-gift-enhanc
과제 진행 사항 상품 옵션 옵션 도메인 설계 옵션 dto validation 설정 상품과 옵션 설정 옵션 cr 구현 옵션 이름 중복 확인 메서드 생성 (도메인 계층에 생성)
github.com
https://github.com/kakao-tech-campus-2nd-step2/spring-gift-enhancement/pull/379#event-13594246113
충남대 BE_이은경 4주차 과제 (3단계) by pkyung · Pull Request #379 · kakao-tech-campus-2nd-step2/spring-gift-enhanc
과제 진행 사항 옵션 수량 차감 수량 차감 메서드 생성 얼만큼 양을 뺄 건지의 dto 부족한 수량에 대한 exception 생성
github.com
구현한 기능📄
# spring-gift-enhancement 🎁
## 4주차 기능 목록 📄
### 상품 카테고리
- [x] 카테고리 도메인 설계
- [x] 상품과 관계 설정
- [x] 카테고리 ru 구현
- [x] 화면 반영 - 상품과 함께 추가
### 상품 옵션
- [x] 옵션 도메인 설계
- [x] 옵션 dto validation 설정
- [x] 상품과 옵션 설정
- [x] 옵션 cr 구현
- [x] 옵션 이름 중복 확인 메서드 생성 (도메인 계층에 생성)
### 옵션 수량 차감
- [x] 수량 차감 메서드 생성
- [x] 얼만큼 양을 뺄 건지의 dto
- [x] 부족한 수량에 대한 exception 생성
받은 피드백🎯 - step1 상품 카테고리
메서드 이름에 모델 이름은 없어도 된다
기존의 코드에서는 updateCategory라는 이름의 메서드로 카테고리 수정을 진행했습니다. 그러나 컨트롤러가 CategoryController이기 때문에 update 만 적어도 category를 수정하는 것을 알 수 있기 때문에 메서드 이름을 단축할 수 있다는 피드백을 받았습니다.
// 기존 코드
@PutMapping("/categories")
public ResponseEntity updateCategory(CategoryRequest request) {
categoryService.updateCategory(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
]
// 수정 코드
@PutMapping("/categories")
public ResponseEntity update(CategoryRequest request) {
categoryService.update(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
]
exception 관리하는 법
사실 exception에 대한 피드백은 이전부터 받았었습니다. 점점 NotFoundException이 많아지니 NotFoundException을 공통으로 만들어서 처리하라는 피드백이었습니다.
그러나, 제가 이전의 피드백을 잘못 이해하여 각 컨트롤러의 에러를 처리하는 ExceptionHandler를 NotFoundExceptionHandler로 처리하는 방법으로 해결을 했었습니다.
하지만 이번 피드백을 받으면서 무슨 말인지 이해했고, CategoryNotFoundException, ProductNotFoundException, OptionNotFoundException 등의 Exception을 모두 NotFoundException으로 합쳐서 처리하도록 수정했고, 기존의 Handler를 GlobalExceptionHandler 클래스로 만들어서 exception을 처리하도록 했습니다.
그래서 아래와 같은 파일 구조를 갖도록 처리했습니다.
MemberNotFound의 경우에는 product나 category를 찾지 못하는 에러와는 사뭇 다른 느낌의 에러여서 따로 분리하여 처리했습니다.
exception/
├── auth/
│ └── UnauthorizedException.java
├── user/
│ └── MemberNotFoundException.java
└── AlreadyExistsException.java
│
└── GlobalExceptionHandler.java
│
└── NotFoundException.java
│
└──OutOfStockException.java
콜렉션 변수형은 복수형으로 작성한다
기존의 코드에서는 아래와 같이 변수명을 작성했다. 콜렉션인 경우 변수명에 콜렉션을 적기보다는 복수형으로 적는게 명확하다고 피드백을 주셨습니다.
사실은 해당 변수가 진짜 List 형식이 아니라면 사용하지 말고 (나의 경우는 진짜 List 타입임), categories, categoryGroup, bundchOfCategories 등으로 표현하는 것이 좋다고 하셨는데 현업에서 사용하는 방식인 것 같았습니다.
// 기존 코드
@GetMapping("/categories")
public ResponseEntity findAllCategories() {
List<Category> categoryList = categoryService.findAllCategories();
}
// 수정 코드
@GetMapping("/categories")
public ResponseEntity findAllCategories() {
List<Category> categories = categoryService.findAllCategories();
}
수정 후 반환은 200, 204
기존의 코드에서는 수정 후에 201 created를 반환했습니다. 그러나 수정은 리소스가 생성된 것이 아니기 때문에 200 ok 또는, 204 no_content를 쓰는 것이 좋다는 피드백을 받았습니다.
// 기존 코드
return ResponseEntity.status(HttpStatus.CREATED).build();
// 수정 코드
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
body가 없는 ResponseEntity는 Void 지정을 하자
body가 없는 경우 Void로 제네릭 타입을 지정하면 의미 전달이 더 잘될 것 같다는 피드백을 받아서 수정했습니다.
// 기존 코드
@PutMapping("/categories")
public ResponseEntity updateCategory(CategoryRequest request)
// 수정 코드
@PutMapping("/categories")
public ResponseEntity<Void> updateCategory(CategoryRequest request)
color와 imageUrl validate 지정하기
기존의 dto 와 entity 코드에서 validate 지정이 안된 색깔 필드와 이미지 링크 필드의 validate를 지정하라는 피드백을 받았습니다. 색깔의 경우 #aaa 또는, #ffffff 가 될 수 있어서 정규식을 통해 검증을 진행했고 imageUrl은 https:// 로 시작할 것 같아서 이와 같은 정규식으로 지정을 했습니다.
@NotBlank
@Pattern(regexp = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", message = "색상 코드가 적절하지 않습니다.")
String color,
@NotBlank
@Pattern(regexp = "https://.*$", message = "이미지 주소가 적절하지 않습니다.")
String imageUrl,
responseType 계층형으로 둘 것
기존의 productResponse 에서 category에 대한 정보를 categoryName, categoryId로 String 타입과 Long 타입으로 지정을 해줬었습니다. 그런데 멘토님께서 대부분 계층형으로 둔다고 하셔서 아하 그렇구나 마인드로 바로 수정했습니다.
public record ProductResponse(
Long id,
String name,
int price,
String imageUrl,
Category category
) {
}
받은 피드백🎯 - step2 상품 옵션
불필요한 for문보다는 stream으로 처리하기
아래의 코드를 stream을 통해 수정해보라는 피드백을 받아서 수정했습니다.
// 기존 코드
public boolean checkDuplicateOptionName(String optionName) {
for (Option option : options) {
if (option.getName().equals(optionName)) {
return true;
}
}
return false;
}
}
// 수정 코드
public boolean checkDuplicateOptionName(String optionName) {
return options.stream()
.anyMatch(option -> option.getName().equals(optionName));
}
product와 category 관계 설정 생성자에서 하기
원래는 setter를 통해 product와 category의 관계를 설정했습니다. 멘토님께서 생성자를 통해 관계 설정 해보는 것이 어떤지에 대해 피드백을 주셔서 수정했습니다.
setter에서 사용하던 코드를 그대로 가져오긴 했습니다. 😅
public Option(String name, Long quantity, Product product) {
this.name = name;
this.quantity = quantity;
if (this.product != null) {
this.product.getOptions().remove(this);
}
this.product = product;
if (product != null) {
product.getOptions().add(this);
}
}
받은 피드백🎯 - step3 옵션 수량 차감
두 번 계산하게 되는 경우 변수로 추출하기
this.quantity - quantity 과정을 반복하기 때문에 remainingQuantity라는 변수를 사용하여 저장한 뒤, 조건문과 필드에 저장을 좀 더 직관적으로 할 수 있었습니다.
// 기존 코드
public void subtract(Long quantity) {
if (this.quantity - quantity >= 0) {
this.quantity -= quantity;
return;
}
throw new OutOfStockException("해당 옵션의 수량이 부족합니다.");
}
}
// 수정 코드
public void subtract(Long quantity) {
Long remainingQuantity = this.quantity - quantity;
if (remainingQuantity < 0) {
throw new OutOfStockException("해당 옵션의 수량이 부족합니다.");
}
this.quantity = remainingQuantity;
}
후기🎓
이번 주도 좋은 피드백을 많이 받아 좀 더 깨끗한 코드를 작성하기 위한 발판이 된 것 같습니다. 앞으로도 파이팅🥊
'🍫카카오 테크 캠퍼스 2기 BE' 카테고리의 다른 글
[카카오 테크 캠퍼스 / BE] 아이디어톤 상을 타버렸습니다 (1) | 2024.08.30 |
---|---|
[카카오 테크 캠퍼스 / BE] 2단계 세 번째 코드 리뷰 (1) | 2024.07.14 |
[카카오 테크 캠퍼스 / BE] 2단계 두 번째 코드 리뷰 (0) | 2024.07.14 |
[카카오 테크 캠퍼스 / BE] 2단계 첫 번째 코드 리뷰 후기 (0) | 2024.07.02 |
[카카오 테크 캠퍼스 / BE] 두 번째 미니과제, 자동차 경주🚗 (1) | 2024.06.10 |