Bactoria 황준오

Enum 정리

2019-07-18
bactoria

Basic

non-enum

class State {
    public static final State READY = new STATE();
    public static final State PLAY = new STATE();
    public static final State EXIT = new STATE();
}

 

enum

enum State {
    READY, PLAY, EXIT
}

   

1. 코드성 엔터티

public enum AttachmentGroupRole {
    PROFILE, BOARD
}
public enum BoardType {
    A,B,C
}
public enum BoardCommentStatus {
    AVAILABLE, DELETED
}
public enum UserRole {
    USER, ADMIN
}

프로젝트 할 때 코드성 엔터티를 DB로 안빼고 Application 단에서 처리했었음

 

2. 싱글톤 구현

// 열거 타입 방식의 싱글턴 - 바람직한 방법 (이펙티브자바 3E :25p)
enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() {
        System.out.println("기다려 자기야, 지금 나갈께!");
    }
}

public Main {
    public static void main(String[] args) {
        Elvis elvis = Elvis.INSTANCE;
        elvis.leaveTheBuilding();
    }
}
  • 직렬화, 리플렉션 에도 싱글톤 유지함.
    • static final / static method 로 싱글톤을 구현하는 경우는
      • 직렬화를 위해 추가적인 작업 필요
      • 리플렉션으로 객체 생성 가능해서 의도적으로 싱글톤을 무너트릴 수 있음.

근데 이거 쓰는거 본적이 없는데..

 

3. 데이터 그룹 관리

public enum BoardGroup {

	ADMIN("관리자", Arrays.asList("안되", "오지마")),
	USER("유저", Arrays.asList("자유게시판", "구루구구")),
	EMPTY("없음", Collections.emptyList());
	
	private String title;
	private List<String> boards;
	
	private BoardGroup(String title, List<String> boards) {
		this.title = title;
		this.boards = boards;
	}

	public static BoardGroup findByBoardCode(String boardCode) {
		return Arrays.stream(BoardGroup.values())
			.filter(boardGroup -> boardGroup.hasBoard(boardCode))
			.findAny()
			.orElse(EMPTY);
	}
	
	private boolean hasBoard(String boardCode) {
		return boards.stream()
				.anyMatch(board -> board.equals(boardCode));
	}
}

이동욱님의 글을 참고 함. http://woowabros.github.io/tools/2017/07/10/java-enum-uses.html

   

4. 익명 메소드

사칙연산을 수행하는 Operation을 만들 수 있따.

익명메서드를 선언하고, 구현은 위에서 해버리기.

// 이펙티브자바 <Item 34>
enum Operation {
    PLUS("+") {
        public double apply(double x, double y) { return x + y; }
    },
    MINUS("-") {
        public double apply(double x, double y) { return x - y; }
    },
    TIMES("*") {
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE("/") {
        public double apply(double x, double y) { return x / y; }
    };

    private final String symbol;

    public abstract double apply(double x, double y);

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

    @Override 
    public String toString() { 
        return symbol; 
    }
}

public class AbstractMethod {
    public static void main(String[] args) {
        double x = 1.1;
        double y = 3.3;
        for (Operation op : Operation.values())
            System.out.printf("%f %s %f = %f%n",
                    x, op, y, op.apply(x, y));

        // 1.100000 + 3.300000 = 4.400000
        // 1.100000 - 3.300000 = -2.200000
        // 1.100000 * 3.300000 = 3.630000
        // 1.100000 / 3.300000 = 0.333333
    }
}

 

5. Functional Interface

위의 익명 메서드 대신 Functional Interface를 사용하여 사칙연산을 구현할 수 있다.

// 이펙티브자바 <Item 42>
public enum Operation { 
    PLUS("+", (x, y) -> x + y),
    MINUS("-", (x, y) -> x - y),
    TIMES("*", (x, y) -> x * y),
    DIVIDE("/", (x, y) -> x / y);

    private final String symbol;
    private final DoubleBinaryOperator op;

    Operation(String symbol, DoubleBinaryOperator op) {
        this.symbol = symbol;
        this.op = op;
    }

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }

    @Override
    public String toString() { return symbol; }
}

우테코 프리코스 과제 (숫자 야구게임)

public enum State {

	PLAY_CONTINUE(Constant.PLAY_CONTINUE_NUMBER),
	EXIT(Constant.EXIT_GAME_NUMBER);
	private final int value;

	private State(int value) {
		this.value = value;
	}

	public static State findState(int i) {
		return Arrays.stream(State.values())
				        .filter(x -> x.getValue() == i)
				        .findAny()
				        .orElseThrow(() -> new IllegalArgumentException("잘못된 입력 값 입니다. :: " + i));
	}

	public int getValue() {
		return value;
	}
}

 

우테코 프리코스 과제 (로또)

public enum Rank {
    FIRST(6, 2_000_000_000), // 1등
    SECOND(5, 30_000_000), // 2등
    THIRD(5, 1_500_000), // 3등
    FOURTH(4, 50_000), // 4등
    FIFTH(3, 5_000), // 5등
    MISS(0, 0);

    private static final int WINNING_MIN_COUNT = 3;

    private final int countOfMatch;
    private final int winningMoney;

    private Rank(int countOfMatch, int winningMoney) {
        this.countOfMatch = countOfMatch;
        this.winningMoney = winningMoney;
    }

    public int getCountOfMatch() {
        return countOfMatch;
    }

    public int getWinningMoney() {
        return winningMoney;
    }

    public static Rank valueOf(int countOfMatch, boolean matchBonus) {
        if (countOfMatch < WINNING_MIN_COUNT) {
            return MISS;
        }

        if (SECOND.matchCount(countOfMatch) && matchBonus) {
            return SECOND;
        }

        for (Rank rank : values()) {
            if (rank.matchCount(countOfMatch) && rank != SECOND) {
                return rank;
            }
        }

        throw new IllegalArgumentException(countOfMatch + "는 유효하지 않은 값입니다.");
    }

    private boolean matchCount(int countOfMatch) {
        return this.countOfMatch == countOfMatch;
    }
}

 


황준오 (Bactoria) 황준오 (Bactoria)

.

Comments

Content