Skip to content

Commit

Permalink
[Refactor] - 여행 계획 Service 코드 리팩터링 (#507)
Browse files Browse the repository at this point in the history
* feat: 여행 계획 도메인에 날짜 추가하는 기능 구현 (양방향 연관관계 편의 메서드)

* feat: 여행 계획 날짜 도메인에 장소 추가하는 기능 구현 (양방향 연관관계 편의 메서드)

* refactor: DTO -> 여행 계획 도메인 매핑 dto 내부로 응집

* refactor: DTO -> 여행 계획 날짜 도메인 매핑 로직 dto 내부로 응집

* feat: 여행 계획 장소 도메인에 Todo 추가하는 기능 구현(양방향 연관관계 편의 메서드)

* refactor: DTO -> 여행 계획 TODO 도메인 매핑 로직 dto 내부로 응집

* refactor: 불필요한 접근 메서드 제거 개선

* refactor: DTO 내부로 응집된 매핑 로직으로 travelPlanService 영속화 과정 단순화 개선

* refactor: 도메인 -> 응답 DTO 생성 로직 DTO 안으로 응집 개선

* refactor: TravelPlanService TravelPlan을 업데이트할 때 DTO 내부의 매핑 로직을 이용하도록 개선

* refactor: 사용하지 않는 메서드 제거 개선 (여행 계획 날짜 등, 부수 요소 생성 로직 DTO 내부로 응집)

* refactor: 여행 계획 조회 응답 매핑 로직 DTO 내부로 응집, 사용되지 않는 매핑 서비스 메서드 제거 개선

* refactor: 불필요한 메서드 호출 제거 개선

* refactor: 사용하지 않는 기능 제거 개선 (여행 계획 기간 구하기)

* feat: TravelPlanFacadeService 구현 및 서비스 계층 분리 시작

* refactor: update 파사드 로직 TravelPlanFacadeService 로 이동

* refactor: delete 파사드 로직 TravelPlanFacadeService 로 이동

* refactor: 공유키 기반 여행 계획 조회 기능 TravelPlanFacadeService 로 이동

* refactor: 여행 계획 컨트롤러 사용하지 않는 서비스 의존 제거

* test: 여행 계획 생성 FacadeService 테스트 작성

* test: 여행 계획 상세 조회 FacadeService 테스트 작성

* test: 여행 계획 수정 FacadeService 테스트 작성

* test: 여행 계획 공유 키 기반 조회 FacadeService 테스트 작성

* test: 여행 계획 삭제 FacadeService 테스트 작성

* refactor: 미사용 파라미터 전달 메서드 개선

* test: 하위 서비스와 비즈니스 파사드 테스트 분리

* test: 서비스 계층에 맞는 Displayname으로 수정

* refactor: 사용하지 않는 메서드 제거 개선

* refactor: 여행 계획 수정 메서드 리턴 타입 void -> PlanResponse로 변경

* test: 여행 계획 수정, 삭제 테스트가 다른 계층의 컴포넌트를 의존하지 않도록 수정

* fix: 누락된 Transactional 작성

* refactor: 사용되지 않는 의존성 제거 개선

* test: TravelPlan 양방향 연관관계 편의 메서드 테스트 작성

* test: TravelPlanDay 양방향 연관관계 편의 메서드 테스트 작성

* test: TravelPlanPlace 양방향 연관관계 편의 메서드 테스트 작성
  • Loading branch information
Libienz authored Oct 9, 2024
1 parent ab39a4d commit 8f2d15e
Show file tree
Hide file tree
Showing 25 changed files with 518 additions and 329 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Page<PlanResponse> readTravelPlans(MemberAuth memberAuth, Pageable pageab
Member member = memberService.getById(memberAuth.memberId());
Page<TravelPlan> travelPlans = travelPlanService.getAllByAuthor(member, pageable);

return travelPlans.map((travelPlanService::getTravelPlanResponse));
return travelPlans.map(PlanResponse::from);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import kr.touroot.travelplan.dto.request.PlanRequest;
import kr.touroot.travelplan.dto.response.PlanCreateResponse;
import kr.touroot.travelplan.dto.response.PlanResponse;
import kr.touroot.travelplan.service.TravelPlanService;
import kr.touroot.travelplan.service.TravelPlanFacadeService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -33,7 +33,7 @@
@RequestMapping("/api/v1/travel-plans")
public class TravelPlanController {

private final TravelPlanService travelPlanService;
private final TravelPlanFacadeService travelPlanFacadeService;

@Operation(summary = "여행 계획 생성")
@ApiResponses(value = {
Expand All @@ -57,7 +57,7 @@ public ResponseEntity<Void> createTravelPlan(
@Valid @RequestBody PlanRequest request,
MemberAuth memberAuth
) {
PlanCreateResponse data = travelPlanService.createTravelPlan(request, memberAuth);
PlanCreateResponse data = travelPlanFacadeService.createTravelPlan(request, memberAuth);
return ResponseEntity.created(URI.create("/api/v1/travel-plans/" + data.id())).build();
}

Expand All @@ -83,7 +83,7 @@ public ResponseEntity<PlanResponse> readTravelPlan(
@Parameter(description = "여행 계획 id") @PathVariable Long id,
MemberAuth memberAuth
) {
PlanResponse data = travelPlanService.readTravelPlan(id, memberAuth);
PlanResponse data = travelPlanFacadeService.findTravelPlanById(id, memberAuth);
return ResponseEntity.ok(data);
}

Expand All @@ -110,7 +110,7 @@ public ResponseEntity<Void> updateTravelPlan(
@Valid MemberAuth memberAuth,
@Valid @RequestBody PlanRequest request
) {
travelPlanService.updateTravelPlan(id, memberAuth, request);
travelPlanFacadeService.updateTravelPlanById(id, memberAuth, request);
return ResponseEntity.ok().build();
}

Expand All @@ -133,7 +133,7 @@ public ResponseEntity<Void> updateTravelPlan(
})
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTravelPlan(@PathVariable Long id, MemberAuth memberAuth) {
travelPlanService.deleteByTravelPlanId(id, memberAuth);
travelPlanFacadeService.deleteTravelPlanById(id, memberAuth);
return ResponseEntity.noContent()
.build();
}
Expand All @@ -154,7 +154,7 @@ public ResponseEntity<Void> deleteTravelPlan(@PathVariable Long id, MemberAuth m
public ResponseEntity<PlanResponse> readSharedTravelPlan(
@Parameter(description = "여행 계획 공유 키") @PathVariable UUID shareKey
) {
PlanResponse data = travelPlanService.readTravelPlan(shareKey);
PlanResponse data = travelPlanFacadeService.findTravelPlanByShareKey(shareKey);
return ResponseEntity.ok(data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,8 @@ private void validateOrderNonNegative(Integer order) {
public void updateCheckedStatus(boolean checkedStatus) {
isChecked = checkedStatus;
}

public void updateTravelPlanPlace(TravelPlanPlace travelPlanPlace) {
this.travelPlanPlace = travelPlanPlace;
}
}
10 changes: 10 additions & 0 deletions backend/src/main/java/kr/touroot/travelplan/domain/TravelPlan.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ public void update(String title, LocalDate startDate) {
this.startDate = startDate;
}

public void updateDays(List<TravelPlanDay> travelPlanDays) {
this.travelPlanDays.clear();
travelPlanDays.forEach(this::addDay);
}

public void addDay(TravelPlanDay day) {
travelPlanDays.add(day);
day.updatePlan(this);
}

public boolean isStartDateBefore(LocalDate date) {
return startDate.isBefore(date);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class TravelPlanDay extends BaseEntity {
private Long id;

@Column(name = "PLAN_DAY_ORDER", nullable = false)
Integer order;
private Integer order;

@JoinColumn(name = "PLAN_ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
Expand Down Expand Up @@ -70,8 +70,17 @@ private void validateOrderRange(Integer order) {
}
}

public void addPlace(TravelPlanPlace place) {
travelPlanPlaces.add(place);
place.updateDay(this);
}

public LocalDate getCurrentDate() {
LocalDate startDate = plan.getStartDate();
return startDate.plusDays(order);
}

public void updatePlan(TravelPlan plan) {
this.plan = plan;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,13 @@ private void validatePlaceNameLength(String placeName) {
throw new BadRequestException("장소 이름은 " + PLACE_NAME_MAX_LENGTH + "자 이하여야 합니다");
}
}

public void addTodo(TravelPlaceTodo todo) {
travelPlaceTodos.add(todo);
todo.updateTravelPlanPlace(this);
}

public void updateDay(TravelPlanDay day) {
this.day = day;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.List;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.domain.TravelPlanDay;
import kr.touroot.travelplan.domain.TravelPlanPlace;

public record PlanDayRequest(
@Schema(description = "여행 장소 정보")
Expand All @@ -17,6 +18,16 @@ public record PlanDayRequest(
) {

public TravelPlanDay toPlanDay(int order, TravelPlan plan) {
return new TravelPlanDay(order, plan);
TravelPlanDay travelPlanDay = new TravelPlanDay(order, plan);
addPlaces(travelPlanDay);
return travelPlanDay;
}

private void addPlaces(TravelPlanDay travelPlanDay) {
for (int order = 0; order < places.size(); order++) {
PlanPlaceRequest planPlaceRequest = places.get(order);
TravelPlanPlace planPlace = planPlaceRequest.toPlanPlace(order, travelPlanDay);
travelPlanDay.addPlace(planPlace);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import kr.touroot.travelplan.domain.TravelPlaceTodo;
import kr.touroot.travelplan.domain.TravelPlanDay;
import kr.touroot.travelplan.domain.TravelPlanPlace;
import lombok.Builder;
Expand All @@ -22,6 +23,22 @@ public record PlanPlaceRequest(
) {

public TravelPlanPlace toPlanPlace(int order, TravelPlanDay day) {
return new TravelPlanPlace(order, day, placeName, position().lat(), position().lng());
TravelPlanPlace travelPlanPlace = new TravelPlanPlace(
order,
day,
placeName,
position().lat(),
position().lng()
);
addTodos(travelPlanPlace);
return travelPlanPlace;
}

private void addTodos(TravelPlanPlace travelPlanPlace) {
for (int order = 0; order < todos.size(); order++) {
PlanPlaceTodoRequest todoRequest = todos.get(order);
TravelPlaceTodo placeTodo = todoRequest.toPlaceTodo(travelPlanPlace, order);
travelPlanPlace.addTodo(placeTodo);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import kr.touroot.member.domain.Member;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.domain.TravelPlanDay;
import lombok.Builder;

@Builder
Expand All @@ -28,6 +30,27 @@ public record PlanRequest(
) {

public TravelPlan toTravelPlan(Member author, UUID shareKey) {
return new TravelPlan(title, startDate, shareKey, author);
TravelPlan travelPlan = new TravelPlan(title, startDate, shareKey, author);
addDays(travelPlan);
return travelPlan;
}

private void addDays(TravelPlan travelPlan) {
for (int order = 0; order < days.size(); order++) {
PlanDayRequest planDayRequest = days.get(order);
TravelPlanDay planDay = planDayRequest.toPlanDay(order, travelPlan);
travelPlan.addDay(planDay);
}
}

public List<TravelPlanDay> getDays(TravelPlan travelPlan) {
List<TravelPlanDay> travelPlanDays = new ArrayList<>();
for (int order = 0; order < days.size(); order++) {
PlanDayRequest planDayRequest = days.get(order);
TravelPlanDay planDay = planDayRequest.toPlanDay(order, travelPlan);
travelPlanDays.add(planDay);
}

return travelPlanDays;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package kr.touroot.travelplan.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import kr.touroot.travelplan.domain.TravelPlan;

public record PlanCreateResponse(
@Schema(description = "생성된 여행 계획 id", example = "1")
Long id
) {

public static PlanCreateResponse from(TravelPlan travelPlan) {
return new PlanCreateResponse(travelPlan.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ public record PlanDayResponse(
@Schema(description = "여행 장소별 정보") List<PlanPlaceResponse> places
) {

public static PlanDayResponse of(
TravelPlanDay planDay,
List<PlanPlaceResponse> places
) {
public static PlanDayResponse from(TravelPlanDay planDay) {
return PlanDayResponse.builder()
.id(planDay.getId())
.date(planDay.getCurrentDate())
.places(places)
.places(getTravelPlanPlaceResponse(planDay))
.build();
}

public static List<PlanPlaceResponse> getTravelPlanPlaceResponse(TravelPlanDay day) {
return day.getTravelPlanPlaces().stream()
.map(PlanPlaceResponse::from)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ public record PlanPlaceResponse(
@Schema(description = "여행 장소 TODO") List<PlanPlaceTodoResponse> todos
) {

public static PlanPlaceResponse of(TravelPlanPlace planPlace, List<PlanPlaceTodoResponse> todos) {
public static PlanPlaceResponse from(TravelPlanPlace planPlace) {
return PlanPlaceResponse.builder()
.id(planPlace.getId())
.placeName(planPlace.getName())
.position(PlanPositionResponse.from(planPlace.getPosition()))
.todos(todos)
.todos(getTodoResponse(planPlace))
.build();
}

private static List<PlanPlaceTodoResponse> getTodoResponse(TravelPlanPlace planPlace) {
return planPlace.getTravelPlaceTodos().stream()
.map(PlanPlaceTodoResponse::from)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ public record PlanResponse(
@Schema(description = "여행 계획 공유 share Key") UUID shareKey
) {

public static PlanResponse of(TravelPlan travelPlan, List<PlanDayResponse> days) {
public static PlanResponse from(TravelPlan travelPlan) {
return PlanResponse.builder()
.id(travelPlan.getId())
.title(travelPlan.getTitle())
.startDate(travelPlan.getStartDate())
.days(days)
.days(getTravelPlanDaysResponse(travelPlan))
.shareKey(travelPlan.getShareKey())
.build();
}

private static List<PlanDayResponse> getTravelPlanDaysResponse(TravelPlan travelPlan) {
return travelPlan.getTravelPlanDays().stream()
.map(PlanDayResponse::from)
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package kr.touroot.travelplan.repository;

import java.util.List;
import kr.touroot.travelplan.domain.TravelPlaceTodo;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.domain.TravelPlanPlace;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PlaceTodoRepository extends JpaRepository<TravelPlaceTodo, Long> {

List<TravelPlaceTodo> findByTravelPlanPlace(TravelPlanPlace travelPlanPlace);

void deleteByTravelPlanPlaceDayPlan(TravelPlan travelPlan);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package kr.touroot.travelplan.repository;

import java.util.List;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.domain.TravelPlanDay;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TravelPlanDayRepository extends JpaRepository<TravelPlanDay, Long> {

List<TravelPlanDay> findByPlan(TravelPlan travelPlan);

void deleteByPlan(TravelPlan plan);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package kr.touroot.travelplan.repository;

import java.util.List;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.domain.TravelPlanDay;
import kr.touroot.travelplan.domain.TravelPlanPlace;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TravelPlanPlaceRepository extends JpaRepository<TravelPlanPlace, Long> {

List<TravelPlanPlace> findByDay(TravelPlanDay day);

void deleteByDayPlan(TravelPlan plan);
}
Loading

0 comments on commit 8f2d15e

Please sign in to comment.