패스트캠퍼스/과제

토이 프로젝트2 : 여행 여정을 기록과 관리하는 SNS 서비스 2단계 회고

개발중인 감자 2023. 11. 2. 15:26

🌟 지난 프로젝트의 피드백

✔️ MVC 패턴이 잘 지켜지지 않았다. -> DDD 구조를 바탕으로 역할을 명확하게 나누어 진행.
✔️ 변수와 메소드 이름이 불분명 및 통일이 안됐다. -> 리팩토링 과정에서 꼼꼼하게 검토

 

🌟 이번 프로젝트의 목표 

  • JPA의 이해
  •  코드 리뷰 적극적
  •  DDD 설계의 이해 

 

🌟 규칙 

1) 깃 플로우 브랜치 전략 사용.

 

 

2) 코드 컨벤션 - 구글 코드 컨벤션 

 

 

 


📌 기능 소개 

 

 

위의 이미지대로 기획을 하였고, 밑에처럼 기능을 나누어 역할을 분담했다. 

내가 맡은 파트는 '여정 n개 삽입' 과 '여정 n개 삭제' 였다. 

 

 

📌 ERD 

 

create_at : 레코드 생성 날짜 
updated_at : 레코드 마지막 수정 날짜 
deleted_at : 레코드 삭제 처리 시 실제로 삭제가 아닌 삭제 날짜 
모두 자동 완성이다. 
여행 (Trip) : 여정 (Itinerary) = 1 : n 관계
여정 : 이동/숙소/체류 = 1 : 1 매핑 이자 부모 - 자식 관계 

 

 

여기서 조금 많이 수정됐지만, 수정권한이 없어서 일단 초기 모델로 가져왔다.

여행과 여정을 1:n으로 하였고, 여정들의 종류에 따라 1:1 테이블을 만들었다. 

1:n 관계는 여러번 짜봤는데 1:1은 처음 해봐서 진짜 힘들었다 ㅠ

 

📌 Entity 

▶️ Trip (여행) : Itineraty List 를 갖는다. 

@Entity
@EntityListeners(AuditingEntityListener.class)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Trip extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Long tripId;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "memberId")
    @JsonIgnore
    private Member member;
    @Column(nullable = false)
    private String tripName;
    @Column(nullable = false)
    private LocalDate startDate;
    @Column(nullable = false)
    private LocalDate endDate;
    @ColumnDefault("true")
    private Boolean isDomestic;
    @ColumnDefault("false")
    private Boolean isDeleted;
    
    @OneToMany(mappedBy = "trip",
        cascade = {CascadeType.ALL},
        fetch = FetchType.EAGER,
        orphanRemoval = true)
    List<Itinerary> itineraryList = new ArrayList<>();
    //CascadeType.ALL -> 상위 객체 작업 하위객체 모두한테 전파.
    //fetch = FetchType.EAGER -> 실제 조회할 때 한방 쿼리로 다 조회.(itinerary을 사용할 때 쿼리 안나가도 된다.)
    //orphanRemoval = true -> 부모가 자식에 대한 참조를 끊을 때, 참조가 끊어진 자식 Entity(고아 객체)를 DB에서 삭제하도록 설정할 수 있다.
    //우리는 soft delete 이므로 굳이 필요는 없음.

 

▶️ Itinerary (여정)

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
@SuperBuilder
public class Itinerary extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long itineraryId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "tripId")
    private Trip trip;

    @Column(nullable = false)
    private String itineraryName;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private ItineraryType itineraryType;

    @Column(nullable = false)
    private Integer itineraryOrder;

    @ColumnDefault("false")
    private Boolean isDeleted;

 

▶️ Movement (이동)

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Movement extends Itinerary {

    @Column(nullable = false)
    private LocalDateTime departureDate;

    @Column(nullable = false)
    private LocalDateTime arrivalDate;

    @Column(nullable = false)
    private String departurePlace;

    @Column(nullable = false)
    private String arrivalPlace;

    @Column(nullable = false)
    private String transportation;

 

 

▶️ Lodgement (숙소)

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Lodgement extends Itinerary {

    @Column(nullable = false)
    private LocalDateTime checkIn;

    @Column(nullable = false)
    private LocalDateTime checkOut;

 

▶️ Stay (체류)

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Stay extends Itinerary {

    @Column(nullable = false)
    private LocalDateTime departureDate;

    @Column(nullable = false)
    private LocalDateTime arrivalDate;

 


📌 잘한 점

 

1. JPA 를 이해할 수 있었다.

특히 슈퍼 - 서브 타입이 이해하기 어려웠지만, 계속적으로 엔티티를 수정해 나가면서 이해할 수 있었다. 

 

2. 리팩토링에 신경 썼다. 

특히 🌟 팩토리 패턴 🌟을 이용해 if문을 없애면서 가독성 있는 코드를 짤 수 있었다. 

 

[spring-boot] [리팩토링] if 문 없이 객체 만들어보자 - 팩토리 패턴, 상속관계 엔티티 생성

이 게시글은 pjh3749님의 게시글을 참고하였습니다. 📌 문제 상황 프로젝트를 하던 중 .. 상속관계에 있는 엔티티들을 매번 빌더로 만들어야하는 상황이었다. 방법이 없어 보여 switch 문 사용해서

nebulaisme.tistory.com

 

3. 깃에 능숙해졌다

충돌 나도 두렵지 않아졌다. 

 

📌 아쉬운 점

 

1. 여정을 Day별로 출력하지 못해 아쉬웠다.

이건 프로젝트가 끝나고 나서 트리플 이라는 앱을 사용해보고 느꼈다. 

 

2. java docs를 사용하지 못해 아쉬웠다. 

자바 독스 사용한 팀이 대부분이었는데, 우리팀은 적용하지 못해 아쉬웠다. 

 

📌 개선 방안

 

1. 트리플 앱을 보며, 여정 부분을 Day별로 출력하고 싶다. 

- request, response 별로 나누어서 처음부터 다시 설계를 해야할 것 같다. 

 

2. JPA를 더 공부하여 조금 더 깔끔한 엔티티 구조를 갖고 싶다. 

슈퍼 - 서브 타입을 사용하면서 req 와 res의 필드 이름이 통일되지 못한 경우가 발생했다. 

이 부분을 고칠 것이다.