태그 달린 클래스를 써야 하는 상황은 거의 없다. 새로운 클래스를 작성하는 데 태그 필드가 등장한다면 태그를 없애고 계층구조로 대체하는 방법을 생각해보자. 기존 클래스가 태그 필드를 사용하고 있다면 계층구조로 리팩터링 하는 걸 고민해보자.
태그 달린 클래스 - 클래스 계층구조보다 훨씬 나쁘다
package effectivejava.chapter4.item23.taggedclass; // 코드 23-1 태그 달린 클래스 - 클래스 계층구조보다 훨씬 나쁘다! (142-143쪽) class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 사각형용 생성자 Figure(double length, double width) { shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area() { switch(shape) { case RECTANGLE: return length * width; case CIRCLE: return Math.PI * (radius * radius); default: throw new AssertionError(shape); } } }
클래스 계층구조
package effectivejava.chapter4.item23.hierarchy; // 코드 23-2 태그 달린 클래스를 클래스 계층구조로 변환 (144쪽) abstract class Figure { abstract double area(); }
package effectivejava.chapter4.item23.hierarchy; // 코드 23-2 태그 달린 클래스를 클래스 계층구조로 변환 (144쪽) class Circle extends Figure { final double radius; Circle(double radius) { this.radius = radius; } @Override double area() { return Math.PI * (radius * radius); } }
package effectivejava.chapter4.item23.hierarchy; // 코드 23-2 태그 달린 클래스를 클래스 계층구조로 변환 (144쪽) class Rectangle extends Figure { final double length; final double width; Rectangle(double length, double width) { this.length = length; this.width = width; } @Override double area() { return length * width; } }