[이펙티브 자바] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라
public class Figure {
enum Shape {RECTANGLE, CIRCLE};
// 태그 필드 - 현재 모양을 나타낸다.
final Shape shape;
// 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다.
double length;
double width;
// 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다.
double radius;
// 원용 생성자
public FigureWithTag(double radius) {
this.shape = Shape.CIRCLE;
this.radius = radius;
}
// 사각형용 생성자
public FigureWithTag(double length, double width) {
this.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);
}
}
}
두 가지 이상의 의미를 표현할 수 있으며, 그중 현재 표현하는 의미를 태그값으로 알려주는 클래스다. (사실 본적이 없다). 위의 코드는 원과 사각형을 표현할 수 있다.
단점
- 열거 타입, 태그 필드, switch문 등 쓸데 없는 코드가 많다.
- 여러 구현이 섞여 있어 가독성이 나쁘다
- 다른 의미를 위한 코드도 함께하니 메모리 비효율적이다.
- 인스턴스 타입만으로 현재 의미를 알 길이 없다.
대체
추상 클래스를 정의하고, 태그 값에 따라 동작이 달라지는 메서드들을 루트 클래스의 추상 메서드로 선언하면 된다. 태그에 상관없이 동작이 일정한 메서드는 루트 클래스에 일반 메서드로 구현하면된다. 공통으로 사용하는 데이터 필드도 루트 클래스로 올린다.
public abstract class Figure {
abstract double area();
}
public class Circle extends Figure {
final double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI * (radius * radius);
}
}
public class Rectangle extends Figure {
final double length;
final double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
double area() {
return length * width;
}
}
Author And Source
이 문제에 관하여([이펙티브 자바] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@injoon2019/이펙티브-자바-아이템-23.-태그-달린-클래스보다는-클래스-계층구조를-활용하라저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)