이펙티브 자바 #item23 태그 달린 클래스보다 계층 구조를 활용하라

임현규·2023년 1월 27일
0

이펙티브 자바

목록 보기
23/47
post-custom-banner

태그 달린 클래스 구조의 문제점

public class Figure {

    public enum Shape {RECTANGLE, CIRCLE}

    private final Shape shape;

    private double length;
    private double width;

    private 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;
    }

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

enum 을 이용해 클래스의 Shape을 표현하고 Shape에 따라 area의 분기문이 생긴다. 이 코드의 문제점은 너무 장황하고 메모리가 낭비된다. shape에 따라 전혀 사용하지 않는 변수가 생기고 area의 코드는 shape 분기마다 계산이 달라지므로 코드가 길어졌다.

컴포지션이 상속보다 좋고 권장하지만, 컴포지션에 따라 여러 분기문이 생긴다면, interface나 상속을 활용해 타입의 다형성을 활용한다.

위의 코드는 다음과 같은 계층 구조를 가진다.

즉 Figure를 상속해 Circle과 Rectangle을 구현하면 불필요한 분기문을 줄일 수 있다.

public abstract class Figure {
    
    public abstract double area();
}


class Circle extends Figure {
    
    private final double radius;

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

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

class Rectangle extends Figure {
    
    private final int width;
    private final int length;

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

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

훨씬 코드가 명확하고 짧아졌음을 알 수 있다.

profile
엘 프사이 콩그루
post-custom-banner

0개의 댓글