Effective Java 2/E - Chatper 06 Enum과 Annotation (2)

Rule 35 - 작명 패턴 대신 어노테이션을 사용하라

일반적인 작명 패턴은 위험함

  • 오타가 날 수 있어서 프로그램이 깨짐
  • 특정 요소에만 적용될 수 있도록 할 수 없다.
  • 인자를 전달할 수 없다.

해결책 어노테이션

example 표식 어노테이션

import java.lang.annotation.*
/**
 * 어노테이션이 붙은 메서드가 테스트 메서드임을 표시.
 * 무인자(parameterless) 정적 메서드에만 사용가능
 */
@Retention(RegentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
}

example 배열 인자를 취하는 어노테이션

// 배열을 인자로 받는 어노테이션 자료형
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
    Class<? extends Exception>[] value();
}

어노테이션을 처리하는 코드는 리플렉션을 사용한다.

  • Method#isAnotationPresent(Class<? extends Annotation) : 메서드에 해당 어노테이션이 존재하나?
  • Method#getAnnotation(Class<? extends Annotation>) : 메서드의 해당 어노테이션 조회

결론

  • 프로그래머가 소스 파일에 정보를 추가할 수 있도록 하는 도구
  • 어노테이션이 존재하면 작명패턴은 안티패턴이다.
  • 서비스 프로그래머는 어노테이션을 만들 상황이 거의 없을 수도 있다. 하지만 특정 도구를 제공한다면 편의에 따라서 만들 수도 있다고 본다.

개인적으로 DTO를 문자열로 직렬화해서 소켓서버로 전송하는 기능을 제공한 적이 있었는데 이런 경우에 해당 객체와 객체 내의 속성을 제공한 어노테이션으로 설정하고 DTO와 문자열 간 직렬화/역직렬화를 제공한 적이 있었는데, 이 때 어노테이션이 코드의 재사용성과 가독성에 큰 도움이 되었음

Rule 36 - Override 어노테이션은 일관되게 사용하라

(java 1.5 이상이라면) 상위 클래스에 선언된 메서드를 재정의할 때는 반드시 선언부에 Override 어노테이션을 붙여야한다. 오류를 미연에 방지할 수 있다. ex) 잘못 재정의 하는 경우

abstract 메서드를 구현할 때는 예외(가능한 붙이는 것을 추천) - 어짜피 추상메서드를 구현 안해도 컴파일러 오류 발생

아래 문구 이해가 안됨

예를 들어 Set 인터페이스는 Collection 인터페이스에 선언된 메서드에 어떤 새로운 메서드도 더하지 않으므로 Override 어노테이션을 모든 메서드 선언에 붙였다. 실수로 Collection 인터페이스에 새로운 메서드를 더하는 일을 막기 위해서다.

Rule 37 - 자료형을 정의할 때 표식 인터페이스를 사용하라

표식 인터페이스(maker interface)는 아무 메서드도 선언하지 않는 인터페이스

  • Serializable

표식 인터페이스의 장점

표식 어노테이션에 비해 나은 점

1. 표식 인터페이스는 결국 표식 붙은 클래스가 만드는 객체들이 구현하는 자료형 이라는 점.

  • 표식 어노테이션은 자료형이 아니다.
  • 표식 인터페이스는 자료형이기 때문에 컴파일시점에 오류가 미리 발견된다.

2. 적용범위(scope)를 좀 더 세밀하게 지정할 수 있다.

  • 인터페이스의 계승(extends)을 통해서 특정 타입을 적용범위로 설정할 수 있다.
  • 하지만 어노테이션은 Target 메타 어노테이션으로만 가능 : 타입, 메소드, 필드 등

표식 어노테이션의 장점

1. 확장 (+ 풍부한 표현)

기본값을 가지는 어노테이션 자료형 요소(annotation type element)를 추가할 수 있다. 확장

표식 인터페이스는 말 그대로 인터페이스이기 때문에 기능(메소드) 추가가 거의 불가능하다고 할 수 있으나, java 1.8의 default 메서드를 통해서 어느정도 해소가 가능하다.

2. 더 큰 어노테이션 기능(facility)의 일부

표식 어노테이션 VS 표식 인터페이스

표식 어노테이션

  • 타입(클래스나 인터페이스) 이외의 프로그램 요소에 적용되어야하는 표식은 어노테이션으로 만들어야한다.
  • 해당 표식(기능)을 영원히 특정 인터페이스가 객체에만 적용할 것이 아니다. 확장여지가 분명하다.

위 상황이 아니라면 표식인터페이스 를 강력하게 추천

결론

  • 새로운 메서드가 없는 자료형을 정의하고자 한다면 표식 인터페이스
  • 타입 이외의 프로그램 요소에 표식을 달아야 하고, 앞으로 표식에 더 많은 정보를 추가할 가능성이 있다면 표식 어노테이션

구체화하면 만일 ElementType.TYPE에 적용될 표식 어노테이션 자료형을 작성하고 있다면, 반드시 어노테이션 자료형으로 구현해야 하는지, 표식 인터페이스로 만드는 것이 바람직하지는 않은지 고민해보자

자료형이 필요하다면 인터페이스를 기본적으로 사용을 고민하라.

MJ

MJ
Backend 개발자 사람입니다. 어플리케이션의 복잡성을 다루는 DDD에 관심이 많습니다. 어제보다 더 나은 개발자가 되려고 항상 노력합니다.

spring boot 2.4.x 에서 openfeign + hystrix 통합하기

spring-boot 2.4.x spring-cloud 2020.x 의존성 상황에서 feign.hystrix.enabled=true가 안됨`feign.circuitbreaker.enabled=true` 로 바꿔보지만 openfeign과 hystr...… Continue reading

IDDD 14장. 애플리케이션

Published on June 19, 2018