본문 바로가기
[JAVA]/JPA

복합 값 타입 - @Embedded와 private static inner class를 비교해보자.

by 황원용 2023. 8. 14.
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