kkkkkkkkkkkk
kkkkk
kkkkkkkkkkkk
전체 방문자
오늘
어제
  • 분류 전체보기
    • CS & OS
    • Algorithms
    • Laguage
    • Book
      • 객체지향의 사실과 오해
      • Effective Java
      • Spring boot 와 AWS로 혼자 구현하는 ..
      • 도메인 주도 계발 시작하기
    • DB
    • Spring
    • Spring Boot
    • JPA
    • Git
    • Clean Code
    • HTTP

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 책임
  • 결합도
  • 설계 원칙
  • 역할
  • 객체지향 프로그래밍
  • 응집도

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
kkkkkkkkkkkk

kkkkk

Book/Effective Java

[Item 23] 태그 달린 클래스보다 클래스 계층구조를 활용하라

2022. 7. 27. 14:13

태그 달린 클래스는 장황하고, 오류를 내기 쉽고, 비효율적이다.

  • 클래스 계층구조보다 나쁘다.
public class Figure {

    enum Shape {RECTANGLE,CIRCLE}

    private final Shape shape;
    private int length;
    private int width;
    private int radius;

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

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

    public int area() {
        switch (shape) {
            caseCIRCLE:
                return (int) Math.PI* (radius * radius);
            caseRECTANGLE:
                return length * width;
            default:
                throw new AssertionError("원이나 사각형이 아니에요");
        }
    }
}

태그 달린 클래스에는 단점이 있다.

  • 열거 타입 선언, 태그 필드, switch 문 등 쓸데없는 코드가 많다.
  • 여러 구현이 한 클래스에 혼합돼 있어 가독성이 나쁘다.
  • 다른 의미를 위한 코드도 언제나 함꼐 작성하니 메모리도 많이 사용한다.
  • final 필드로 선언하려면 해당 의미에 쓰이지 않는 필드들까지 생성자에 초기화 해야 한다.
  • 새로운 의미를 부여할 때 switch 문에 로직을 추가해야한다.

 

태그 달린 클래스보다 계층구조를 활용하는 서브타이핑이 훨씬 나은 수단이다.

계층구조로 바꾸는 방법

  • 루트가 될 추상 클래스를 정의
  • 태그 값에 따라 동작이 달라지는 메서드들을 루트 클래스의 추상 메서드로 선언
    • 위의 코드에서는 area() 메서드가 해당된다.
  • 태그 값에 상관없이 동작하는 메서드를 루트 클래스에 일반 클래스로 정의한다.
  • 모든 하위 클래스에서 공통으로 사용하는 필드를 루트 클래스로 모아준다.
  • 루트 클래스를 확장한 구체 클래스를 의미별로 하나씩 정의한다.
    • Rectangle
    • Circle
public abstract class FigureSolution {
    public abstract int area();
}
@Getter
@Builder
@AllArgsConstructor
public class Circle extends FigureSolution {

    private final int radius;

    @Override
    public int area() {
        return (int) Math.PI* (radius * radius);
    }
}
@Getter
@Builder
@AllArgsConstructor
public class Rectangle extends FigureSolution {

    private final int length;
    private final int width;

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

간결하고 명확하며, 자신의 책임을 위임해주어 쓸데 없는 코드들이 제거되었다.

이러한 계층구조를 반영할 수 있어 유연성은 물론 컴파일타임 타입 검사 능력을 높여준다는 장점도 있다.

 

정리

  • 태그 달린 클래스를 써야 하는 상황은 거의 없다.
  • 새로운 클래스를 작성하는 데 태그 필드가 등장한다면 태그를 없애고 계층구조로 대체하는 방법을 생각해보자.
  • 기존 클래스가 태그 필드를 사용하고 있다면 계층구조로 리팩터링하는 걸 고민해보자.

'Book > Effective Java' 카테고리의 다른 글

[Item 27] 비검사 경고를 제거하라  (0) 2022.08.06
[Item 26] 로 타입(Raw Type)은 사용하지 말라  (0) 2022.08.05
[Item 25] 톱레벨 클래스는 한 파일에 하나만 담으라  (0) 2022.08.05
[Item 24] 멤버 클래스는 되도록 static 으로 만들라  (0) 2022.07.27
[Item 22] 인터페이스는 타입을 정의하는 용도로만 사용하라  (0) 2022.07.26
[Item 21] 인터페이스는 구현하는 쪽을 생각해 설계해라  (0) 2022.07.26
[Item 20] 추상 클래스보다는 인터페이스를 우선하라  (0) 2022.07.26
[Item 19] 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라  (0) 2022.07.24
    'Book/Effective Java' 카테고리의 다른 글
    • [Item 25] 톱레벨 클래스는 한 파일에 하나만 담으라
    • [Item 24] 멤버 클래스는 되도록 static 으로 만들라
    • [Item 22] 인터페이스는 타입을 정의하는 용도로만 사용하라
    • [Item 21] 인터페이스는 구현하는 쪽을 생각해 설계해라
    kkkkkkkkkkkk
    kkkkkkkkkkkk

    티스토리툴바