티스토리 뷰

728x90
반응형

태그 달린 클래스보다는 클래스 계층구조를 활용하라


  • 태그 달린 클래스란, 두 가지 이상의 의미를 표현할 수 있으며 현재 표현하는 의미를 태그 값으로 알려주는 클래스입니다.

 

🧨 예제 코드

  • Figure 클래스는 원(Circle)과 사각형(Rectangle)을 나타내는 클래스이고, 하나의 클래스에서 두 타입에 대응이 가능합니다.
  • area 메서드는 타입별로 맞는 크기를 계산해 반환하기에 편해보일 수 있습니다.
public class Figure {

    enum Shape {
        RECTANGLE, CIRCLE
    }

    // 공통 필드
    final Shape shape;

    double length;
    double width;
    double radius;

    public Figure(double radius) {
        this.shape = Shape.CIRCLE;
        this.radius = radius;
    }

    public Figure(double length, double width) {
        this.shape = Shape.RECTANGLE;
        this.length = length;
        this.width = width;
    }

    double area() {
        switch (this.shape) {
            case RECTANGLE:
                return length * width;
            case CIRCLE:
                return Math.PI * (radius * radius);
            default:
                throw new AssertionError(shape);
        }
    }
}

 

🧨 단점

  • 하나의 클래스에서 Enum, 태그 필드, switch문 등 부가적인 코드들이 많습니다.
  • 부가적인 코드들이 많기 때문에 가독성이 떨어지게 됩니다.
  • 하나의 타입으로 정해지면 그외에 타입을 위한 모든 코드는 불필요해지며, 메모리 낭비가 됩니다.
  • 필드가 final인 경우 항상 초기화를 해줘야합니다.
  • 새로운 타입이 추가될 때마다 분기가 필요한 모든 메서드에서 새로운 타입에 대응하는 코드를 작성해야 합니다.(switch)

 

💡 해결책

  • 계층 구조의 루트 추상 클래스를 선언한 뒤, 태그에 따라 동작이 달라지는 추상 메서드를 선언합니다.
  • 태그값에 상관없이 동일한 동작을 하는 메서드를 루트 클래스에 일반 메서드로 추가합니다.(area 메서드)
  • 루트 클래스를 확장한 구체 클래스를 의미별로 만듭니다.
  • 루트 클래스의 추상 메서드를 구체 클래스에서 의미별로 구현합니다.
public abstract class AbstractFigure {

    abstract double area();
}

public class Circle extends AbstractFigure {

    final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    double area() {
        return Math.PI * (radius * radius);
    }
}

public class Rectangle extends AbstractFigure {

    final double length;
    final double width;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    @Override
    double area() {
        return length * width;
    }
}

 

 

 

 

728x90
반응형