-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BE] 이근표 강화하기 #2
base: rootTiket
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다!
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매개변수가 있는 생성자를 대체하기 위해 정적 팩토리 메서드를 사용하신 것이라면, 해당 어노테이션은 필요가 없는 어노테이션이라 생각되는데 혹시 어떤 이유로 사용하셨을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구현된 정적 팩토리는 유저가 가지고 있는 확률아이템의 개수를 감소시키는 메서드 였습니다!
import static org.springframework.http.HttpStatus.OK; | ||
|
||
@RestController | ||
@EnableJpaAuditing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EnableJpaAuditing
를 컨트롤러에 어노테이션을 붙여주신 이유가 궁금합니다!
저는 JpaAuditingConfig라는 auditing 기능을 담당하는 클래스를 만들고, 이 클래스에 해당 어노테이션을 붙여주는데 그 이유는 다음과 같습니다.
한 번 참고해 보시면 좋을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지적 감사합니다! 수정하였습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserResponseMessage
enum 에서는 @Getter와 @AllArgsConstructor로 처리해주셨는데, 해당 클래스에서는 직접 getter와 생성자를 만드신 이유가 궁금합니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
서비스로직 중 level 객체에서 정보를 가져와야 하는 부분이 있어 필요에 의해 만들었습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니당
public User checkValidUser(LoginRequest loginRequest) { | ||
if (!(userRepository.findByEmail(loginRequest.email()).isPresent())) { | ||
throw new InvalidIdException(); | ||
} else if (!(userRepository.findByPassword(loginRequest.password())).isPresent()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해싱도 하면 좋을 거 같아요 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
누락된것 같습니다 감사합니다!
public static Optional<Level> getLevelByNumber(int levelNumber) { | ||
return Arrays.stream(values()) | ||
.filter(level -> level.getLevel() == levelNumber) | ||
.findFirst(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7레벨 넘게 된다면 리턴 값이 null 일 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로직 분리 중 누락되었네요 감사합니다
private static final int MAX_DESTROY_RATE = 50; | ||
|
||
public void createWeapon(Authentication authentication, CreateWeaponRequest createWeaponRequest) { | ||
User user = userRepository.findByEmail(authentication.getName()).orElseThrow(UserNotFoundException::new); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User 객체를 가져오는 로직이 메서드마다 동일하게 존재하는데 컨트롤러 내부에서 하나의 메서드로 뺴두고 호출하면 중복도 피하고 가독성 면에서도 좋을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
참고하겠습니다 !
@Slf4j | ||
@RestControllerAdvice | ||
@RequiredArgsConstructor | ||
public class GlobalExceptionHandler { | ||
private static final String LOG_FORMAT = "Class : {}, Code : {}, Message : {}"; | ||
@ExceptionHandler(ServiceException.class) | ||
public ResponseDto handleApplicationException(ServiceException ex) { | ||
log.error(LOG_FORMAT, ex.getClass().getSimpleName(), ex.getErrorCode(), ex.getMessage()); | ||
return ResponseDto.of(ex.getErrorCode(), ex.getMessage()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
덕분에 저도 컨트롤러를 간결하게 작성할 수 있었어요
에러는 다른 곳에서 핸들링 하는 게 보기 좋네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다 :)
if (useIncreaseProbability && user.getIncreasingProbability() <= 0) { | ||
throw new NoItemException(); | ||
} else if (useIncreaseProbability) { | ||
userRepository.save(User.decreaseItem(user)); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
얼리리턴 형식으로 바꿀 수 있을거 같아요!
if (random.nextInt(RANDOM_BOUND) < 50) { | ||
this.level = 0; | ||
return new EnhanceResponse(DESTROYED, this.level); | ||
} else { | ||
this.level--; | ||
return new EnhanceResponse(LEVEL_DOWN, this.level); | ||
} | ||
} else { | ||
return new EnhanceResponse(UPGRADE_FAILED, this.level);} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이것도 얼리리턴 형식으로 바꾸면 더 깔끔할 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
최고!
❓ 어떤 기능을 구현하였나요?
✅ 회원가입 기능 구현
결과 사진
✅ 로그인 기능 구현
결과 사진
✅ 강화기능 구현
결과 사진
강화권 소진 시 예외
✅ 아이템 생성 구현
결과 사진
✅ 아이템 조회 구현
결과 사진
✅ 아이템Top10 조회 구현
결과 사진
🤔 구현 중 무엇을 고민했을까요?
최초 구현 코드
아무리 봐도 읽기 쉽지 않은 코드
기존 강화는 weaponEnhance(아이템 관련 로직을 처리하는 함수) 에 모두 구현되어 있었습니다.
함수 분리
가독성도, 유지보수도 어려운 코드 인 것 같아 확률을 얻어오는 함수, 강화를 담당하는 함수, 강화실패시 로직을 처리하는 함수를 분리하자는 생각으로 리펙토링을 진행하였습니다.
클래스 분리
💭 어차피 강화는 무기(아이템)의 수치를 변경하는 것 아닌가? 클래스를 분리해보자!
💭 아쉬운 점은?
스트림, 람다를 공부 하고 있어 최대한 활용해보려고 노력했습니다. 또한 기존이라면
서비스에서 처리해야 할 것 같다
하는 부분도 더 고민해 보며객체에서 변경 가능한가?
,이걸 서비스에서 처리하는게 맞나?
를 고민해보며 코드를 짰던 것 같습니다.클래스 분리 한 강화 코드에서 반환 형태를 ResponseDto로 넘기는 부분은 코드의 의미가 명확하지 못해서 다른 클래스로 전달하여 처리하는 로직으로 수정하려고 합니다.