태그 클래스
하나의 클래스의 두 가지 이상의 기능이 있는 클래스를 말한다. 하지만 이와 같은 클래스는 오히려 가독성을 떨어트릴 뿐이다.
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();
}
}
}
보이는 봐와 같이 enum과 switch문이 들어가 있고 다양한 생성자와 필드가 만들어 진걸 볼 수 있다. 이런 코드는 가독성을 떨어뜨릴고 객체가 만들어 질 때 필요하지 않은 필드까지 초기화 시키니 메모리 요구도 늘어난다. 그리고 오류 발생 가능성도 더 높고 도형이 추가 될 때 마다 이 클래스는 점점 불어 날것이다.
수정
위와 같은 클래스를 다음과 같이 고칠 수 있다.
abstract class Figure {
abstract double area();
}
class Circle extends Figure {
final double radius;
Circle(double radius) {
this.radius = radius;
}
double area() {
return Math.PI *(radius * radius);
}
}
class Rectangle extends Figure {
final double length;
final double width;
Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
double area() {
return length * width;
}
}
위에 있는 태그 기반 클래스 보다 더 읽기 쉽고 불 필요한 코드가 전부 사라졌음을 볼 수 있다. 또한 태그 기반 클래스의 단점을 모두 해결하였다.