Item23. 태그 달린 class보다는 class 계층 구조를 활용하자
태그 달린 class
헌재 표현하는 의미를 태그 값으로 알려주는 class 는 아래와 같이 class 계층구조를 사용하지 않고, 한 class내에 태그 필드를 가지는 class를 말한다.
1 | public class Figure { |
태그 필드를 가지고, 분기처리 (swith,if-else)를 하기 때문에 코드 가독성이 떨어지고, 계층형 구조로 가져갔을때 불필요한 코드들이 생긴다.
태그 값마다 필요한 필드가 다른데, 이를 모두 하나의 class에 보관함으로, 객체를 생성하였을떄 사용되지 않는 필드 (메모리 낭비) 도 같이 초기화 된다.
변경에 열려있다, 태그 값 추가시마다 분기로직을 수정해야 한다.
인스턴스 타입을 보고 현재 타입이 나타내는 의미를 알 수가 없다.
클래스 계층 구조로 변경
- 태그 달린 class는 위와 같은 단점들을 가지고 있기 떄문에, 클래스 계층 구조로 변경하는게 더 바람직하다.
- 변경 방법을 정리하면 다음과 같다.
계층 구조의 부모가 될 추상 class를 정의
태그 값에 따라 동작이 달라지는 method를 자식이 구현하도록 abstract method로 선언
태그 값에 따라 동작이 달라지지 않는 method는 default method로 선언
구현체는 태그값(의미)별로 하나씩 정의
예제 코드를 보면 Figure class를 다음과 같은 클래스 계층구조로 변경하였다.
1 |
|
태그값 (의미) 별로 구현체로 분리하였으며, 구현체마다 다른 로직은 추상 method로 뽑았다.
1 | public class Circle extends Figure { |
계층구조로 변경하면서 생긴 장점은 다음과 같다.
- 불필요한 분기로직 제거
- 타입만 보아도 해당 class가 무슨 기능을 하는지 짐작 할 수 있다. (가독성)
- 불필요한 필드 제거 , 해당 클래스에서 필요한 필드만 가지고 있다.
- 확장성 증가
예를 들어 직사각형 class를 상속받는 정사각형 class는 다음과 같이 간단히 표현될 수 있다.
1 | public class Square extends Rectangle{ |
정리
태그 달린 class는 계층구조로 리팩토링 하자, 구현체간에 공통된 로직은 default method로 , 구현체마다 다른 로직은 abstract method로 선언하면 변경이 가능하다.