설명하기에 앞서..
이 포스팅은 본래 enum의 주 사용목적인
열거형 제한을 걸어 개발자의 실수를 막는다거나
인스턴스 생성 및 상속을 방지하여
상수값의 타입안정성 보장 등을
하기 위한 목적으로 작성된 것이 아님을 알려드립니다.
JAVA enum을 사용하여 코드가 단순해짐에 따라
가독성이 상승하는 효과만을 위해 쓰여졌습니다
따라서 이 글에서 언급될 코드들은
enum 사용없이 구현해도 상관없습니다.
자바의 enum은 다른 언어와 다르게 클래스 취급을 받기 때문에 생성자 선언을 통해 다양한 일을 할 수 있습니다.
이를테면 아래의 코드처럼 enum의 각 요소들의 생성자에 특정한 수학 공식을 미리 기입해둠으로 메서드처럼* 사용할 수 있습니다.
(실사용 코드는 글 맨 아래에 있습니다.)
//JAVA 8
public enum Calculator {
POWER(n -> n * n), // n제곱
GAUSE(n -> (1 + n) * (n / 2)), // 1부터 n까지 합산한 결과
PYTHAGORAS((n, m) -> Math.sqrt(POWER.calculate(n) + POWER.calculate(m)));
private Function<Long, Long> expression;
private BiFunction<Long, Long, Double> pyhagoras;
private Calculator(Function<Long, Long> expression) {
this.expression = expression;
}
private Calculator(BiFunction<Long, Long, Double> pyhagoras) {
this.pyhagoras = pyhagoras;
}
public long calculate(long value) {
return expression.apply(value);
}
public double calculate(long a, long b) {
return pyhagoras.apply(a, b);
}
}
JAVA 8 미만의 버전에서는 람다 기능을 지원하지 않기 때문에
생성자(ABC(n, m) 등)내에서 유동적인 값의 계산이 불가능합니다.
예를 들어 POWER(3, 4) 는 요소로 선언가능하지만, POWER(n, m)는 요소로 올 수 없습니다.
아래의 코드를 참고하세요.
enum EnumPossible {
ABC(3, 4); // 선언 가능.
EnumPossible(int n, int m) {}
}
enum EnumImpossible {
ABC(n, m); // 선언 불가능
EnumImpossible(int n, int m) {}
}
따라서 JAVA 8 방식에서 사용된 방식과 동일하게 사용하려면 아래와 같이 작성할 수 있습니다.
그러나 코드에서도 알 수 있듯 각 enum 요소에서 구현되는 추상 메소드들에 대한 오버로딩이 사용될 경우
불필요한 메소드조차 강제로 구현해야하는 단점이 존재합니다.
//JAVA 7
enum Calculator7 {
POWER7 {
long calculate(long n) { return n * n; }
double calculate(long value, long value2) { return 0; } // 불필요한 코드 구현을 강제당함
},
GAUSE7 {
long calculate(long n) { return (1 + n) * (n / 2); }
double calculate(long value, long value2) { return 0; } // // 불필요한 코드 구현을 강제당함
},
PYTHAGORAS7 {
long calculate(long value) { return 0; } // 불필요한 코드 구현을 강제당함
double calculate(long n, long m) {
return Math.sqrt(POWER7.calculate(n) + POWER7.calculate(m));
}
};
abstract long calculate(long value);
abstract double calculate(long n, long m);
}
개발자의 실수를 유발할 수 있는 이런 치명적인 단점 때문에 enum에서의 추상메소드 사용기법이 추천되지 않았으나
JAVA 8부터 함수형 프로그래밍이 가능해짐에 따라 역량에 따라 활용도를 높일 수 있을 것입니다.
JAVA8, JAVA7 enum 사용 코드
class RunCalculator {
public static void main(String[] args) {
System.out.println("------------JAVA 8-------------");
Calculator gause = Calculator.GAUSE;
System.out.println(gause.calculate(100));
Calculator pyhagoras = Calculator.PYTHAGORAS;
System.out.println(pyhagoras.calculate(3, 4));
System.out.println("------------JAVA 7-------------");
Calculator7 gause7 = Calculator7.GAUSE7;
System.out.println(gause7.calculate(100));
Calculator7 pytagoras7 = Calculator7.PYTHAGORAS7;
System.out.println(pytagoras7.calculate(3, 4));
}
}
JAVA8 방식이든 JAVA7 방식이든 의도에 맞게 사용한다면
결과값은 아래와 같이 서로 동일하게 출력됩니다.
[전체코드]
import java.util.function.BiFunction;
import java.util.function.Function;
//JAVA 8
public enum Calculator {
POWER(n -> n * n), // n제곱
GAUSE(n -> (1 + n) * (n / 2)), // 1부터 n까지 합산한 결과
PYTHAGORAS((n, m) -> Math.sqrt(POWER.calculate(n) + POWER.calculate(m)));
private Function<Long, Long> expression;
private BiFunction<Long, Long, Double> pyhagoras;
private Calculator(Function<Long, Long> expression) {
this.expression = expression;
}
private Calculator(BiFunction<Long, Long, Double> pyhagoras) {
this.pyhagoras = pyhagoras;
}
public long calculate(long value) {
return expression.apply(value);
}
public double calculate(long a, long b) {
return pyhagoras.apply(a, b);
}
}
//JAVA 7
enum Calculator7 {
POWER7 {
long calculate(long n) { return n * n; }
double calculate(long value, long value2) { return 0; } // 불필요한 코드 구현을 강제당함
},
GAUSE7 {
long calculate(long n) { return (1 + n) * (n / 2); }
double calculate(long value, long value2) { return 0; } // // 불필요한 코드 구현을 강제당함
},
PYTHAGORAS7 {
long calculate(long value) { return 0; } // 불필요한 코드 구현을 강제당함
double calculate(long n, long m) {
return Math.sqrt(POWER7.calculate(n) + POWER7.calculate(m));
}
};
abstract long calculate(long value);
abstract double calculate(long n, long m);
}
class RunCalculator {
public static void main(String[] args) {
System.out.println("------------JAVA 8-------------");
Calculator gause = Calculator.GAUSE;
System.out.println(gause.calculate(100));
Calculator pyhagoras = Calculator.PYTHAGORAS;
System.out.println(pyhagoras.calculate(3, 4));
System.out.println("------------JAVA 7-------------");
Calculator7 gause7 = Calculator7.GAUSE7;
System.out.println(gause7.calculate(100));
Calculator7 pytagoras7 = Calculator7.PYTHAGORAS7;
System.out.println(pytagoras7.calculate(3, 4));
}
}
'Java > Java' 카테고리의 다른 글
java 슈퍼 타입 토큰을 활용한 map 및 list 구현 (1) | 2021.07.29 |
---|---|
은행 계좌 관리 프로그램 ver 1.1 (0) | 2020.09.03 |
간단한 은행 계좌 관리 프로그램 (0) | 2020.08.30 |