아이템38 - 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

Sorbet·2021년 11월 13일
0

아이템38 - 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

열거형의 단점

  • 우리가 쓰는 Enum의 특징으로는 클라이언트가 값을 더 추가해서 쓸 수 없다
  • 예시로 Spring HttpMethod httpMethod 은 우리가 값을 추가할수 없는데 잘 생각해보면 그럴필요가 없다
  • 생각해보면 확장할 필요가 있는경우가 드물다.. HttpMethod 같은걸 일개 개발자가 추가할리는 없으니..까?
@Slf4j
@RestController
public class RequestHeaderController {

    @RequestMapping("/header")
    public String headers(HttpServletRequest request, HttpServletResponse response,
                          HttpMethod httpMethod, Locale locale,
                          @RequestHeader MultiValueMap<String, String> headerMap,
                          @RequestHeader("host") String host,
                          @CookieValue(value = "myCookie", required = false) String cookie) {
 

public enum HttpMethod {

	GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;


	private static final Map<String, HttpMethod> mappings = new HashMap<>(16);

	static {
		for (HttpMethod httpMethod : values()) {
			mappings.put(httpMethod.name(), httpMethod);
		}
	}
    
    @Nullable
    public static HttpMethod resolve(@Nullable String method) {
        return (method != null ? mappings.get(method) : null);
    }
    
    public boolean matches(String method) {
        return name().equals(method);
    }

}

그럼에도 불구하고

  • 과거에 사용했던 타입안전 열거패턴은 가능했는데 이런게 필요한 경우가 있을까??
  • 딱하나 있다면 연산자(Op code)같은게 있을수 있고, 이때는 Enum 으로 인터페이스를 구현하는 방식을 사용하면된다

public interface Operation {
    double apply(double x, double y);
}
public enum BasicOps implements Operation {
    PULS("+") {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUS("+") {
       
    },
    TIMES("*") {

    },
    DIVIDE("/") {
       
    };
    
    private final String symbol;

    BasicOps(String symbol) {
        this.symbol = symbol;
    }
    
}

위와 같은 코드를 프레임워크가 만들어줬다고 하면, 클라이언트가 아래 코드를 추가할 수 있다

public enum ExtenedOps implements Operation {

    EXP("*") {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    REMAINDER("%") {
        //...
    }
}
profile
Sorbet is good...!

0개의 댓글