[Java] Enum 클래스 필드와 Static Import

dondonee·2024년 4월 27일
0
post-thumbnail

Enum 클래스 필드와 Static Import

도메인 클래스의 필드로 사용되는 Enum 클래스는 도메인의 내부 클래스로 선언하는 것이 좋다. 이것에 대해 공부하게 된 과정에 대해 정리해 보았다.



문제 상황

@Data
public class Member {
    private Long profileId;
    private Long userNo;
    private String nickname;
    private String imageUrl;
    private Grade grade;    //*
    private Boolean transferred;
    private Region region;  //*
    private Authority authority;  //*
    private LocalDateTime joinedDate;
    private LocalDateTime updatedDate;
 )

회원(Member) 도메인 클래스는 세 개의 Enum 필드를 가지고 있다(grade, region, authority).


처음에는 위와 같이 Enum 클래스들을 별도의 클래스로 만들고 member 패키지에 모아놓았다.

그런데 Enum 필드 클래스들은 항상 Member를 통해서만 사용되는데 패키지에서 Member와 동일한 레벨처럼 밖으로 꺼내져 있어 부적절해보였다. 논리적으로도 grade, region, authorityMember의 구성요소에 불과하니 안으로 넣는게 맞는 것 같았다.


수정을 하니 패키지가 깔끔해졌다.


궁금증

member.setRegion(Member.Region.SEOUL);

그런데 테스트 코드를 작성하다 보니 위와 같이 Enum 상수를 사용할 때 네임스페이스가 길어진다는 문제가 있었다.


import static com.knou.board.domain.member.Member.*;


member.setRegion(Region.SEOUL);

import static을 사용하면 네임스페이스를 축약할 수 있지만, 테스트 코드의 Assertions 외에는 사용하는 것을 본 적이 없어서 Static import를 사용하는 것이 괜찮은 방법인지 궁금해졌다.



Static Import

import / import static 차이

import com.knou.board.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;

일반적인 import는 패키지로부터 클래스를 import 한다. 패키지 제약 없이 클래스를 사용할 수 있도록 한다.


import static com.knou.board.domain.member.Member.*;
import static org.assertj.core.api.Assertions.*;

Static import(import static)는 클래스에서 정적 멤버를 import 한다. 클래스 제약 없이, 즉 클래스 정적 멤버를 사용할 수 있도록 한다.


double r = Math.cos(Math.PI * theta);

double r = cos(PI * theta);  // Static Import 사용

즉 위와 같이 클래스 명시 없이 단독으로 접근 가능해진다.


member.setRegion(Member.Region.SEOUL);

member.setRegion(Region.SEOUL);  // Static Import 사용

Enum 클래스도 마찬가지로 자신이 속한 도메인 클래스를 명시하지 않고 사용할 수 있게 된다. (참고로 Enum 클래스는 static이며 Enum 상수는 static final이다.)


사용시 주의점

Static import를 하면 정적 멤버가 어느 클래스에서 왔는지 알기 어렵다. (코드를 작성하는 시점에서는 명확하게 느껴져도 나중에는 그렇지 않을 수 있다는 것을 고려해야 한다.)

또한 다른 클래스에서 온 동일한 이름의 정적 멤버가 중복되어 사용되는 경우 컴파일이 되지 않는다.


때문에 Static import는 제한적으로 사용해야 하며, 클래스의 정적 멤버 전체를 import 하는 것보다 필요한 정적 멤버만 개별적으로 import 하는 것이 좋다.


사용 예

단점에도 불구하고 Static import가 사용되는 경우가 있다. 가장 대표적인 예시는 테스트 코드의 Assertions일 것이다.


Assertions.assertThat().isEqualTo();

assertThat().isEqualTo();  // Static Import 사용

Assertions는 테스트 클래스 내에서 반복적으로 사용되기 때문에 Static import를 통해 반복을 줄이면 가독성이 좋아진다. 또한 코드의 맥락으로도 Assertions 클래스임을 쉽게 알 수 있고, assertThat() 등 정적 멤버의 이름으로도 출처 클래스를 유추하기 어렵지 않다.



정리

Static import를 적용할 지의 기준은 결국 가독성 문제이다.

일반적으로는 사용되지 않지만 테스트 코드의 Assertions 처럼 해당 클래스 내에서 자주 사용되고, 클래스 내에서 Static import 되는 클래스가 한 두 개 로 많지 않을 때, Static import를 사용함으로써 가독성을 높일 수 있다면 사용하는 것이 좋다.


Member member = new Member();
member.setNickname("nickname");
member.setGrade(Grade.GRADE_1);
member.setTransferred(false);
member.setRegion(Region.SEOUL);
member.setAuthority(Authority.USER);
member.setJoinedDate(LocalDateTime.now());

도메인 클래스의 Enum 필드로 사용되는 Grade, Region, Authority의 경우도 Member를 통해서만 사용되기 때문에 Static import를 통해 Member 클래스를 생략해도 출처는 명확하다.


member.setGrade(Member.Grade.GRADE_1);
member.setRegion(Member.Region.SEOUL);
member.setAuthority(Member.Authority.USER);

오히려 Static import를 사용하지 않으면 위에서 보듯 가독성이 매우 떨어진다.

또한 Member 클래스를 다른 패키지로 이동해도 그에 속한 Enum 클래스들도 함께 옮겨지기 때문에 관리하기에도 편하다.




🔗 References

0개의 댓글