JAVA/Effective Java

[아이템 23] 태그 달린 클래스보다는 클래스 계층 구조를 활용하라

꾸준함. 2024. 2. 7. 23:07

태그 달린 클래스

두 가지 이상 의미를 표현할 수 있으며, 그중 현재 표현하는 의미를 태그 값으로 알려주는 클래스를 태그 달린 클래스라고 정의합니다.
아래 Figure 클래스가 대표적인 태그 클래스입니다.
 

 
 
 
 
태그 달린 클래스에는 다음과 같은 단점들이 있습니다.

  • 쓸데없는 코드가 많아 가독성이 떨어짐
  • 다른 의미의 코드가 항상 함께 하기 때문에 최적화된 코드보다 메모리 많이 사용
  • 필드를 final로 선언하기 위해서는 불필요한 필드까지 초기화 필요
  • 클래스가 여러 의미를 가지므로 인스턴스 타입만으로 현재 인스턴스가 나타내는 의미를 알 수가 없음
    • 태그 필드인 shape을 통해서만 알 수 있음
    • SOLID 원칙의 단일 책임 원칙 위반

 
요약하면 태그 달린 클래스는 장황하고, 오류를 내기 쉽고, 비효율적입니다.
태그 달린 클래스는 클래스 계층구조를 부족하게 모방한 것일 뿐이므로 해당 방식은 피하고, 대신 상속을 통한 명확한 계층 구조를 채택하는 것이 권장됩니다.

 

클래스 계층 구조

태그가 달린 클래스를 계층 구조로 전환하는 프로세스는 다음과 같습니다.

  • 계층 구조의 루트가 될 추상 클래스 정의 (Figure)
  • 태그 값에 따라 동작이 달라지는 메서드들을 루트 클래스의 추상 메서드로 선언 (getArea 메서드)
  • 태그 값에 상관없이 동작이 일정한 메서드들을 루트 클래스에 일반 메서드로 추가
  • 하위 클래스에서 공통으로 사용하는 데이터 필드도 전부 루트 클래스로 올리기

 
이전에 제시한 Figure 클래스를 계층 구조를 갖도록 변형하면 다음과 같습니다.
 

 
계층 구조로의 전환으로 인해 태그가 달린 클래스의 단점을 모두 해결했습니다.

  • 쓸데없는 코드가 모두 사라짐
    • 각 의미를 독립된 클래스에 담아 관련 없던 데이터 필드 모두 제거

 

  • 살아 남은 필드들은 모두 final로 선언하여 불변성 유지
    • 각 클래스의 생성자가 모든 필드를 초기화하고 추상 메서드를 모두 구현했는지 컴파일러 통해 확인 가능

 

  • 루트 클래스의 코드를 건드리지 않고도 개발자들이 독립적으로 계층 구조를 확장하고 함께 사용 가능
  • 타입이 의미별로 별도로 존재하므로 변수의 의미를 명시하거나 제한할 수 있으며 특정 의미만 매개변수로 받을 수 있음

 

정리

태그 달린 클래스 사용은 최소화해야 합니다.
클래스 내에 if문과 switch문이 늘어날 경우, 태그 달린 클래스와 유사하게 바뀌고 있는지 의심해야 하며 필요에 따라 계층 구조로 분리하는 것이 좋습니다.

 

참고

이펙티브 자바
이펙티브 자바 완벽 공략 2부 - 백기선 강사님

반응형