-
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
Changes from 12 commits
f44658b
43ca5c9
85f7423
7674fc9
c1fa2c3
ba3c449
97ce588
c4fad88
0372e0d
d399ab5
3469889
7f49f6d
6288499
35a5747
2d059a8
592b1c7
f8b4dbd
d33ee40
44ae717
28ce548
6b7459f
d5ca66d
4c780fc
5f608cc
d008f2e
0035310
227cf26
a4dc6a1
84b1100
2973615
9d03477
1f31077
6c04212
b35c425
f1fa25b
3b9d046
9d5693e
dfac844
4528710
5362f5d
03dcdd3
fc15e7e
7b48ca1
4fe6e61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.example.parking.api.parking; | ||
|
||
import com.example.parking.application.parking.ParkingService; | ||
import com.example.parking.application.parking.dto.ParkingLotsResponse; | ||
import com.example.parking.application.parking.dto.ParkingQueryRequest; | ||
import com.example.parking.config.argumentresolver.parking.ParkingQuery; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
public class ParkingController { | ||
|
||
private final ParkingService parkingService; | ||
|
||
@GetMapping("/parkings") | ||
public ResponseEntity<ParkingLotsResponse> find(@ParkingQuery ParkingQueryRequest parkingQueryRequest) { | ||
ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest); | ||
return ResponseEntity.ok(parkingLots); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.example.parking.application.parking; | ||
|
||
import com.example.parking.domain.parking.Parking; | ||
import com.example.parking.domain.parking.dto.ParkingQueryCondition; | ||
import java.util.List; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class ParkingDomainService { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 새로 서비스를 나눠서 구현한건 좋은 거 같습니다. |
||
public List<Parking> filterByCondition(List<Parking> parkingLots, ParkingQueryCondition parkingQueryCondition) { | ||
return parkingLots.stream() | ||
.filter(parking -> parking.isMatchOperationType(parkingQueryCondition.getOperationType())) | ||
.filter(parking -> parking.isMatchParkingType(parkingQueryCondition.getParkingType())) | ||
.toList(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.example.parking.application.parking; | ||
|
||
import com.example.parking.application.parking.dto.ParkingLotsResponse; | ||
import com.example.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse; | ||
import com.example.parking.application.parking.dto.ParkingQueryRequest; | ||
import com.example.parking.domain.parking.Location; | ||
import com.example.parking.domain.parking.Parking; | ||
import com.example.parking.domain.parking.dto.ParkingQueryCondition; | ||
import com.example.parking.domain.parking.repository.ParkingRepository; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class ParkingService { | ||
|
||
public static final String DISTANCE_ORDER_CONDITION = "가까운 순"; | ||
private final ParkingRepository parkingRepository; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 라인 분리 어떨까요? |
||
private final ParkingDomainService parkingDomainService; | ||
|
||
public ParkingLotsResponse findParkingLots(ParkingQueryRequest parkingQueryRequest) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 트랜잭셔널이 없어도될까요 ? |
||
Location middlLocation = Location.of(parkingQueryRequest.getLatitude(), parkingQueryRequest.getLongitude()); | ||
|
||
List<Parking> parkingLots = findParkingLotsByOrderCondition(parkingQueryRequest, middlLocation); | ||
List<ParkingResponse> parkingLotsResponse = filteringByCondition(parkingQueryRequest, parkingLots); | ||
|
||
return new ParkingLotsResponse(parkingLotsResponse); | ||
} | ||
|
||
private List<ParkingResponse> filteringByCondition(ParkingQueryRequest parkingQueryRequest, | ||
List<Parking> parkingLots) { | ||
ParkingQueryCondition queryCondition = parkingQueryRequest.toQueryCondition(); | ||
|
||
List<Parking> filteredParkingLots = parkingDomainService.filterByCondition(parkingLots, queryCondition); | ||
return filteredParkingLots.stream() | ||
.map(this::toParkingResponse) | ||
.toList(); | ||
} | ||
|
||
private List<Parking> findParkingLotsByOrderCondition(ParkingQueryRequest parkingQueryRequest, | ||
Location middleLocation) { | ||
if (parkingQueryRequest.getPriority().equals(DISTANCE_ORDER_CONDITION)) { | ||
return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.getPoint(), | ||
parkingQueryRequest.getRadius()); | ||
} | ||
return parkingRepository.findAroundParkingLots(middleLocation.getPoint(), parkingQueryRequest.getRadius()); | ||
} | ||
|
||
private ParkingResponse toParkingResponse(Parking parking) { | ||
return new ParkingResponse( | ||
parking.getId(), | ||
parking.getBaseInformation().getName(), | ||
null, | ||
null, | ||
parking.getBaseInformation().getParkingType().getDescription(), | ||
false, | ||
parking.getLocation().getLatitude(), | ||
parking.getLocation().getLongitude() | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.example.parking.application.parking.dto; | ||
|
||
import java.util.List; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @NoArgsConstructor(access = AccessLevel.PRIVATE) |
||
public class ParkingLotsResponse { | ||
|
||
private List<ParkingResponse> parkingLots; | ||
|
||
private ParkingLotsResponse() { | ||
} | ||
|
||
public ParkingLotsResponse(List<ParkingResponse> parkingLots) { | ||
this.parkingLots = parkingLots; | ||
} | ||
|
||
@Getter | ||
public static class ParkingResponse { | ||
private Long parkingId; | ||
private String parkingName; | ||
private Integer estimatedFee; | ||
private Integer estimatedWalkingTime; | ||
private String parkingType; | ||
private Boolean isFavorite; | ||
private Double latitude; | ||
private Double longitude; | ||
|
||
private ParkingResponse() { | ||
} | ||
|
||
public ParkingResponse(Long parkingId, String parkingName, Integer estimatedFee, Integer estimatedWalkingTime, | ||
String parkingType, Boolean isFavorite, Double latitude, Double longitude) { | ||
this.parkingId = parkingId; | ||
this.parkingName = parkingName; | ||
this.estimatedFee = estimatedFee; | ||
this.estimatedWalkingTime = estimatedWalkingTime; | ||
this.parkingType = parkingType; | ||
this.isFavorite = isFavorite; | ||
this.latitude = latitude; | ||
this.longitude = longitude; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.example.parking.application.parking.dto; | ||
|
||
import com.example.parking.domain.parking.OperationType; | ||
import com.example.parking.domain.parking.ParkingType; | ||
import com.example.parking.domain.parking.dto.ParkingQueryCondition; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class ParkingQueryRequest { | ||
|
||
private final String operationType; | ||
private final String parkingType; | ||
private final String feeType; | ||
private final Boolean cardEnabled; | ||
private final String priority; | ||
private final Integer hours; | ||
private final Double latitude; | ||
private final Double longitude; | ||
private final Integer radius; | ||
|
||
public ParkingQueryRequest(String operationType, String parkingType, String feeType, Boolean cardEnabled, | ||
String priority, | ||
Integer hours, Double latitude, Double longitude, Integer radius) { | ||
this.operationType = operationType; | ||
this.parkingType = parkingType; | ||
this.feeType = feeType; | ||
this.cardEnabled = cardEnabled; | ||
this.priority = priority; | ||
this.hours = hours; | ||
this.latitude = latitude; | ||
this.longitude = longitude; | ||
this.radius = radius; | ||
} | ||
|
||
public ParkingQueryCondition toQueryCondition() { | ||
return new ParkingQueryCondition( | ||
OperationType.find(this.operationType), | ||
ParkingType.find(this.parkingType), | ||
this.cardEnabled | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.example.parking.config.argumentresolver; | ||
|
||
import com.example.parking.config.argumentresolver.parking.ParkingQueryArgumentResolver; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
@RequiredArgsConstructor | ||
@Configuration | ||
public class WebMvcConfig implements WebMvcConfigurer { | ||
|
||
private final ParkingQueryArgumentResolver parkingQueryArgumentResolver; | ||
|
||
@Override | ||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(parkingQueryArgumentResolver); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.example.parking.config.argumentresolver.parking; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ParkingQuery { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.example.parking.config.argumentresolver.parking; | ||
|
||
import com.example.parking.application.parking.dto.ParkingQueryRequest; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
@Override | ||
public boolean supportsParameter(MethodParameter parameter) { | ||
return parameter.hasParameterAnnotation(ParkingQuery.class); | ||
} | ||
|
||
@Override | ||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, | ||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { | ||
return new ParkingQueryRequest( | ||
webRequest.getParameter("operationType"), | ||
webRequest.getParameter("parkingType"), | ||
webRequest.getParameter("feeType"), | ||
Boolean.parseBoolean(webRequest.getParameter("cardEnabled")), | ||
webRequest.getParameter("priority"), | ||
Integer.parseInt(webRequest.getParameter("hours")), | ||
Double.valueOf(webRequest.getParameter("latitude")), | ||
Double.valueOf(webRequest.getParameter("longitude")), | ||
Integer.parseInt(webRequest.getParameter("radius")) | ||
); | ||
} | ||
} |
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.
호이 리뷰에 커멘트 달았슴다~