본문 바로가기
Java/series

[Java 5편] 객체, 엔티티, 테이블 설계

by 무대포 개발자 2022. 8. 4.
728x90
반응형

목차는 Java series 에 있습니다.

유튜브 보고 내용을 정리했습니다. 간단히 작성 후, 추후 공부하면서 내용을 보강할 예정입니다.

내용 정리가 뒤죽박죽으로 돼있습니다...

[Java 5편] 객체, 엔티티, 테이블 설계

설계란?

  • 코드를 어떻게 배치할 것인지에 대한 의사결정입니다.
  • 어떻게 배치할 것인지에 대한 질문은 의존성에 달려있습니다. 변화하는 것은 변화하는 것끼리 코드를 배치시키고, 변화하지 않는 것은 변화하지 않는 것에 코드를 배치시킵니다.
  • 즉, 의존성은 변화에 의해서 영향받을 수 있는 가능성입니다.

설계 순서

  1. 비즈니스 분석 및 행위, 상태, 필요 기능, 제약사항 등을 플로우로 그립니다.
  2. 구조도 및 클래스 다이어그램을 그립니다.
  3. 다이어그램 내에 방향 또는 관계 표현은 필수 입니다. (1:n, 1:1 등)
  4. 객체 설계 --> 엔티티 설계 --> 테이블 설계를 진행합니다.

객체 설계 예시

요구사항

  • TEAM 과 MEMBER 가 있고, TEAM 에는 여러 TEAM_MEMBER 가 있다고 가정합니다.

  • TEAM 안에 어떤 멤버가 속했는지 알 수 있어야 합니다.

클래스 설계

TEAM MEMBER 다이어그램.drawio

엔티티 설계 (=테이블 설계)

  • cascade 를 안준 이유는 요구사항에 TEAM, TEAM_MEMBER 가 동시에 변경해야하는 요건이 없기에 cascade 를 안줬습니다.

  • cascade ALL 을 줄 경우 트랜잭션에 묶인다는 의미이며, 결합성이 강해지기 때문입니다.

  • 아래 List 는 자주 쓰이고, 같은 도메인 영역이라 판단되어 객체 연관관계로 설정했습니다.

    • 만약 객체 참조가 여러번 일어나지 않고 1~2번 일어날 경우 객체 의존관계로 설정해도 됩니다.
    • 객체 의존관계는 객체내에 인스턴스로 설정하는게 아니라 메소드의 파라미터, return 값 등으로 사용하는 것입니다.
  • 될 수 있으면 객체, 엔티티간 관계를 안맺는 것이 좋다고 생각되며, 필요할 경우 객체 ID 를 통해 접근하는 것이 좋다고 생각합니다.

설계 주의 사항

객체지향적 설계

  • 객체지향적 설계라는 의미는 객체 간의 통신을 통해 비즈니스 로직을 구현하는 것입니다.
  • 비즈니스 분석을 통해 A function, B function 이라는 기능을 구현해야하는데 A 는 A 객체, B 는 B 객체에 접근해서 (public) 원하는 것을 얻어야 합니다.

객체를 어떻게 묶어야 하는가?

  • 생성, 삭제 라이프 사이클이 같다면 묶는 것이 좋습니다.
    • 아래 reference 에 나온것처럼 Order --> OrderItem 은 자주 사용하고, 생성, 삭제 라이프사이클이 같으니 묶는게 좋습니다. (연관관계)
  • 객체 간 제약사항이 있다면 묶는게 좋습니다.
    • 예를 들면, A 객체는 B 객체랑 묶여야하는 조건이 있을수 있습니다.

객체 간 사이클이 발생할 경우

  • package 를 합치는 방법이 있습니다. 객체 간 사이클 즉, 연관관계라는건 변할 때, 같이 변할 수 있다는 것이고, 이 객체들은 같은 패키지로 묶는 것이 맞습니다.
  • 중간에 별도 객체 TEMP 라는 것을 만들었다고 가정합니다. 사이클이 발생하는 객체는 TEMP 라는 것을 바라보도록 하면 사이클이 깨집니다. (단, TEMP 가 변경되면 TEMP 바라보는 객체들은 변경 가능성이 있습니다.)
  • 약한 결합을 사용하는 방법이 있습니다.
    • 아래 reference 처럼 Order 와 Shop 간에는 강한 결합이 필요 없으므로 Order 에서는 Shop ID 만을 가지고 조회하는 것이 좋습니다.

패키지 의존성을 끊는 방법

  • 이벤트를 발생시킵니다.
  • 아래 reference 처럼 Order , Delivery, Shop 의 경우 Order 가 처리함과 동시에 내부 이벤트를 발생시켜 Shop, Delivery 시스템에 이벤트를 전달하여 처리합니다. 시스템간 결합도가 낮아집니다.

다중성이 적은 방향을 선택

  • 아래와 같이 A --> B 를 연관관계를 맺고 있는데, JPA 로 구현할 경우 OneToMany 관계를 설정해줘야 합니다.
  • OneToMany 를 사용할 경우 n+1 성능 문제가 발생할 수 있으며, 그걸 방지하기 위해 노력을 기울여햐 하기에 될 수 있으면 다중성이 적은 방향을 선택하는 것이 좋습니다. (after 선택)
// before 
public class A {
  private List<String> B;
}

public class B {

}

// after
public class B {

  private A a;
}

약한 결합 문제점

  • 약한 결합을 사용할 경우 다른 객체의 메소드를 사용하지 못합니다. ID 를 통해 접근해야 하니 아래 reference 처럼 공통적으로 쓰이는 validate 같은 것을 Validator 라는 별도 클래스를 만들어 묶는 것이 응집도가 좋고, 보기에 편합니다. (절차지향적)

의존성을 한방향으로

  • 의존성이 layer 와 관계 없이 복잡하게 엮여있다면 추후 소스를 수정할 때, 사이드 이펙트를 추정하기 어렵습니다.
  • 해결하는 방법은 상위 layer 가 하위 layer 를 참조하도록 설계하는 것입니다. 이렇게 한다면 의존성이 한방향으로 흐르기에 추후 소스 수정 시 사이드 이펙트 측정이 가능합니다.

Reference

댓글