728x90
💡
Java에서 주소 정보와 같은 그룹화할 수 있는 필드를 추가할 때 보통 @Embedded 애너테이션 또는 private static 클래스를 사용한다. 두 접근 방식에는 각각 장단점이 있기 때문에 상황에 맞게 선택하는 것이 좋다.
이 글에서는 각 방식의 사용 시나리오와 그에 따른 장단점을 비교해보겠다.
@Embedded 애너테이션 사용 시나리오
- @Embedded 애너테이션은 주로 관계형 데이터베이스와 JPA 기반의 구현체에서 사용된다.
- 주소, 이름 등 공통으로 사용되는 속성을 별개의 클래스로 분리하여 코드의 재사용성과 모듈화를 증가시킬 수 있다.
예시 코드
// Member
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Document(collection = "member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
private String phoneNumber;
private String hobby;
@Embedded
private Address address;
// 생성자 메서드
public Member(String name, int age, String phoneNumber, String hobby, Address address) {
this.name = name;
this.age = age;
this.phoneNumber = phoneNumber;
this.hobby = hobby;
this.address = address;
}
}
// Address
@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Address {
private String city;
private String street;
private String zipcode;
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
장점
코드 모듈화 & 재사용성 증가
- 공통 속성을 별도의 클래스로 분리하여 관리할 수 있어 코드가 깔끔하게 정리되며 재사용하기 편리하다.
복합 값 타입을 사용하기 편리
- @Embedded 애너테이션을 이용하면 클래스 간 관계를 사용 기반으로 쉽게 정의할 수 있다.
단점
결합도 증가
- 당연한 얘기지만 관련된 클래스 간 결합도가 상대적으로 높아진다.
의존성 증가
- @Embedded 애너테이션은 JPA 기반의 구현체에 의존적이다.
- @Embedded 애너테이션은 JPA를 사용하는 프로젝트 또는 구현체에서만 사용할 수 있다.
@Embedded 애너테이션을 사용하는 경우
- JPA를 사용하는 프로젝트에서 공통 속성(그룹화 가능한 필드)을 모듈화 하고 싶을 때
- 복합 값 타입을 다른 클래스와 함께 사용하고자 할 때
private static 클래스 사용 시나리오
- private static 클래스는 주로 클래스 내부에서만 사용되는 경우에 유용하다.
- 이 경우에는 외부 클래스와의 의존성이 줄어들고 캡슐화를 강화할 수 있다.
예시 코드
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Document(collection = "member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
private String phoneNumber;
private String hobby;
private Address address;
// 생성자 메서드
public Member(String name, int age, String phoneNumber, String hobby, Address address) {
this.name = name;
this.age = age;
this.phoneNumber = phoneNumber;
this.hobby = hobby;
this.address = address;
}
// static inner class
private static class Address {
private final String city;
private final String state;
private final String country;
// 생성자는 private으로 설정하여 외부에서 접근 못하게 막음
private Address(String city, String state, String country) {
this.city = city;
this.state = state;
this.country = country;
}
// 정적 팩토리 메서드 사용
public static Address AddAddress(String city, String state, String country) {
return new Address(city, state, country);
}
}
}
장점
높은 캡슐화
- 클래스 내부에서만 사용되는 경우에는 외부 클래스에 의존하지 않고 내부 클래스를 관리할 수 있다.
간결한 코드
- 해당 클래스 내에서만 구현이 필요한 경우, 전체 코드가 간결하여 관리하기 쉽고, 가독성 역시 올라간다.
단점
확장성 제한
- private static 클래스는 해당 클래스 내에서만 사용 가능하므로 확장성이 떨어진다.
재사용성 감소
- 다른 곳에서 해당 클래스를 사용할 수 없다.
- 자칫하다가는 코드의 중복이 발생할 수 있다.
private static 클래스를 사용하는 경우
- 클래스 내부에서만 사용되고 외부에서 접근이 필요하지 않은 일부 속성이 있을 때
- 외부 클래스와의 의존성을 줄이고 캡슐화를 강화하려고 할 때
결론
- 두 가지 접근 방식은 상황과 요구 사항에 따라 다른 장점을 가진다.
- JPA 기반 프로젝트를 개발하는 등 일반적인 프로젝트의 경우 @Embedded 애너테이션을 사용해 공통 속성을 모듈화 하는 것이 유용하다.
- 코드의 모듈화를 통해 재사용성이 높아지기 때문이다.
- 만약 클래스 내부에서만 사용되는 속성을 캡슐화하는 데에 집중하거나 비교적 간단한 구현이나 테스트 코드 작성 등의 작업에서는 private static 클래스가 더 적합하다.
참고
뤼튼
728x90
'[JAVA] > JPA' 카테고리의 다른 글
JPA Specification을 이용하여 다중 조건 검색 로직을 구현해보자. (2) | 2024.01.31 |
---|---|
Entity 클래스에서 @Builder 제대로 알고 사용하자 (5) | 2023.05.23 |
JPARepository의 findAll() 호출 시 하나의 Row가 중복해서 여러 개 들어가는 경우와 특정 컬럼만 null이 들어가 있는 경우 (엔티티명과 컬럼명의 올바른 매핑 방법) (0) | 2023.05.19 |
JPQL - 벌크 연산 (1) | 2023.05.14 |
JPQL - @NamedQuery 애너테이션 (0) | 2023.05.13 |