태그달린 클래스
class Figure {
enum Shape { RECTANGLE, CIRCLE };
// 도형의 형태를 나타내는 태그 필드
final Shape shape;
double length;
double width;
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);
}
}
}
클래스의 유형을 나타내는 태그 필드를 가지고 있는 클래스를 태그달린 클래스라고 한다. 위의 예제를 보면 Figure라는 도형 클래스가 있다. 그리고 Figure 클래스는 shape에 RECTANGLE, CIRCLE 값을 가지면서 도형이 사각형인지 원인지를 나타내고 있다. 도형 클래스의 사각형, 원 유형을 태그로 나타내는 태그 클래스인 것이다.
태그 클래스에는 단점이 많다. 1) 먼저 열거 타입 선언, 태그 필드, switch문 등 쓸데 없는 코드가 많다. 2) 여러 유형의 코드가 한 클래스에 들어있어서 가독성이 나쁘다. 3) 여러 유형의 데이터를 가지고 있어야 하기 때문에 메모리가 낭비된다. 4) 생성자가 많아지고 불필요한 추가 동작이 추가된다. 5) 유형을 추가하려면 기존 코드 수정이 필요하다. 6) 인스턴스 타입으로는 유형을 알수 없고 태그 필드까지 확인해야 한다.
태그클래스는 장황하고, 오류가 발생하기 쉽고, 비효율적이다.
상속을 활용한 계층구조
// Figure.java
abstract class Figure {
public abstract double area();
}
// Rectangle.java
class Rectangle extends Figure {
private final double length;
private final double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public double area() { return length * width; }
}
// Circle.java
class Circle extends Figure {
private final double radius;
public Circle(double radius) { this.radius = radius; }
@Override
public double area() { return Math.PI * (radius * radius); }
}
태그를 사용하여 유형을 표현하는 대신 상속을 사용하여 유형을 나타내도록 하면 태그클래스의 단점들이 모두 해결된다. 모든 유형들의 공통 내용을 상위 추상클래스로 보내고, 유형별 상세 내용을 각자의 유형이 가지도록 구현하면 된다. 그 덕분에 1) 각 클래스에는 필요한 코드만 존재한다. 2) 가독성이 좋다. 3) 메모리낭비가 없다. 4) 생성자가 깔끔해진다. 5) 유연하게 새로운 유형 추가가 가능하다. 6) 인스턴스의 타입만으로 유형을 알 수 있다.
'STUDY > 이펙티브자바' 카테고리의 다른 글
5-1) 제네릭 클래스의 raw type은 사용하지 마라 (1) | 2022.09.23 |
---|---|
4-10) 멤버 클래스는 되도록 static으로 만들어라 (0) | 2022.09.19 |
4-8) 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.09.15 |
4-7) 인터페이스는 구현하는 쪽을 생각해 설계하라 (0) | 2022.09.13 |
4-6) 추상 클래스보다는 인터페이스를 우선하라 (0) | 2022.09.07 |