Enum 공통 유틸 만들기

taeni·2022년 11월 16일
0

Enum을 활용한 코드 관리시에 반복적으로 사용되는 부분을 공통 유틸로 생성

나는 평소에 Enum을 활용하여 코드를 관리하는 것을 선호한다.
Enum으로 관리시에 자주 사용되는 부분을 공통 유틸로 분리하는 패턴을 적용하여 기록한다. 아래 패턴은 조금 더 좋은 아이디어가 있을 때마다 리팩토링하여 업데이트 할 예정이다

일반적으로 사용되는 Enum 반복 사용 패턴 1

@AllArgsConstructor
@Getter
public enum Friut {
	APPLE("AP"),
    BANANA("BN"),
    STRAWBERRY("ST"),
    MANGO("MG"),
    PINEAPPLE("PA");
    
    private String code;
    
    public static Friut findBycode(String code) {
    	return Arrays.stream(Fruit.values())
        	.filter(f -> f.getCode().equals(value))
            .findAny()
            .orElse(Fruit.APPLE);
    }
}

Interface를 활용하여 findByCode 부분 유틸화

  • 코드값 관련 인터페이스
public interface EnumCode {
	String getCode();
}
  • EnumValue 인터페이스 구현 Enum
@AllArgsConstructor
@Getter
public enum Friut implements EnumCode {
	APPLE("AP"),
    BANANA("BN"),
    STRAWBERRY("ST"),
    MANGO("MG"),
    PINEAPPLE("PA");
    
    private String code;
}
  • Enum code find util
public class EnumFindUtil{
	public static <E extends Enum<E> & EnumCode> Optional<E> findByValue(Class<E> clazz, String value) {
		return Arrays.stream(clazz.getEnumConstants())
			.filter(e -> e.getCode().equals(value)
            .findAny();
	}
}
  • 활용
Fruit favoriteFruit = EnumFindUtil.findByCode(Fruit.class, "MG").orElse(Fruit.APPLE);

일반적으로 사용되는 Enum 반복 사용 패턴 2

@AllArgsConstructor
@Getter
public enum FruitTypeByColor implements EnumCode, EnumValueList<Fruit> {
	RED_FRUIT("RD", Arrays.asList(FRUIT.APPLE, FRUIT.STRAWBERRY)),
    YELLOW_FRUIT("YL", Arrays.asList(FRUIT.BANANA, FRUIT.MANGO, FRUIT.PINEAPPLE));
    
    private String code;
    private List<Fruit> valueList;
    
    public static FruitTypeByColor findByCode(String code) {
    	return Arrays.stream(FruitTypeByColor.values())
        	.filter(f -> f.getCode().equals(value))
            .findAny()
            .orElseThrow();
    }
    
    public FruitTypeByColor findByValue(Fruit value){
    	return Arrays.stream(FruitTypeByColor.values())
        	.filter(e -> hasByValue(e.getValueList(), value))
            .findAny()
            .orElseThrow();
    }
    
    private boolean hasByValue(List<Fruit> values, Fruit value) {
    	return values.stream()
        	.anyMatch(e -> e == value);
    }
}

Interface를 활용하여 getValueList 부분 유틸화

  • 코드리스트 관련 인터페이스
public interface EnumValueList<T> {
	List<T> getValueList();
}
  • EnumCodeList 인터페이스 구현 Enum
@AllArgsConstructor
@Getter
public enum FruitTypeByColor implements EnumCode, EnumValueList<Fruit> {
	RED_FRUIT("RD", Arrays.asList(FRUIT.APPLE, FRUIT.STRAWBERRY)),
    YELLOW_FRUIT("YL", Arrays.asList(FRUIT.BANANA, FRUIT.MANGO, FRUIT.PINEAPPLE));
    
    private String code;
    private List<Fruit> valueList;
}
  • Enum code find util
public class EnumFindUtil{
	public static <E extends Enum<E> & EnumCode> Optional<E> findByCode(Class<E> clazz, String value) {
		return Arrays.stream(clazz.getEnumConstants())
			.filter(e -> e.getCode().equals(value)
            .findAny();
	}
    
	public static <E extends Enum<E> & EnumValueList<C>, C extends Enum<C>> Optional<E> findByValue(Class<E> clazz, C value){
    	return Arrays.stream(clazz.getEnumConstants())
        	.filter(e -> hasByValue(e.getValueList(), code))
            .findAny();
    }
    
    private static <E extends Enum<E>, C extends Enum<C>> boolean hasByValue(List<E> values, C value) {
    	return values.stream()
        	.anyMatch(e -> e == value);
    }
}
  • 활용
FruitTypeByColor favoriteFruit = EnumFindUtil.findByCode(Fruit.class, "RD").orElseThrow();
FruitTypeByColor fruitType = EnumFindUtil.findByValue(FruitTypeByValue.class, Fruit.APPLE).orElseThrow();

위 패턴을 활용하여 다양한 적용이 가능할 것으로 보인다

profile
정태인의 블로그

0개의 댓글