태그 달린 클래스
- 아래처럼 태그 필드가 있는 코드를 태그 달린 클래스라고 한다.
- 두가지 이상의 의미를 표현할 수 있으며, 그 중 현재 표현하는 의미를 태그값으로 알려주는 클래스
public class Figure {
enum Shape {RECTANGLE, CIRCLE};
// 태그 필드 - 현재의 모양을 나타냄
final Shape shape;
// Rectangle 일 때만 사용된다.
double length;
double width;
// Circle 일때만 사용
double radius;
// 원 생성자
Figure(double radius){
shape = Shape.RECTANGLE;
this.radius = radius;
}
// 사각형 생성자
Figure(double length, double width){
shape = Shape.RECTANGLE;
this.length = length;
this.width = width;
}
double area(){
switch (shape){
case RECTANGLE:
return width*length;
case CIRCLE:
return (radius*radius)*Math.PI;
default:
throw new AssertionError(shape);
}
}
}
System.out.println(circle.shape);
System.out.println(rectangle.shape);
태그 달린 클래스의 단점
1. 열거 타입 선언, 태그 필드, switch 문 등 쓸모없는 코드들이 너무 많다.
2. 여러 구현이 한 클래스에 합쳐져 가독성이 좋지 않다.
3. 다른 의미를 위한 코드도 함께 있어 메모리도 많이 사용된다.
-> Rectagle을 만들어도 Circle의 필드나 관련 코드들이 함께 존재
4. 필드들을 final로 선언하고 싶어도 선언하면 다른 타입의 필드까지 초기화해야해서 불필요한 코드 증가
5. 또다른 의미를 추가하면 switch문에 추가해야하고 실수로 추가하지 않아도 컴파일러의 도움을 받지못한다.
-> 오류를 Runtime시 찾아야 한다.
6. 인스턴스의 타입만 보고 해당 인스턴스의 의미를 파악하기 어렵다
-> Figure 로 선언하기 때문에 의미 한번에 파악하기 어려움
해결 : 계층적 구조로 만들어 사용하자 (= 서브타이핑)
방법
// 태그 클래스를 계층구조로 만드는 방법
// 1. 계층구조의 루트가 될 추상 클래스 정의
// 2. 태그 값에 따라 달라질 메서드들을 루트 클래스의 추상메서드로 정의
// 3. 태그 값에 관계없이 동작이 일정한 메서드들을 루트 클래스의 일반 메서드로 추가
// 4. 하위 클래스에서 공통으로 사용하는 필드들을 전부 루트 클래스에 추가
// 5. 루트 클래스를 확장한 구체 클래스를 의미별로 하나씩 정의
// Figure 적용
// -> Figure의 Area 메서드를 추상메서드로 정의
// -> Circle, Rectangle 클래스 생성
newCircle circle1 = new newCircle(1);
newRectangle rectangle1 = new newRectangle(1, 2);
개선 점
// 1. 열거타입 선언, 태그 필드, switch 문 모두 제거 됨
// 2. 가독성이 좋아짐
// 3. 필요없는 필드들 제거
// 4. final로 선언 가능
// 5. 초기화시 컴파일 도움도 받는다. -> 추상 메서드를 모두 구현했는지 등에 대한 여부
// 6. switch 문 수정 필요가 없다.
// 7. 의미 파악이 쉬움
정리
태그 달린 클래스는 사용하지말고 계층구조를 사용하자 이미 사용중이라면 리팩토링 하자.
코드
https://github.com/mokjaemin/EffectiveJAVA
'Language > Java Plus' 카테고리의 다른 글
Effective JAVA - Item25 : 톱 클래스 파일은 한 파일에 하나만 담아라 (0) | 2023.10.12 |
---|---|
Effective JAVA - Item24 : 멤버 클래스는 되도록 static으로 만들어라 (0) | 2023.10.12 |
Effective JAVA - Item22 : 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2023.10.10 |
Effective JAVA - Item21 : 인터페이스는 구현하는 쪽을 생각해서 설계하라. (0) | 2023.10.09 |
Effective JAVA - Item20 : 추상 클래스보단 인터페이스를 우선시하라. (0) | 2023.10.09 |