-
Notifications
You must be signed in to change notification settings - Fork 1
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
반경 내 주차장 조회 기능 구현 #13
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.
각각 커멘트 남겼씁니다 _
public static final String DISTANCE_ORDER_CONDITION = "가까운 순"; | ||
private final ParkingRepository parkingRepository; |
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 ParkingLotsResponse findParkingLots(ParkingQueryRequest parkingQueryRequest) { |
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 java.util.List; | ||
import lombok.Getter; | ||
|
||
@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.
@NoArgsConstructor(access = AccessLevel.PRIVATE)
import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
||
@Component | ||
public class ParkingQueryArgumentResolver implements HandlerMethodArgumentResolver { |
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.
👍
# Conflicts: # src/main/java/com/example/parking/domain/parking/ParkingRepository.java # src/main/resources/application.yml # src/test/java/com/example/parking/auth/AuthServiceTest.java # src/test/resources/application.yml
Test Results127 tests 127 ✅ 2s ⏱️ Results for commit 4fe6e61. ♻️ This comment has been updated with latest results. |
|
|
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.
고생하셨습니다 영호씨 🙇♂️
리뷰 남겼어여 확인부탁드려요
@@ -16,6 +18,13 @@ public enum OperationType implements SearchConditionAvailable { | |||
this.description = description; | |||
} | |||
|
|||
public static List<String> getAllValues() { |
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.
중복 메서드 SearchConditionAvailable
에 아래 메서드 만들어서 쓰는게 나을거 같아여
static <E extends SearchConditionAvailable> List<String> getAllValues(E... values) {
return Arrays.stream(values)
.filter(e -> e != e.getDefault())
.map(E::getDescription)
.toList();
}
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.
적용했습니다~
@@ -26,6 +26,25 @@ public static List<String> getAllValues() { | |||
.toList(); | |||
} | |||
|
|||
public static List<PayType> collectMatch(List<String> descriptions) { |
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.
이것도 SearchConditionAvailable
모으는게 나을거 같아여
static <E extends SearchConditionAvailable> List<E> collectMatch(List<String> descriptions, E... values) {
return descriptions.stream()
.map(d -> (E) find(d))
.toList();
}
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.
이게 싫으면 SearchConditionAvailable
인터페이스에는 필요한 메서드만 두고 SearchConditionMapper
에 Enum <-> String 간 변환 로직 둬도 괜찮을 거 같아여.
아래는 생각해본 예시임다,
public interface SearchConditionAvailable {
String getDescription();
<E extends SearchConditionAvailable> E getDefault();
<E extends SearchConditionAvailable> E[] values();
}
public class SearchConditionMapper {
public static <E extends SearchConditionAvailable> List<E> toEnums(E sc, List<String> descriptions) {
return descriptions.stream()
.map(description -> toEnum(sc, description))
.toList();
}
public static <E extends SearchConditionAvailable> E toEnum(E sc, String description) {
return (E) Arrays.stream(sc.values())
.filter(e -> description.startsWith(sc.getDescription()))
.findAny()
.orElse(sc.getDefault());
}
public static <E extends SearchConditionAvailable> List<String> toStrings(E sc) {
return Arrays.stream(sc.values())
.filter(e -> e != sc.getDefault())
.map(e -> ((SearchConditionAvailable) e).getDescription())
.toList();
}
}
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.
모던 자바의 신이시네여; 코드 그대로 썼습니다.. 감사해요..
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.
적용했습니다~
@@ -22,19 +22,17 @@ public class ParkingDomainService { | |||
|
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.
ParkingDomainService
역할이 짬뽕된거 같아여
이름은 Domain
, 어노테이션은 Component
라서 도메인 서비스 같아 보이지만
패키지는 application
에 있고 반환도 response
반환하고 있어서 어플리케이션 서비스 같이도 보여여
하나로 맞춰주셨으면 합니다
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.
조회 조건에 맞게 필터링하는 절차지향적인 로직이라 별도의 Service 를 만들어서 ParkingService 를 조금 더 간결하게 해보려고 했는데 ParkingService 내부 private 메서드로 수정하는게 더 나을까요??
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.
일단 제가 의도한건 Application Service 가 더 맞는거같아서 네이밍 수정할게요~
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.
List 을 응답 dto 로 만들기 위해서 예상 요금, 도보 시간 계산, 즐겨 찾기 유무 확인해서 만드는 로직이 절차지향적이라 이 메서드를 ParkingService 의 private 메서드로 옮길지 ParkingApplicationService 에 둘지 계속 고민되네여,, 뭐가 더 괜찮아보이시나여?
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.
새로 서비스를 나눠서 구현한건 좋은 거 같습니다.
그렇지만, 조회 조건에 맞게 필터링하는 건 ParkingFilterService
같은 도메인 서비스를 두고 ParkingResponse
로 변환해주는 코드는 Application Service 내부에 private 메소드로 둬도 괜찮을 거 같아여
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ParkingMemberId { |
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.
MemberAuth
랑 역할이 동일한거 같은데
무슨 차이인가여?
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.
기존의 MemberAuth 는 잘못된 인증 정보면 예외를 던지는데 주차장 조회 기능에선 memberId 가 없으면 즐겨찾기 값을 전부 다 false 로 반환해야됩니다.
그래서 기존 MemberAuth의 잘못된 인증정보 시 예외던지는 코드를 주차장 조회 기능 때문에 null 을 반환하게 하면 MemberAuth 를 사용하고 있는 다른 로직에서 반환된 값의 null 체크를 하고 예외처리를 해야되기 때문에 예외 말고 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.
같은 목적의 어노테이션을 두개로 늘리기 보다는
아래처럼 필드를 추가해주고
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberAuth {
boolean required() default true;
}
아규먼트 리졸버에서 required 값을 판단해서 아래처럼 내려주면 될 거 같습니다
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
MemberAuth memberAuth = memberAuthFrom(parameter);
if (memberAuth.required()) {
String sessionId = webRequest.getHeader(JSESSIONID);
MemberSession session = authService.findSession(sessionId);
return session.getMemberId();
}
return null;
}
private MemberAuth memberAuthFrom(MethodParameter parameter) {
return parameter.getParameterAnnotation(MemberAuth.class);
}
그러고 회원 정보가 필수가 아닌 컨트롤러에서 적용해주면 될 거 같습니다
@GetMapping("/parkings")
public ResponseEntity<ParkingLotsResponse> find(
@ParkingQuery ParkingQueryRequest parkingQueryRequest,
@ParkingSearchCondition ParkingSearchConditionRequest parkingSearchConditionRequest,
@MemberAuth(required = false) Long memberId
) {
ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest,
parkingSearchConditionRequest, memberId, LocalDateTime.now());
return ResponseEntity.ok(parkingLots);
}
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 String RECOMMEND_ORDER_CONDITION = "추천 순"; | ||
|
||
private final List<String> operationTypes; | ||
private final List<String> parkingTypes; | ||
private final List<String> feeTypes; | ||
private final String feeTypes; |
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.
요건 제가 놓쳤네염. 감사합니다~
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.
적용했습니다~
return false; | ||
} | ||
|
||
private List<String> toCollection(String[] parameters) { |
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.
toList()는 어때요 ?
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.
고민했었는데 toList로 바꿀게여 ㅋㅋㅋㅋ
|
||
List<ParkingResponse> parkingResponses = new ArrayList<>(); | ||
for (Parking parking : parkingLots) { | ||
Fee fee = parkingFeeCalculator.calculateParkingFee(parking, now, now.plusHours(hours)); |
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.
야무지더라구요
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class ParkingDomainService { |
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.
호이 리뷰에 커멘트 달았슴다~
double deltaLatitude = Math.abs(parkingLatitude - destination.getLatitude()) * toRadian; | ||
double deltaLongitude = Math.abs(parkingLongitude - destination.getLongitude()) * toRadian; | ||
|
||
double sinDeltaLat = Math.sin(deltaLatitude / 2); | ||
double sinDeltaLng = Math.sin(deltaLongitude / 2); | ||
double squareRoot = Math.sqrt( | ||
sinDeltaLat * sinDeltaLat + | ||
Math.cos(parkingLatitude * toRadian) * Math.cos(destination.getLatitude() * toRadian) | ||
* sinDeltaLng | ||
* sinDeltaLng); | ||
|
||
return 2 * radius * Math.asin(squareRoot); | ||
} |
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.
그러게여 ParkingFeeCalculator
처럼 목적지까지 거리나 시간 측정하는거 만들어서 빼도 될거 같아여
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.
출발 위치 정보를 받고 주차장까지의 도보 예상 시간을 구하는 책임이라 Parking 에 있는게 자연스럽다고 생각했는데 별도의 Calculator 가 낫다고 생각하시나여??
# Conflicts: # src/main/java/com/example/parking/config/WebMvcConfig.java
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.
긴 과정 고생하셨습니다 영호씨 👍
👍관련 이슈
🤔세부 내용
GET /parkings?정렬조건
API 구현했습니다.
ST_BUFFER(POINT, radius)
: POINT 중점으로 부터 반지름이 radius 인 원을 생성해줍니다.ST_CONTAINS(원, POINT)
: POINT 가 원 안에 있는지 판단합니다. 여기서 원은 ST_BUFFER 로 생성된 원을 사용하도록 했습니다.ST_DISTANCE_SPHERE(POINT, POINT)
: POINT 간의 거리 차이를 계산합니다. 이 함수는 가까운 순으로 정렬조건을 줬을 때 사용합니다.🫵리뷰 중점사항
필터링 하는 부분을 별도의 ParkingDomainService 로 분리했습니다. (네이밍은 생각이 안나서 일단 ParkingDomainService 로 했어요..)
필터링 조건 중 cardEnabled는 전에 얘기한대로 애매한 부분이 있어서 제외했습니다.
필터링 조건 중 유.무료 부분은 요금계산 로직이 완료되면 그걸 토대로 필터링 조건 추가하면 될 것 같습니다.
응답 값에서 예상 요금, 도보 시간, 즐겨찾기는 아직 구현되지 않은 부분이라 null 을 반환하도록 했습니다.
더미 데이터 지도 사진
거리순 정렬 X
거리순 정렬 O